From 3e1fb7e5114d35a465fffc0af287968eb9d6f058 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 6 Mar 2025 00:01:11 +0100 Subject: [PATCH 01/42] chore: 0.35.0-dev --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index b53d92a195a..bca3b4238fa 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.34.0-dev" +const CurrentVersionNumber = "0.35.0-dev" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 6f2196f6552e4c5c800bd95141396b48d582a224 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Fri, 7 Mar 2025 08:42:55 +0100 Subject: [PATCH 02/42] deps: update boxo to main-branch commit --- 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 | 8 ++++---- 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 8dffe9c1434..8ca4390ed3c 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.24 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.29.0 + github.com/ipfs/boxo v0.29.1-0.20250307073615-93ea580a3bb0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.41.0 github.com/multiformats/go-multiaddr v0.15.0 @@ -52,7 +52,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.6 // indirect - github.com/gammazero/chanqueue v1.0.0 // indirect + github.com/gammazero/chanqueue v1.1.0 // indirect github.com/gammazero/deque v1.0.0 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect github.com/go-jose/go-jose/v4 v4.0.5 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 9a5fa3be19e..6207a1d8abd 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -166,8 +166,8 @@ 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.6 h1:3+PzJTKLkvgjeTbts6msPJt4DixhT4YtFNf1gtGe3zc= github.com/gabriel-vasile/mimetype v1.4.6/go.mod h1:JX1qVKqZd40hUPpAfiNTe0Sne7hdfKSbOqqmkq8GCXc= -github.com/gammazero/chanqueue v1.0.0 h1:FER/sMailGFA3DDvFooEkipAMU+3c9Bg3bheloPSz6o= -github.com/gammazero/chanqueue v1.0.0/go.mod h1:fMwpwEiuUgpab0sH4VHiVcEoji1pSi+EIzeG4TPeKPc= +github.com/gammazero/chanqueue v1.1.0 h1:yiwtloc1azhgGLFo2gMloJtQvkYD936Ai7tBfa+rYJw= +github.com/gammazero/chanqueue v1.1.0/go.mod h1:fMwpwEiuUgpab0sH4VHiVcEoji1pSi+EIzeG4TPeKPc= github.com/gammazero/deque v1.0.0 h1:LTmimT8H7bXkkCy6gZX7zNLtkbz4NdS2z8LZuor3j34= github.com/gammazero/deque v1.0.0/go.mod h1:iflpYvtGfM3U8S8j+sZEKIak3SAKYpA5/SQewgfXDKo= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= @@ -298,8 +298,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 h1:OqNqsGZPX8zh3eFMO8Lf8EHRRnSGBMqcd github.com/ipfs-shipyard/nopfs/ipfs v0.25.0/go.mod h1:BxhUdtBgOXg1B+gAPEplkg/GpyTZY+kCMSfsJvvydqU= 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.29.0 h1:clzd7PglUcE+Ufq1KucS3aKID7pzGVaSgcdRsW395t4= -github.com/ipfs/boxo v0.29.0/go.mod h1:c3R52nMlgMsN1tADffYcogKoVRsX1RJE1TMYSpJ4uVs= +github.com/ipfs/boxo v0.29.1-0.20250307073615-93ea580a3bb0 h1:wkFvXf7SqRiAu5ezj6lsieE2PwDk3nUkFOs9/+5lWdo= +github.com/ipfs/boxo v0.29.1-0.20250307073615-93ea580a3bb0/go.mod h1:MkDJStXiJS9U99cbAijHdcmwNfVn5DKYBmQCOgjY2NU= 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 0bcc1869f6e..0bcfbc99de4 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.14 github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 - github.com/ipfs/boxo v0.29.0 + github.com/ipfs/boxo v0.29.1-0.20250307073615-93ea580a3bb0 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.5.0 github.com/ipfs/go-cidutil v0.1.0 @@ -125,7 +125,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.6 // indirect - github.com/gammazero/chanqueue v1.0.0 // indirect + github.com/gammazero/chanqueue v1.1.0 // indirect github.com/gammazero/deque v1.0.0 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect github.com/go-jose/go-jose/v4 v4.0.5 // indirect diff --git a/go.sum b/go.sum index e29d9352f3c..7e2b6e63afb 100644 --- a/go.sum +++ b/go.sum @@ -200,8 +200,8 @@ 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.6 h1:3+PzJTKLkvgjeTbts6msPJt4DixhT4YtFNf1gtGe3zc= github.com/gabriel-vasile/mimetype v1.4.6/go.mod h1:JX1qVKqZd40hUPpAfiNTe0Sne7hdfKSbOqqmkq8GCXc= -github.com/gammazero/chanqueue v1.0.0 h1:FER/sMailGFA3DDvFooEkipAMU+3c9Bg3bheloPSz6o= -github.com/gammazero/chanqueue v1.0.0/go.mod h1:fMwpwEiuUgpab0sH4VHiVcEoji1pSi+EIzeG4TPeKPc= +github.com/gammazero/chanqueue v1.1.0 h1:yiwtloc1azhgGLFo2gMloJtQvkYD936Ai7tBfa+rYJw= +github.com/gammazero/chanqueue v1.1.0/go.mod h1:fMwpwEiuUgpab0sH4VHiVcEoji1pSi+EIzeG4TPeKPc= github.com/gammazero/deque v1.0.0 h1:LTmimT8H7bXkkCy6gZX7zNLtkbz4NdS2z8LZuor3j34= github.com/gammazero/deque v1.0.0/go.mod h1:iflpYvtGfM3U8S8j+sZEKIak3SAKYpA5/SQewgfXDKo= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= @@ -362,8 +362,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 h1:OqNqsGZPX8zh3eFMO8Lf8EHRRnSGBMqcd github.com/ipfs-shipyard/nopfs/ipfs v0.25.0/go.mod h1:BxhUdtBgOXg1B+gAPEplkg/GpyTZY+kCMSfsJvvydqU= 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.29.0 h1:clzd7PglUcE+Ufq1KucS3aKID7pzGVaSgcdRsW395t4= -github.com/ipfs/boxo v0.29.0/go.mod h1:c3R52nMlgMsN1tADffYcogKoVRsX1RJE1TMYSpJ4uVs= +github.com/ipfs/boxo v0.29.1-0.20250307073615-93ea580a3bb0 h1:wkFvXf7SqRiAu5ezj6lsieE2PwDk3nUkFOs9/+5lWdo= +github.com/ipfs/boxo v0.29.1-0.20250307073615-93ea580a3bb0/go.mod h1:MkDJStXiJS9U99cbAijHdcmwNfVn5DKYBmQCOgjY2NU= 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 6fca5043c0a..6fb22bf3d68 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -116,7 +116,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.29.0 // indirect + github.com/ipfs/boxo v0.29.1-0.20250307073615-93ea580a3bb0 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.5.0 // indirect github.com/ipfs/go-datastore v0.8.2 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 5ec6fbf5759..1fa1886037b 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -156,8 +156,8 @@ 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/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= -github.com/gammazero/chanqueue v1.0.0 h1:FER/sMailGFA3DDvFooEkipAMU+3c9Bg3bheloPSz6o= -github.com/gammazero/chanqueue v1.0.0/go.mod h1:fMwpwEiuUgpab0sH4VHiVcEoji1pSi+EIzeG4TPeKPc= +github.com/gammazero/chanqueue v1.1.0 h1:yiwtloc1azhgGLFo2gMloJtQvkYD936Ai7tBfa+rYJw= +github.com/gammazero/chanqueue v1.1.0/go.mod h1:fMwpwEiuUgpab0sH4VHiVcEoji1pSi+EIzeG4TPeKPc= github.com/gammazero/deque v1.0.0 h1:LTmimT8H7bXkkCy6gZX7zNLtkbz4NdS2z8LZuor3j34= github.com/gammazero/deque v1.0.0/go.mod h1:iflpYvtGfM3U8S8j+sZEKIak3SAKYpA5/SQewgfXDKo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -294,8 +294,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.29.0 h1:clzd7PglUcE+Ufq1KucS3aKID7pzGVaSgcdRsW395t4= -github.com/ipfs/boxo v0.29.0/go.mod h1:c3R52nMlgMsN1tADffYcogKoVRsX1RJE1TMYSpJ4uVs= +github.com/ipfs/boxo v0.29.1-0.20250307073615-93ea580a3bb0 h1:wkFvXf7SqRiAu5ezj6lsieE2PwDk3nUkFOs9/+5lWdo= +github.com/ipfs/boxo v0.29.1-0.20250307073615-93ea580a3bb0/go.mod h1:MkDJStXiJS9U99cbAijHdcmwNfVn5DKYBmQCOgjY2NU= 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.5.0 h1:goEKKhaGm0ul11IHA7I6p1GmKz8kEYniqFopaB5Otwg= From ba22102a640b3f41804319981d83908c96a96275 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 6 Mar 2025 15:19:19 +0100 Subject: [PATCH 03/42] provider: buffer pin providers. Fixes #10596. The reproviding process can take long. Currently, each CID to be provided is obtained by making a query to the pinner and reading one by one as the CIDs get provided. While this query is ongoing, the pinner holds a Read mutex on the pinset. If a pin-add-request arrives, a goroutine will start waiting for a Write mutex on the pinset. From that point, no new Read mutexes can be taken until the writer can proceed and finishes. However, no one can proceed because the read mutex is still held while the reproviding is ongoing. The fix is mostly in Boxo, where we add a "buffered" provider which reads the cids onto memory so that they can be provided at its own pace without making everyone wait. The consequence is we will need more RAM memory. Rule of thumb is 1GiB extra per 20M cids to be reprovided. --- core/node/provider.go | 13 ++++++++++--- docs/changelogs/v0.34.md | 5 +++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/core/node/provider.go b/core/node/provider.go index d6ab26b0c0d..78f0761cc14 100644 --- a/core/node/provider.go +++ b/core/node/provider.go @@ -167,16 +167,23 @@ func newProvidingStrategy(onlyPinned, onlyRoots bool) interface{} { IPLDFetcher fetcher.Factory `name:"ipldFetcher"` } return func(in input) provider.KeyChanFunc { + // Pinner-related CIDs will be buffered in memory to avoid + // deadlocking the pinner when the providing process is slow. + if onlyRoots { - return provider.NewPinnedProvider(true, in.Pinner, in.IPLDFetcher) + return provider.NewBufferedProvider( + provider.NewPinnedProvider(true, in.Pinner, in.IPLDFetcher), + ) } if onlyPinned { - return provider.NewPinnedProvider(false, in.Pinner, in.IPLDFetcher) + return provider.NewBufferedProvider( + provider.NewPinnedProvider(false, in.Pinner, in.IPLDFetcher), + ) } return provider.NewPrioritizedProvider( - provider.NewPinnedProvider(true, in.Pinner, in.IPLDFetcher), + provider.NewBufferedProvider(provider.NewPinnedProvider(true, in.Pinner, in.IPLDFetcher)), provider.NewBlockstoreProvider(in.Blockstore), ) } diff --git a/docs/changelogs/v0.34.md b/docs/changelogs/v0.34.md index b11ec3699e3..91877452589 100644 --- a/docs/changelogs/v0.34.md +++ b/docs/changelogs/v0.34.md @@ -14,6 +14,7 @@ - [Badger datastore update](#badger-datastore-update) - [Datastore Implementation Updates](#datastore-implementation-updates) - [One Multi-error Package](#one-multi-error-package) + - [Fix hanging pinset operations during reprovides](#fix-hanging-pinset-operations-during-reprovides) - [πŸ“¦οΈ Important dependency updates](#-important-dependency-updates) - [πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors](#-contributors) @@ -74,6 +75,10 @@ The go-ds-xxx datastore implementations have been updated to support the updated Kubo previously depended on multiple multi-error packages, `github.com/hashicorp/go-multierror` and `go.uber.org/multierr`. These have nearly identical functionality so there was no need to use both. Therefore, `go.uber.org/multierr` was selected as the package to depend on. Any future code needing multi-error functionality should use `go.uber.org/multierr` to avoid introducing unneeded dependencies. +#### Fix hanging pinset operations during reprovides + +The reprovide process can be quite slow. In default settings, the reprovide process will start reading CIDs that belong to the pinset. During this operation, starvation can occurr for other operations that need pinset access (see https://github.com/ipfs/kubo/issue/10596). We have now switch to buffering pinset-related cids that are going to be reprovided in memory, so that we can free pinset mutexes as soon as possible so that pinset-writes and subsequent read operations can proceed. The downside is larger pinsets will need some extra memory, with an estimation of ~1GiB of RAM memory-use per 20 million items to be reprovided. + #### πŸ“¦οΈ Important dependency updates - update `go-libp2p` to [v0.41.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.41.0) (incl. [v0.40.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.40.0)) From 9de938479cca7c223bf87cba17b54ce59245e207 Mon Sep 17 00:00:00 2001 From: Guillaume Michel Date: Fri, 7 Mar 2025 16:37:44 +0100 Subject: [PATCH 04/42] Update docs/changelogs/v0.34.md --- docs/changelogs/v0.34.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelogs/v0.34.md b/docs/changelogs/v0.34.md index 91877452589..8c1c5753e3f 100644 --- a/docs/changelogs/v0.34.md +++ b/docs/changelogs/v0.34.md @@ -77,7 +77,7 @@ Kubo previously depended on multiple multi-error packages, `github.com/hashicorp #### Fix hanging pinset operations during reprovides -The reprovide process can be quite slow. In default settings, the reprovide process will start reading CIDs that belong to the pinset. During this operation, starvation can occurr for other operations that need pinset access (see https://github.com/ipfs/kubo/issue/10596). We have now switch to buffering pinset-related cids that are going to be reprovided in memory, so that we can free pinset mutexes as soon as possible so that pinset-writes and subsequent read operations can proceed. The downside is larger pinsets will need some extra memory, with an estimation of ~1GiB of RAM memory-use per 20 million items to be reprovided. +The reprovide process can be quite slow. In default settings, the reprovide process will start reading CIDs that belong to the pinset. During this operation, starvation can occur for other operations that need pinset access (see https://github.com/ipfs/kubo/issue/10596). We have now switch to buffering pinset-related cids that are going to be reprovided in memory, so that we can free pinset mutexes as soon as possible so that pinset-writes and subsequent read operations can proceed. The downside is larger pinsets will need some extra memory, with an estimation of ~1GiB of RAM memory-use per 20 million items to be reprovided. #### πŸ“¦οΈ Important dependency updates From 095cc0d731e3addfc2b7505763dee7a67ba895ab Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Tue, 11 Mar 2025 14:04:16 -0700 Subject: [PATCH 05/42] Nonfunctional (#10753) * fix typos * fix func name in docstring * use t.TempDir instead of os.MkdirTemp * fix typo * unique option names --- config/bootstrap_peers.go | 2 +- core/commands/cid.go | 6 +++--- core/commands/cid_test.go | 4 ++-- repo/fsrepo/migrations/setup_test.go | 14 ++++++-------- test/cli/files_test.go | 2 +- 5 files changed, 13 insertions(+), 15 deletions(-) diff --git a/config/bootstrap_peers.go b/config/bootstrap_peers.go index 91f8ea1afa4..55fe66a986f 100644 --- a/config/bootstrap_peers.go +++ b/config/bootstrap_peers.go @@ -47,7 +47,7 @@ func (c *Config) SetBootstrapPeers(bps []peer.AddrInfo) { c.Bootstrap = BootstrapPeerStrings(bps) } -// ParseBootstrapPeer parses a bootstrap list into a list of AddrInfos. +// ParseBootstrapPeers parses a bootstrap list into a list of AddrInfos. func ParseBootstrapPeers(addrs []string) ([]peer.AddrInfo, error) { maddrs := make([]ma.Multiaddr, len(addrs)) for i, addr := range addrs { diff --git a/core/commands/cid.go b/core/commands/cid.go index a3f3a5490f4..26596f01155 100644 --- a/core/commands/cid.go +++ b/core/commands/cid.go @@ -34,7 +34,7 @@ var CidCmd = &cmds.Command{ const ( cidFormatOptionName = "f" - cidVerisonOptionName = "v" + cidToVersionOptionName = "v" cidCodecOptionName = "mc" cidMultibaseOptionName = "b" ) @@ -53,13 +53,13 @@ The optional format string is a printf style format string: }, Options: []cmds.Option{ cmds.StringOption(cidFormatOptionName, "Printf style format string.").WithDefault("%s"), - cmds.StringOption(cidVerisonOptionName, "CID version to convert to."), + cmds.StringOption(cidToVersionOptionName, "CID version to convert to."), cmds.StringOption(cidCodecOptionName, "CID multicodec to convert to."), cmds.StringOption(cidMultibaseOptionName, "Multibase to display CID in."), }, Run: func(req *cmds.Request, resp cmds.ResponseEmitter, env cmds.Environment) error { fmtStr, _ := req.Options[cidFormatOptionName].(string) - verStr, _ := req.Options[cidVerisonOptionName].(string) + verStr, _ := req.Options[cidToVersionOptionName].(string) codecStr, _ := req.Options[cidCodecOptionName].(string) baseStr, _ := req.Options[cidMultibaseOptionName].(string) diff --git a/core/commands/cid_test.go b/core/commands/cid_test.go index 10629628264..d159521d256 100644 --- a/core/commands/cid_test.go +++ b/core/commands/cid_test.go @@ -40,7 +40,7 @@ func TestCidFmtCmd(t *testing.T) { // Mock request req := &cmds.Request{ Options: map[string]interface{}{ - cidVerisonOptionName: "0", + cidToVersionOptionName: "0", cidMultibaseOptionName: e.MultibaseName, cidFormatOptionName: "%s", }, @@ -91,7 +91,7 @@ func TestCidFmtCmd(t *testing.T) { // Mock request req := &cmds.Request{ Options: map[string]interface{}{ - cidVerisonOptionName: e.Ver, + cidToVersionOptionName: e.Ver, cidMultibaseOptionName: e.MultibaseName, cidFormatOptionName: "%s", }, diff --git a/repo/fsrepo/migrations/setup_test.go b/repo/fsrepo/migrations/setup_test.go index 2e306fda17f..9761edb942f 100644 --- a/repo/fsrepo/migrations/setup_test.go +++ b/repo/fsrepo/migrations/setup_test.go @@ -32,9 +32,10 @@ var ( ) func TestMain(m *testing.M) { + t := &testing.T{} + // Setup test data - testDataDir := makeTestData() - defer os.RemoveAll(testDataDir) + testDataDir := makeTestData(t) testCar := makeTestCar(testDataDir) defer os.RemoveAll(testCar) @@ -47,18 +48,15 @@ func TestMain(m *testing.M) { os.Exit(m.Run()) } -func makeTestData() string { - tempDir, err := os.MkdirTemp("", "kubo-migrations-test-*") - if err != nil { - panic(err) - } +func makeTestData(t testing.TB) string { + tempDir := t.TempDir() 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) + err := os.MkdirAll(filepath.Join(tempDir, name), 0777) if err != nil { panic(err) } diff --git a/test/cli/files_test.go b/test/cli/files_test.go index 109c7ab9b50..27526189785 100644 --- a/test/cli/files_test.go +++ b/test/cli/files_test.go @@ -65,7 +65,7 @@ func TestFilesCp(t *testing.T) { // we manually changed codec from raw to dag-pb to test "bad dag-pb" scenario cid := "bafybeic7pdbte5heh6u54vszezob3el6exadoiw4wc4ne7ny2x7kvajzkm" - // should fail because node cant be read as a valid dag-pb + // should fail because node cannot be read as a valid dag-pb cpResNoForce := node.RunIPFS("files", "cp", fmt.Sprintf("/ipfs/%s", cid), "/invalid-proto") assert.NotEqual(t, 0, cpResNoForce.ExitErr.ExitCode()) assert.Contains(t, cpResNoForce.Stderr.String(), "Error") From 183dc7d40afb2326b11e052c8b90aab847592d5b Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Thu, 13 Mar 2025 16:44:01 -0700 Subject: [PATCH 06/42] Upgrade to Boxo v0.29.1 (#10755) * Upgrade to Boxo v0.29.1 --- docs/changelogs/v0.34.md | 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 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/changelogs/v0.34.md b/docs/changelogs/v0.34.md index 8c1c5753e3f..3e3ba289b1f 100644 --- a/docs/changelogs/v0.34.md +++ b/docs/changelogs/v0.34.md @@ -83,7 +83,7 @@ The reprovide process can be quite slow. In default settings, the reprovide proc - update `go-libp2p` to [v0.41.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.41.0) (incl. [v0.40.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.40.0)) - update `go-libp2p-kad-dht` to [v0.30.2](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.30.2) (incl. [v0.29.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.29.0), [v0.29.1](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.29.1), [v0.29.2](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.29.2), [v0.30.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.30.0), [v0.30.1](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.30.1)) -- update `boxo` to [v0.29.0](https://github.com/ipfs/boxo/releases/tag/v0.29.0) (incl. [v0.28.0](https://github.com/ipfs/boxo/releases/tag/v0.28.0) +- update `boxo` to [v0.29.1](https://github.com/ipfs/boxo/releases/tag/v0.29.1) (incl. [v0.28.0](https://github.com/ipfs/boxo/releases/tag/v0.28.0) [v0.29.0](https://github.com/ipfs/boxo/releases/tag/v0.29.0)) - update `ipfs-webui` to [v4.5.0](https://github.com/ipfs/ipfs-webui/releases/tag/v4.5.0) - update `p2p-forge/client` to [v0.4.0](https://github.com/ipshipyard/p2p-forge/releases/tag/v0.4.0) - update `go-datastore` to [v0.8.2](https://github.com/ipfs/go-datastore/releases/tag/v0.8.2) (incl. [v0.7.0](https://github.com/ipfs/go-datastore/releases/tag/v0.7.0), [v0.8.0](https://github.com/ipfs/go-datastore/releases/tag/v0.8.0)) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 8ca4390ed3c..bd1adb4b230 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.24 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.29.1-0.20250307073615-93ea580a3bb0 + github.com/ipfs/boxo v0.29.1 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.41.0 github.com/multiformats/go-multiaddr v0.15.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 6207a1d8abd..7a384b22e59 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -298,8 +298,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 h1:OqNqsGZPX8zh3eFMO8Lf8EHRRnSGBMqcd github.com/ipfs-shipyard/nopfs/ipfs v0.25.0/go.mod h1:BxhUdtBgOXg1B+gAPEplkg/GpyTZY+kCMSfsJvvydqU= 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.29.1-0.20250307073615-93ea580a3bb0 h1:wkFvXf7SqRiAu5ezj6lsieE2PwDk3nUkFOs9/+5lWdo= -github.com/ipfs/boxo v0.29.1-0.20250307073615-93ea580a3bb0/go.mod h1:MkDJStXiJS9U99cbAijHdcmwNfVn5DKYBmQCOgjY2NU= +github.com/ipfs/boxo v0.29.1 h1:z61ZT4YDfTHLjXTsu/+3wvJ8aJlExthDSOCpx6Nh8xc= +github.com/ipfs/boxo v0.29.1/go.mod h1:MkDJStXiJS9U99cbAijHdcmwNfVn5DKYBmQCOgjY2NU= 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 0bcfbc99de4..f655462f23c 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.14 github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 - github.com/ipfs/boxo v0.29.1-0.20250307073615-93ea580a3bb0 + github.com/ipfs/boxo v0.29.1 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.5.0 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 7e2b6e63afb..467408d7556 100644 --- a/go.sum +++ b/go.sum @@ -362,8 +362,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 h1:OqNqsGZPX8zh3eFMO8Lf8EHRRnSGBMqcd github.com/ipfs-shipyard/nopfs/ipfs v0.25.0/go.mod h1:BxhUdtBgOXg1B+gAPEplkg/GpyTZY+kCMSfsJvvydqU= 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.29.1-0.20250307073615-93ea580a3bb0 h1:wkFvXf7SqRiAu5ezj6lsieE2PwDk3nUkFOs9/+5lWdo= -github.com/ipfs/boxo v0.29.1-0.20250307073615-93ea580a3bb0/go.mod h1:MkDJStXiJS9U99cbAijHdcmwNfVn5DKYBmQCOgjY2NU= +github.com/ipfs/boxo v0.29.1 h1:z61ZT4YDfTHLjXTsu/+3wvJ8aJlExthDSOCpx6Nh8xc= +github.com/ipfs/boxo v0.29.1/go.mod h1:MkDJStXiJS9U99cbAijHdcmwNfVn5DKYBmQCOgjY2NU= 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 6fb22bf3d68..33f37ce8652 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -116,7 +116,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.29.1-0.20250307073615-93ea580a3bb0 // indirect + github.com/ipfs/boxo v0.29.1 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.5.0 // indirect github.com/ipfs/go-datastore v0.8.2 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 1fa1886037b..0aaa785bea9 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -294,8 +294,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.29.1-0.20250307073615-93ea580a3bb0 h1:wkFvXf7SqRiAu5ezj6lsieE2PwDk3nUkFOs9/+5lWdo= -github.com/ipfs/boxo v0.29.1-0.20250307073615-93ea580a3bb0/go.mod h1:MkDJStXiJS9U99cbAijHdcmwNfVn5DKYBmQCOgjY2NU= +github.com/ipfs/boxo v0.29.1 h1:z61ZT4YDfTHLjXTsu/+3wvJ8aJlExthDSOCpx6Nh8xc= +github.com/ipfs/boxo v0.29.1/go.mod h1:MkDJStXiJS9U99cbAijHdcmwNfVn5DKYBmQCOgjY2NU= 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.5.0 h1:goEKKhaGm0ul11IHA7I6p1GmKz8kEYniqFopaB5Otwg= From 96f3007b55169d5b178b4e0563ec2dda6e29d3f5 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 14 Mar 2025 17:55:35 +0100 Subject: [PATCH 07/42] docs(readme): update min. requirements + cleanup (#10750) * docs(readme): update min. requirements + cleanup Adding note about extra memory requirement due to https://github.com/ipfs/kubo/commit/ba22102a640b3f41804319981d83908c96a96275 * docs(config): memory cost of buffered provider Co-authored-by: Daniel Norman <1992255+2color@users.noreply.github.com> --- README.md | 32 +++++++++++++++----------------- docs/config.md | 7 ++++++- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 4970cd9aff6..2e6766877b6 100644 --- a/README.md +++ b/README.md @@ -12,19 +12,19 @@ Official Part of IPFS Project Discourse Forum Matrix - ci + GitHub release - godoc reference


## 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. +Kubo was the first IPFS implementation and is the most widely used one today. Implementing the *Interplanetary Filesystem* - the standard for content-addressing on the Web, interoperable with HTTP. Thus powered by future-proof data models and the libp2p for network communication. Kubo is written in Go. Featureset - Runs an IPFS-Node as a network service that is part of LAN and WAN DHT +- Native support for UnixFS (most popular way to represent files and directories on IPFS) - [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 @@ -64,12 +64,11 @@ 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) + - [Minimal System Requirements](#minimal-system-requirements) - [Docker](#docker) - [Official prebuilt binaries](#official-prebuilt-binaries) - [Updating](#updating) - - [Using ipfs-update](#using-ipfs-update) - [Downloading builds using IPFS](#downloading-builds-using-ipfs) - [Unofficial Linux packages](#unofficial-linux-packages) - [ArchLinux](#arch-linux) @@ -112,16 +111,21 @@ Before opening an issue, consider using one of the following locations to ensure Please follow [`SECURITY.md`](SECURITY.md). -### Minimal System Requirements +## Install -IPFS can run on most Linux, macOS, and Windows systems. We recommend running it on a machine with at least 6 GB of RAM and 2 CPU cores (ideally more, Kubo is highly parallel). +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. -> [!CAUTION] -> On systems with less memory, it may not be completely stable, and you run on your own risk. +For production use, Release Docker images (below) are recommended. -## Install +### Minimal System Requirements -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. +Kubo runs on most Linux, macOS, and Windows systems. For optimal performance, we recommend at least 6 GB of RAM and 2 CPU cores (more is ideal, as Kubo is highly parallel). + +> [!IMPORTANT] +> Larger pinsets require additional memory, with an estimated ~1 GiB of RAM per 20 million items for reproviding to the Amino DHT. + +> [!CAUTION] +> Systems with less than the recommended memory may experience instability, frequent OOM errors or restarts, and missing data announcement (reprovider window), which can make data fully or partially inaccessible to other peers. Running Kubo on underprovisioned hardware is at your own risk. ### Docker @@ -170,12 +174,6 @@ If you are unable to access [dist.ipfs.tech](https://dist.ipfs.tech#kubo), you c #### Updating -##### Using ipfs-update - -IPFS has an updating tool that can be accessed through `ipfs update`. The tool is -not installed alongside IPFS in order to keep that logic independent of the main -codebase. To install `ipfs-update` tool, [download it here](https://dist.ipfs.tech/#ipfs-update). - ##### Downloading builds using IPFS List the available versions of Kubo (go-ipfs) implementation: diff --git a/docs/config.md b/docs/config.md index 5b7aa614055..206d1f719f8 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1597,7 +1597,12 @@ 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 +- `"flat"` - same as `all`, announce all CIDs of stored blocks, but without prioritizing anything. + +> [!IMPORTANT] +> Reproviding larger pinsets using the `all`, `pinned`, or `roots` strategies requires additional memory, with an estimated ~1 GiB of RAM per 20 million items for reproviding to the Amino DHT. +> This is due to the use of a buffered provider, which avoids holding a lock on the entire pinset during the reprovide cycle. +> The `flat` strategy can be used to lower memory requirements, but only recommended if memory utilization is too high, prioritization of pins is not necessary, and it is acceptable to announce every block cached in the local repository. Default: `"all"` From b2efaa992f979f4053eee8decbb6d918da3fa247 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 14 Mar 2025 18:08:19 +0100 Subject: [PATCH 08/42] feat: ipfs-webui v4.6 (#10756) https://github.com/ipfs/ipfs-webui/releases/tag/v4.6.0 --- core/corehttp/webui.go | 3 ++- docs/changelogs/v0.34.md | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index 89315a24ed3..32d76a49deb 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/bafybeiata4qg7xjtwgor6r5dw63jjxyouenyromrrb4lrewxrlvav7gzgi" // v4.5.0 +const WebUIPath = "/ipfs/bafybeibpaa5kqrj4gkemiswbwndjqiryl65cks64ypwtyerxixu56gnvvm" // v4.6.0 // WebUIPaths is a list of all past webUI paths. var WebUIPaths = []string{ WebUIPath, + "/ipfs/bafybeiata4qg7xjtwgor6r5dw63jjxyouenyromrrb4lrewxrlvav7gzgi", // v4.5.0 "/ipfs/bafybeigp3zm7cqoiciqk5anlheenqjsgovp7j7zq6hah4nu6iugdgb4nby", // v4.4.2 "/ipfs/bafybeiatztgdllxnp5p6zu7bdwhjmozsmd7jprff4bdjqjljxtylitvss4", // v4.4.1 "/ipfs/bafybeibgic2ex3fvzkinhy6k6aqyv3zy2o7bkbsmrzvzka24xetv7eeadm", diff --git a/docs/changelogs/v0.34.md b/docs/changelogs/v0.34.md index 3e3ba289b1f..1d99f69ebe7 100644 --- a/docs/changelogs/v0.34.md +++ b/docs/changelogs/v0.34.md @@ -7,6 +7,7 @@ - [Overview](#overview) - [πŸ”¦ Highlights](#-highlights) - [AutoTLS now enabled by default for nodes with 1 hour uptime](#autotls-now-enabled-by-default-for-nodes-with-1-hour-uptime) + - [New WebUI features](#new-webui-features) - [RPC and CLI command changes](#rpc-and-cli-command-changes) - [Bitswap improvements from Boxo](#bitswap-improvements-from-boxo) - [`IPFS_LOG_LEVEL` deprecated](#ipfs_log_level-deprecated) @@ -44,6 +45,10 @@ To troubleshoot, use `GOLOG_LOG_LEVEL="error,autotls=info`. For more details, check out the [`AutoTLS` configuration documentation](https://github.com/ipfs/kubo/blob/master/docs/config.md#autotls) or dive deeper with [AutoTLS libp2p blog post](https://blog.libp2p.io/autotls/). +#### New WebUI features + +The WebUI, accessible at http://127.0.0.1:5001/webui/, now includes support for CAR file import and QR code sharing directly from the Files view. Additionally, the Peers screen has been updated with the latest [`ipfs-geoip`](https://www.npmjs.com/package/ipfs-geoip) dataset. + #### RPC and CLI command changes - `ipfs config` is now validating json fields ([#10679](https://github.com/ipfs/kubo/pull/10679)). @@ -84,7 +89,7 @@ The reprovide process can be quite slow. In default settings, the reprovide proc - update `go-libp2p` to [v0.41.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.41.0) (incl. [v0.40.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.40.0)) - update `go-libp2p-kad-dht` to [v0.30.2](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.30.2) (incl. [v0.29.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.29.0), [v0.29.1](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.29.1), [v0.29.2](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.29.2), [v0.30.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.30.0), [v0.30.1](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.30.1)) - update `boxo` to [v0.29.1](https://github.com/ipfs/boxo/releases/tag/v0.29.1) (incl. [v0.28.0](https://github.com/ipfs/boxo/releases/tag/v0.28.0) [v0.29.0](https://github.com/ipfs/boxo/releases/tag/v0.29.0)) -- update `ipfs-webui` to [v4.5.0](https://github.com/ipfs/ipfs-webui/releases/tag/v4.5.0) +- update `ipfs-webui` to [v4.6.0](https://github.com/ipfs/ipfs-webui/releases/tag/v4.6.0) (incl. [v4.5.0](https://github.com/ipfs/ipfs-webui/releases/tag/v4.5.0)) - update `p2p-forge/client` to [v0.4.0](https://github.com/ipshipyard/p2p-forge/releases/tag/v0.4.0) - update `go-datastore` to [v0.8.2](https://github.com/ipfs/go-datastore/releases/tag/v0.8.2) (incl. [v0.7.0](https://github.com/ipfs/go-datastore/releases/tag/v0.7.0), [v0.8.0](https://github.com/ipfs/go-datastore/releases/tag/v0.8.0)) From a9eb546cc4f13a8f81ccfc5191c1bcb47d38f7ce Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 20 Mar 2025 23:05:57 +0100 Subject: [PATCH 09/42] chore: start changelog for v0.35 --- CHANGELOG.md | 1 + docs/changelogs/v0.34.md | 4 ++++ docs/changelogs/v0.35.md | 25 +++++++++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 docs/changelogs/v0.35.md diff --git a/CHANGELOG.md b/CHANGELOG.md index bf92b1e6a7a..1513562ffd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Kubo Changelogs +- [v0.35](docs/changelogs/v0.35.md) - [v0.34](docs/changelogs/v0.34.md) - [v0.33](docs/changelogs/v0.33.md) - [v0.32](docs/changelogs/v0.32.md) diff --git a/docs/changelogs/v0.34.md b/docs/changelogs/v0.34.md index c89f41675f5..3f1cd27a5a1 100644 --- a/docs/changelogs/v0.34.md +++ b/docs/changelogs/v0.34.md @@ -1,5 +1,9 @@ # Kubo changelog v0.34 + + +This release was brought to you by the [Shipyard](http://ipshipyard.com/) team. + - [v0.34.0](#v0340) ## v0.34.0 diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md new file mode 100644 index 00000000000..7b261ed5501 --- /dev/null +++ b/docs/changelogs/v0.35.md @@ -0,0 +1,25 @@ +# Kubo changelog v0.35 + + + +This release was brought to you by the [Shipyard](http://ipshipyard.com/) team. + +- [v0.35.0](#v0340) + +## v0.35.0 + +- [Overview](#overview) +- [πŸ”¦ Highlights](#-highlights) + - [πŸ“¦οΈ Important dependency updates](#-important-dependency-updates) +- [πŸ“ Changelog](#-changelog) +- [πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors](#-contributors) + +### Overview + +### πŸ”¦ Highlights + +#### πŸ“¦οΈ Important dependency updates + +### πŸ“ Changelog + +### πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors From ecca2eba8e8350f6003a5e0001eaea4de5e543a9 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 24 Mar 2025 15:16:46 +0100 Subject: [PATCH 10/42] Support WithIgnoreProviders() in provider query manager Adds `Routing.IgnoreProviders`. This requires initializing a custom providerQueryManager and using it instead of the default created internally in Bitswap. Since the default is created with some internal default configuration options (MaxProviders), this hardcodes it. --- config/init.go | 7 ++++--- config/routing.go | 4 ++++ core/node/bitswap.go | 21 ++++++++++++++++++--- docs/config.md | 14 ++++++++++++++ 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/config/init.go b/config/init.go index f5217f413f1..a0351bd8b18 100644 --- a/config/init.go +++ b/config/init.go @@ -48,9 +48,10 @@ func InitWithIdentity(identity Identity) (*Config, error) { }, Routing: Routing{ - Type: nil, - Methods: nil, - Routers: nil, + Type: nil, + Methods: nil, + Routers: nil, + IgnoreProviders: []peer.ID{}, }, // setup the node mount points. diff --git a/config/routing.go b/config/routing.go index 52d8b7296b4..a6f899a1ca9 100644 --- a/config/routing.go +++ b/config/routing.go @@ -6,6 +6,8 @@ import ( "os" "runtime" "strings" + + peer "github.com/libp2p/go-libp2p/core/peer" ) const ( @@ -41,6 +43,8 @@ type Routing struct { LoopbackAddressesOnLanDHT Flag `json:",omitempty"` + IgnoreProviders []peer.ID + Routers Routers Methods Methods diff --git a/core/node/bitswap.go b/core/node/bitswap.go index a310709bd6a..4bcc9706604 100644 --- a/core/node/bitswap.go +++ b/core/node/bitswap.go @@ -5,11 +5,13 @@ import ( "time" "github.com/ipfs/boxo/bitswap" + "github.com/ipfs/boxo/bitswap/client" bsnet "github.com/ipfs/boxo/bitswap/network/bsnet" blockstore "github.com/ipfs/boxo/blockstore" exchange "github.com/ipfs/boxo/exchange" "github.com/ipfs/boxo/exchange/providing" provider "github.com/ipfs/boxo/provider" + rpqm "github.com/ipfs/boxo/routing/providerquerymanager" "github.com/ipfs/kubo/config" irouting "github.com/ipfs/kubo/routing" "github.com/libp2p/go-libp2p/core/host" @@ -61,6 +63,7 @@ type bitswapIn struct { fx.In Mctx helpers.MetricsCtx + Cfg *config.Config Host host.Host Rt irouting.ProvideManyRouter Bs blockstore.GCBlockstore @@ -71,12 +74,24 @@ type bitswapIn struct { // Additional options to bitswap.New can be provided via the "bitswap-options" // group. func Bitswap(provide bool) interface{} { - return func(in bitswapIn, lc fx.Lifecycle) *bitswap.Bitswap { + return func(in bitswapIn, lc fx.Lifecycle) (*bitswap.Bitswap, error) { bitswapNetwork := bsnet.NewFromIpfsHost(in.Host) var provider routing.ContentDiscovery if provide { - provider = in.Rt + // We need to hardcode the default because it is an + // internal setting in boxo. + pqm, err := rpqm.New(bitswapNetwork, + in.Rt, + rpqm.WithMaxProviders(10), + rpqm.WithIgnoreProviders(in.Cfg.Routing.IgnoreProviders...), + ) + if err != nil { + return nil, err + } + in.BitswapOpts = append(in.BitswapOpts, bitswap.WithClientOption(client.WithDefaultProviderQueryManager(false))) + provider = pqm + } bs := bitswap.New(helpers.LifecycleCtx(in.Mctx, lc), bitswapNetwork, provider, in.Bs, in.BitswapOpts...) @@ -85,7 +100,7 @@ func Bitswap(provide bool) interface{} { return bs.Close() }, }) - return bs + return bs, nil } } diff --git a/docs/config.md b/docs/config.md index 206d1f719f8..6056510b8a3 100644 --- a/docs/config.md +++ b/docs/config.md @@ -119,6 +119,7 @@ config file at runtime. - [`Routing.Type`](#routingtype) - [`Routing.AcceleratedDHTClient`](#routingaccelerateddhtclient) - [`Routing.LoopbackAddressesOnLanDHT`](#routingloopbackaddressesonlandht) + - [`Routing.IgnoreProviders`](#routingignoreproviders) - [`Routing.Routers`](#routingrouters) - [`Routing.Routers: Type`](#routingrouters-type) - [`Routing.Routers: Parameters`](#routingrouters-parameters) @@ -1718,6 +1719,19 @@ Default: `false` Type: `bool` (missing means `false`) +### `Routing.IgnoreProviders` + +An array of peerIDs. Any provider record associated to one of these peer IDs is ignored. + +Apart from ignoring specific providers for reasons like misbehaviour etc. this +setting is useful to ignore providers as a way to indicate preference, when the same provider +is found under different peerIDs (i.e. one for HTTP and one for Bitswap retrieval). + +Default: `[]` + +Type: `array[peerID]` + + ### `Routing.Routers` **EXPERIMENTAL: `Routing.Routers` configuration may change in future release** From 1d9e3d6c4f10bb5937785cd9828e7beda3b8e2ae Mon Sep 17 00:00:00 2001 From: Guillaume Michel Date: Tue, 25 Mar 2025 15:48:10 +0000 Subject: [PATCH 11/42] fix: reprovides warning (#10761) --- core/node/provider.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/node/provider.go b/core/node/provider.go index 78f0761cc14..51b12862b7a 100644 --- a/core/node/provider.go +++ b/core/node/provider.go @@ -26,7 +26,7 @@ func ProviderSys(reprovideInterval time.Duration, acceleratedDHTClient bool) fx. provider.ReproviderInterval(reprovideInterval), provider.KeyProvider(keyProvider), } - if !acceleratedDHTClient { + if !acceleratedDHTClient && reprovideInterval > 0 { // 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 @@ -68,7 +68,7 @@ func ProviderSys(reprovideInterval time.Duration, acceleratedDHTClient bool) fx. πŸ””πŸ””πŸ”” 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. +This means your content could be 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, @@ -97,7 +97,7 @@ https://github.com/ipfs/kubo/blob/master/docs/config.md#routingaccelerateddhtcli πŸ””πŸ””πŸ”” 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. +This means your content could be 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. From 112eb61f66f07e96c16405940c532a1a6c0f6f7c Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 1 Apr 2025 09:53:28 +0200 Subject: [PATCH 12/42] changelog: add mention to IgnoreProviders --- docs/changelogs/v0.35.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index 7b261ed5501..d1432a1f41c 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -18,6 +18,13 @@ This release was brought to you by the [Shipyard](http://ipshipyard.com/) team. ### πŸ”¦ Highlights +##### `Routing.IgnoreProviders` + +This new option allows ignoring specific peer IDs when returned by the content +routing system as providers of content. See the +[documentation](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingignoreproviders) +for for information. + #### πŸ“¦οΈ Important dependency updates ### πŸ“ Changelog From ef7cc60a5bec1dc6498eeee5eb5dc6071f5e4341 Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Tue, 1 Apr 2025 16:26:38 +0200 Subject: [PATCH 13/42] docs: Fix typo in v0.34 changelog (#10771) --- docs/changelogs/v0.34.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelogs/v0.34.md b/docs/changelogs/v0.34.md index 22fc5b24a17..2b4761de1f0 100644 --- a/docs/changelogs/v0.34.md +++ b/docs/changelogs/v0.34.md @@ -148,7 +148,7 @@ Use [`Reprovider.Strategy`](https://github.com/ipfs/kubo/blob/master/docs/config - fix: switch away from IPFS_LOG_LEVEL (#10694) ([ipfs/kubo#10694](https://github.com/ipfs/kubo/pull/10694)) - Merge release v0.33.2 ([ipfs/kubo#10713](https://github.com/ipfs/kubo/pull/10713)) - Remove unused TimeParts struct (#10708) ([ipfs/kubo#10708](https://github.com/ipfs/kubo/pull/10708)) - - fix(rpc): restore and reprecate `bitswap reprovide` (#10699) ([ipfs/kubo#10699](https://github.com/ipfs/kubo/pull/10699)) + - fix(rpc): restore and deprecate `bitswap reprovide` (#10699) ([ipfs/kubo#10699](https://github.com/ipfs/kubo/pull/10699)) - docs(release): update RELEASE_CHECKLIST.md after v0.33.1 (#10697) ([ipfs/kubo#10697](https://github.com/ipfs/kubo/pull/10697)) - docs: update min requirements (#10687) ([ipfs/kubo#10687](https://github.com/ipfs/kubo/pull/10687)) - Merge release v0.33.1 ([ipfs/kubo#10698](https://github.com/ipfs/kubo/pull/10698)) From fd50eb0fc385ec35cc2269646182920849b3c9b5 Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Tue, 1 Apr 2025 16:28:12 +0200 Subject: [PATCH 14/42] fix: Add IPFS & IPNS path details to error (re. #10762) (#10770) --- fuse/node/mount_unix.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fuse/node/mount_unix.go b/fuse/node/mount_unix.go index 63763996b2f..a5a2a371688 100644 --- a/fuse/node/mount_unix.go +++ b/fuse/node/mount_unix.go @@ -89,11 +89,11 @@ func doMount(node *core.IpfsNode, fsdir, nsdir string) error { wg.Wait() if err1 != nil { - log.Errorf("error mounting: %s", err1) + log.Errorf("error mounting IPFS %s: %s", fsdir, err1) } if err2 != nil { - log.Errorf("error mounting: %s", err2) + log.Errorf("error mounting IPNS %s for IPFS %s: %s", nsdir, fsdir, err2) } if err1 != nil || err2 != nil { From d7f026606814754d116dfc218426ddec4ff58075 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 4 Apr 2025 01:07:40 +0200 Subject: [PATCH 15/42] docs: known issues with file/urlstores (#10768) Co-authored-by: Andrew Gillis <11790789+gammazero@users.noreply.github.com> --- docs/experimental-features.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/experimental-features.md b/docs/experimental-features.md index 84a9adfc3a4..3fccdad197f 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -87,6 +87,10 @@ filestore instead of copying the files into your local IPFS repo. - [ ] Needs more people to use and report on how well it works. - [ ] Need to address error states and failure conditions + - [ ] cleanup of broken filesystem references (if file is deleted) + - [ ] tests that confirm ability to override preexisting filesystem links (allowing user to fix broken link) + - [ ] support for a a single block having more than one sources in filesystem (blocks can be shared by unrelated files, and not be broken when some files are unpinned / gc'd) + - [ ] [other known issues](https://github.com/ipfs/kubo/issues/7161) - [ ] Need to write docs on usage, advantages, disadvantages - [ ] Need to merge utility commands to aid in maintenance and repair of filestore @@ -122,6 +126,9 @@ And then add a file at a specific URL using `ipfs urlstore add ` ### Road to being a real feature - [ ] Needs more people to use and report on how well it works. - [ ] Need to address error states and failure conditions + - [ ] cleanup of broken URL+range references (if URL starts returning 404 or error) + - [ ] tests that confirm ability to override preexisting URL+range links (allowing user to fix broken link) + - [ ] support for a a single block having more than one URL+range (blocks can be shared by unrelated URLs) - [ ] Need to write docs on usage, advantages, disadvantages - [ ] Need to implement caching - [ ] Need to add metrics to monitor performance From 19b591da9fc0601744d0f0879e4f237992a738c2 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 8 Apr 2025 15:17:34 +0200 Subject: [PATCH 16/42] chore: update url --- test/sharness/t0165-keystore-data/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sharness/t0165-keystore-data/README.md b/test/sharness/t0165-keystore-data/README.md index 4c0a68b5169..298b7708e95 100644 --- a/test/sharness/t0165-keystore-data/README.md +++ b/test/sharness/t0165-keystore-data/README.md @@ -8,7 +8,7 @@ openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 > openssl_rsa.pem ``` secp key used in the 'restrict import key' test. -From: https://www.openssl.org/docs/man1.1.1/man1/openssl-genpkey.html +From: https://docs.openssl.org/1.1.1/man1/genpkey/ ```bash openssl genpkey -genparam -algorithm EC -out ecp.pem \ -pkeyopt ec_paramgen_curve:secp384r1 \ From 996bcf30a687a1334379d5df9d4dc2579970a70f Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Wed, 9 Apr 2025 18:28:29 +0200 Subject: [PATCH 17/42] feat: partial DAG provides with Reprovider.Strategy=mfs|pinned+mfs (#10754) Co-authored-by: Marcin Rataj --- core/node/core.go | 1 + core/node/provider.go | 88 +++++++++++++------ docs/changelogs/v0.35.md | 11 +++ docs/config.md | 13 ++- 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 +- .../t0119-prometheus-data/prometheus_metrics | 1 + 11 files changed, 91 insertions(+), 41 deletions(-) diff --git a/core/node/core.go b/core/node/core.go index 1c372b642c3..cb34399394d 100644 --- a/core/node/core.go +++ b/core/node/core.go @@ -115,6 +115,7 @@ func FetcherConfig(bs blockservice.BlockService) FetchersOut { // path resolution should not fetch new blocks via exchange. offlineBs := blockservice.New(bs.Blockstore(), offline.Exchange(bs.Blockstore())) offlineIpldFetcher := bsfetcher.NewFetcherConfig(offlineBs) + offlineIpldFetcher.SkipNotFound = true // carries onto the UnixFSFetcher below offlineIpldFetcher.PrototypeChooser = dagpb.AddSupportToChooser(bsfetcher.DefaultPrototypeChooser) offlineUnixFSFetcher := offlineIpldFetcher.WithReifier(unixfsnode.Reify) diff --git a/core/node/provider.go b/core/node/provider.go index 51b12862b7a..4638aad4dc5 100644 --- a/core/node/provider.go +++ b/core/node/provider.go @@ -7,8 +7,10 @@ import ( "github.com/ipfs/boxo/blockstore" "github.com/ipfs/boxo/fetcher" + "github.com/ipfs/boxo/mfs" pin "github.com/ipfs/boxo/pinning/pinner" provider "github.com/ipfs/boxo/provider" + "github.com/ipfs/go-cid" "github.com/ipfs/kubo/repo" irouting "github.com/ipfs/kubo/routing" "go.uber.org/fx" @@ -136,14 +138,8 @@ func OnlineProviders(useStrategicProviding bool, reprovideStrategy string, repro var keyProvider fx.Option switch reprovideStrategy { - case "all", "": - keyProvider = fx.Provide(newProvidingStrategy(false, false)) - case "roots": - keyProvider = fx.Provide(newProvidingStrategy(true, true)) - case "pinned": - keyProvider = fx.Provide(newProvidingStrategy(true, false)) - case "flat": - keyProvider = fx.Provide(provider.NewBlockstoreProvider) + case "all", "", "roots", "pinned", "mfs", "pinned+mfs", "flat": + keyProvider = fx.Provide(newProvidingStrategy(reprovideStrategy)) default: return fx.Error(fmt.Errorf("unknown reprovider strategy %q", reprovideStrategy)) } @@ -159,32 +155,68 @@ func OfflineProviders() fx.Option { return fx.Provide(provider.NewNoopProvider) } -func newProvidingStrategy(onlyPinned, onlyRoots bool) interface{} { +func mfsProvider(mfsRoot *mfs.Root, fetcher fetcher.Factory) provider.KeyChanFunc { + return func(ctx context.Context) (<-chan cid.Cid, error) { + err := mfsRoot.FlushMemFree(ctx) + if err != nil { + return nil, fmt.Errorf("error flushing mfs, cannot provide MFS: %w", err) + } + rootNode, err := mfsRoot.GetDirectory().GetNode() + if err != nil { + return nil, fmt.Errorf("error loading mfs root, cannot provide MFS: %w", err) + } + + kcf := provider.NewDAGProvider(rootNode.Cid(), fetcher) + return kcf(ctx) + } + +} + +func mfsRootProvider(mfsRoot *mfs.Root) provider.KeyChanFunc { + return func(ctx context.Context) (<-chan cid.Cid, error) { + rootNode, err := mfsRoot.GetDirectory().GetNode() + if err != nil { + return nil, fmt.Errorf("error loading mfs root, cannot provide MFS: %w", err) + } + ch := make(chan cid.Cid, 1) + ch <- rootNode.Cid() + close(ch) + return ch, nil + } +} + +func newProvidingStrategy(strategy string) interface{} { type input struct { fx.In - Pinner pin.Pinner - Blockstore blockstore.Blockstore - IPLDFetcher fetcher.Factory `name:"ipldFetcher"` + Pinner pin.Pinner + Blockstore blockstore.Blockstore + OfflineIPLDFetcher fetcher.Factory `name:"offlineIpldFetcher"` + OfflineUnixFSFetcher fetcher.Factory `name:"offlineUnixfsFetcher"` + MFSRoot *mfs.Root } return func(in input) provider.KeyChanFunc { - // Pinner-related CIDs will be buffered in memory to avoid - // deadlocking the pinner when the providing process is slow. - - if onlyRoots { - return provider.NewBufferedProvider( - provider.NewPinnedProvider(true, in.Pinner, in.IPLDFetcher), + switch strategy { + case "roots": + return provider.NewBufferedProvider(provider.NewPinnedProvider(true, in.Pinner, in.OfflineIPLDFetcher)) + case "pinned": + return provider.NewBufferedProvider(provider.NewPinnedProvider(false, in.Pinner, in.OfflineIPLDFetcher)) + case "pinned+mfs": + return provider.NewPrioritizedProvider( + provider.NewBufferedProvider(provider.NewPinnedProvider(false, in.Pinner, in.OfflineIPLDFetcher)), + mfsProvider(in.MFSRoot, in.OfflineUnixFSFetcher), ) - } - - if onlyPinned { - return provider.NewBufferedProvider( - provider.NewPinnedProvider(false, in.Pinner, in.IPLDFetcher), + case "mfs": + return mfsProvider(in.MFSRoot, in.OfflineUnixFSFetcher) + case "flat": + return provider.NewBlockstoreProvider(in.Blockstore) + default: // "all", "" + return provider.NewPrioritizedProvider( + provider.NewPrioritizedProvider( + provider.NewBufferedProvider(provider.NewPinnedProvider(true, in.Pinner, in.OfflineIPLDFetcher)), + mfsRootProvider(in.MFSRoot), + ), + provider.NewBlockstoreProvider(in.Blockstore), ) } - - return provider.NewPrioritizedProvider( - provider.NewBufferedProvider(provider.NewPinnedProvider(true, in.Pinner, in.IPLDFetcher)), - provider.NewBlockstoreProvider(in.Blockstore), - ) } } diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index d1432a1f41c..a41a7040c58 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -10,6 +10,7 @@ This release was brought to you by the [Shipyard](http://ipshipyard.com/) team. - [Overview](#overview) - [πŸ”¦ Highlights](#-highlights) + - [Dedicated `Reprovider.Strategy` for MFS](#dedicated-reproviderstrategy-for-mfs) - [πŸ“¦οΈ Important dependency updates](#-important-dependency-updates) - [πŸ“ Changelog](#-changelog) - [πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors](#-contributors) @@ -18,6 +19,16 @@ This release was brought to you by the [Shipyard](http://ipshipyard.com/) team. ### πŸ”¦ Highlights +#### Dedicated `Reprovider.Strategy` for MFS + +The [Mutable File System (MFS)](https://docs.ipfs.tech/concepts/glossary/#mfs) in Kubo is a UnixFS filesystem managed with [`ipfs files`](https://docs.ipfs.tech/reference/kubo/cli/#ipfs-files) commands. It supports familiar file operations like cp and mv within a folder-tree structure, automatically updating a MerkleDAG and a "root CID" that reflects the current MFS state. Files in MFS are protected from garbage collection, offering a simpler alternative to `ipfs pin`. This makes it a popular choice for tools like [IPFS Desktop](https://docs.ipfs.tech/install/ipfs-desktop/) and the [WebUI](https://github.com/ipfs/ipfs-webui/#readme). + +Previously, the `pinned` reprovider strategy required manual pin management: each dataset update meant pinning the new version and unpinning the old one. Now, new strategiesβ€”`mfs` and `pinned+mfs`β€”let users limit announcements to data explicitly placed in MFS. This simplifies updating datasets and announcing only the latest version to the Amino DHT. + +Users relying on the `pinned` strategy can switch to `pinned+mfs` and use MFS alone to manage updates and announcements, eliminating the need for manual pinning and unpinning. We hope this makes it easier to publish just the data that matters to you. + +See [`Reprovider.Strategy`](https://github.com/ipfs/kubo/blob/master/docs/config.md#reproviderstrategy) for more details. + ##### `Routing.IgnoreProviders` This new option allows ignoring specific peer IDs when returned by the content diff --git a/docs/config.md b/docs/config.md index 6056510b8a3..8ff11a408d4 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1587,10 +1587,10 @@ 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 and MFS root are announced first, then the rest of blockstore +- `"pinned"` - only announce recursively pinned CIDs (`ipfs pin add -r`, 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 +- `"roots"` - only announce the root block of explicitly pinned CIDs (`ipfs pin add`) - **⚠️ 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 @@ -1598,10 +1598,15 @@ 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. +- `"mfs"` - announce only the local CIDs that are part of the MFS (`ipfs files`) + - Note: MFS is lazy-loaded. Only the MFS blocks present in local datastore are announced. +- `"pinned+mfs"` - a combination of the `pinned` and `mfs` strategies. + - **ℹ️ NOTE:** This is the suggested strategy for users who run without GC and don't want to provide everything in cache. + - Order: first `pinned` and then the locally available part of `mfs`. - `"flat"` - same as `all`, announce all CIDs of stored blocks, but without prioritizing anything. > [!IMPORTANT] -> Reproviding larger pinsets using the `all`, `pinned`, or `roots` strategies requires additional memory, with an estimated ~1 GiB of RAM per 20 million items for reproviding to the Amino DHT. +> Reproviding larger pinsets using the `all`, `mfs`, `pinned`, `pinned+mfs` or `roots` strategies requires additional memory, with an estimated ~1 GiB of RAM per 20 million items for reproviding to the Amino DHT. > This is due to the use of a buffered provider, which avoids holding a lock on the entire pinset during the reprovide cycle. > The `flat` strategy can be used to lower memory requirements, but only recommended if memory utilization is too high, prioritization of pins is not necessary, and it is acceptable to announce every block cached in the local repository. diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 38b3e64e9a1..bfaa528c9e7 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.24 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.29.1 + github.com/ipfs/boxo v0.29.2-0.20250409154342-bbaf2e146dfb github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.41.1 github.com/multiformats/go-multiaddr v0.15.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index f8fc2a88567..eb2997529af 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -298,8 +298,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 h1:OqNqsGZPX8zh3eFMO8Lf8EHRRnSGBMqcd github.com/ipfs-shipyard/nopfs/ipfs v0.25.0/go.mod h1:BxhUdtBgOXg1B+gAPEplkg/GpyTZY+kCMSfsJvvydqU= 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.29.1 h1:z61ZT4YDfTHLjXTsu/+3wvJ8aJlExthDSOCpx6Nh8xc= -github.com/ipfs/boxo v0.29.1/go.mod h1:MkDJStXiJS9U99cbAijHdcmwNfVn5DKYBmQCOgjY2NU= +github.com/ipfs/boxo v0.29.2-0.20250409154342-bbaf2e146dfb h1:kA7c3CF6/d8tUwGJR/SwIfaRz7Xk7Fbyoh2ePZAFMlw= +github.com/ipfs/boxo v0.29.2-0.20250409154342-bbaf2e146dfb/go.mod h1:omQZmLS7LegSpBy3m4CrAB9/SO7Fq3pfv+5y1FOd+gI= 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 1abbe78123d..8975eb21054 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.14 github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 - github.com/ipfs/boxo v0.29.1 + github.com/ipfs/boxo v0.29.2-0.20250409154342-bbaf2e146dfb github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.5.0 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 91d34dbbdb0..e926a459635 100644 --- a/go.sum +++ b/go.sum @@ -362,8 +362,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 h1:OqNqsGZPX8zh3eFMO8Lf8EHRRnSGBMqcd github.com/ipfs-shipyard/nopfs/ipfs v0.25.0/go.mod h1:BxhUdtBgOXg1B+gAPEplkg/GpyTZY+kCMSfsJvvydqU= 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.29.1 h1:z61ZT4YDfTHLjXTsu/+3wvJ8aJlExthDSOCpx6Nh8xc= -github.com/ipfs/boxo v0.29.1/go.mod h1:MkDJStXiJS9U99cbAijHdcmwNfVn5DKYBmQCOgjY2NU= +github.com/ipfs/boxo v0.29.2-0.20250409154342-bbaf2e146dfb h1:kA7c3CF6/d8tUwGJR/SwIfaRz7Xk7Fbyoh2ePZAFMlw= +github.com/ipfs/boxo v0.29.2-0.20250409154342-bbaf2e146dfb/go.mod h1:omQZmLS7LegSpBy3m4CrAB9/SO7Fq3pfv+5y1FOd+gI= 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 3f6a1e39bcd..0cf72f9ca8a 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -116,7 +116,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.29.1 // indirect + github.com/ipfs/boxo v0.29.2-0.20250409154342-bbaf2e146dfb // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.5.0 // indirect github.com/ipfs/go-datastore v0.8.2 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 757ab2b7c52..4fef97504e1 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -294,8 +294,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.29.1 h1:z61ZT4YDfTHLjXTsu/+3wvJ8aJlExthDSOCpx6Nh8xc= -github.com/ipfs/boxo v0.29.1/go.mod h1:MkDJStXiJS9U99cbAijHdcmwNfVn5DKYBmQCOgjY2NU= +github.com/ipfs/boxo v0.29.2-0.20250409154342-bbaf2e146dfb h1:kA7c3CF6/d8tUwGJR/SwIfaRz7Xk7Fbyoh2ePZAFMlw= +github.com/ipfs/boxo v0.29.2-0.20250409154342-bbaf2e146dfb/go.mod h1:omQZmLS7LegSpBy3m4CrAB9/SO7Fq3pfv+5y1FOd+gI= 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.5.0 h1:goEKKhaGm0ul11IHA7I6p1GmKz8kEYniqFopaB5Otwg= diff --git a/test/sharness/t0119-prometheus-data/prometheus_metrics b/test/sharness/t0119-prometheus-data/prometheus_metrics index 60475da439f..07cd44d8f5c 100644 --- a/test/sharness/t0119-prometheus-data/prometheus_metrics +++ b/test/sharness/t0119-prometheus-data/prometheus_metrics @@ -1,3 +1,4 @@ +exchange_bitswap_requests_in_flight exchange_bitswap_response_bytes_bucket exchange_bitswap_response_bytes_count exchange_bitswap_response_bytes_sum From ee7fef251cd23dc69304f8a0edb85884df794139 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 9 Apr 2025 20:58:32 +0200 Subject: [PATCH 18/42] feat: ipfs-webui v4.7.0 (#10780) https://github.com/ipfs/ipfs-webui/releases/tag/v4.7.0 --- core/corehttp/webui.go | 3 ++- docs/changelogs/v0.35.md | 12 +++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index 32d76a49deb..387a5b9ca72 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/bafybeibpaa5kqrj4gkemiswbwndjqiryl65cks64ypwtyerxixu56gnvvm" // v4.6.0 +const WebUIPath = "/ipfs/bafybeibfd5kbebqqruouji6ct5qku3tay273g7mt24mmrfzrsfeewaal5y" // v4.7.0 // WebUIPaths is a list of all past webUI paths. var WebUIPaths = []string{ WebUIPath, + "/ipfs/bafybeibpaa5kqrj4gkemiswbwndjqiryl65cks64ypwtyerxixu56gnvvm", // v4.6.0 "/ipfs/bafybeiata4qg7xjtwgor6r5dw63jjxyouenyromrrb4lrewxrlvav7gzgi", // v4.5.0 "/ipfs/bafybeigp3zm7cqoiciqk5anlheenqjsgovp7j7zq6hah4nu6iugdgb4nby", // v4.4.2 "/ipfs/bafybeiatztgdllxnp5p6zu7bdwhjmozsmd7jprff4bdjqjljxtylitvss4", // v4.4.1 diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index a41a7040c58..0d55c1aa6c6 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -11,6 +11,8 @@ This release was brought to you by the [Shipyard](http://ipshipyard.com/) team. - [Overview](#overview) - [πŸ”¦ Highlights](#-highlights) - [Dedicated `Reprovider.Strategy` for MFS](#dedicated-reproviderstrategy-for-mfs) + - [`Routing.IgnoreProviders`](#routingignoreproviders) + - [Grid view in WebUI](#grid-view-in-webui) - [πŸ“¦οΈ Important dependency updates](#-important-dependency-updates) - [πŸ“ Changelog](#-changelog) - [πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors](#-contributors) @@ -29,15 +31,23 @@ Users relying on the `pinned` strategy can switch to `pinned+mfs` and use MFS al See [`Reprovider.Strategy`](https://github.com/ipfs/kubo/blob/master/docs/config.md#reproviderstrategy) for more details. -##### `Routing.IgnoreProviders` +#### `Routing.IgnoreProviders` This new option allows ignoring specific peer IDs when returned by the content routing system as providers of content. See the [documentation](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingignoreproviders) for for information. +#### Grid view in WebUI + +The WebUI, accessible at http://127.0.0.1:5001/webui/, now includes support for the grid view on the _Files_ screen: + +> ![image](https://github.com/user-attachments/assets/80dcf0d0-8103-426f-ae91-416fb25d32b6) + #### πŸ“¦οΈ Important dependency updates +- update `ipfs-webui` to [v4.7.0](https://github.com/ipfs/ipfs-webui/releases/tag/v4.7.0) + ### πŸ“ Changelog ### πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors From fe3106f9a645f3a5bc348b94454012d0dd90b448 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 9 Apr 2025 21:17:19 +0200 Subject: [PATCH 19/42] feat(config): expose ProviderSearchMaxResults (#10773) Replacing hardcoded integer with named default and expose config option for adjusting it, like we do in Rainbow https://github.com/ipfs/kubo/pull/10765/files#r2025455848 --- config/internal.go | 1 + core/node/bitswap.go | 9 ++++++--- docs/changelogs/v0.35.md | 10 ++++------ docs/config.md | 14 +++++++++++--- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/config/internal.go b/config/internal.go index f43746534a3..fe7e8432085 100644 --- a/config/internal.go +++ b/config/internal.go @@ -14,5 +14,6 @@ type InternalBitswap struct { EngineTaskWorkerCount OptionalInteger MaxOutstandingBytesPerPeer OptionalInteger ProviderSearchDelay OptionalDuration + ProviderSearchMaxResults OptionalInteger WantHaveReplaceSize OptionalInteger } diff --git a/core/node/bitswap.go b/core/node/bitswap.go index 4bcc9706604..2408fe3715e 100644 --- a/core/node/bitswap.go +++ b/core/node/bitswap.go @@ -28,6 +28,7 @@ const ( DefaultEngineTaskWorkerCount = 8 DefaultMaxOutstandingBytesPerPeer = 1 << 20 DefaultProviderSearchDelay = 1000 * time.Millisecond + DefaultMaxProviders = 10 // matching BitswapClientDefaultMaxProviders from https://github.com/ipfs/boxo/blob/v0.29.1/bitswap/internal/defaults/defaults.go#L15 DefaultWantHaveReplaceSize = 1024 ) @@ -79,11 +80,13 @@ func Bitswap(provide bool) interface{} { var provider routing.ContentDiscovery if provide { - // We need to hardcode the default because it is an - // internal setting in boxo. + var maxProviders int = DefaultMaxProviders + if in.Cfg.Internal.Bitswap != nil { + maxProviders = int(in.Cfg.Internal.Bitswap.ProviderSearchMaxResults.WithDefault(DefaultMaxProviders)) + } pqm, err := rpqm.New(bitswapNetwork, in.Rt, - rpqm.WithMaxProviders(10), + rpqm.WithMaxProviders(maxProviders), rpqm.WithIgnoreProviders(in.Cfg.Routing.IgnoreProviders...), ) if err != nil { diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index 0d55c1aa6c6..e9daf0d510a 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -11,7 +11,7 @@ This release was brought to you by the [Shipyard](http://ipshipyard.com/) team. - [Overview](#overview) - [πŸ”¦ Highlights](#-highlights) - [Dedicated `Reprovider.Strategy` for MFS](#dedicated-reproviderstrategy-for-mfs) - - [`Routing.IgnoreProviders`](#routingignoreproviders) + - [Additional new configuration options](#additional-new-configuration-options) - [Grid view in WebUI](#grid-view-in-webui) - [πŸ“¦οΈ Important dependency updates](#-important-dependency-updates) - [πŸ“ Changelog](#-changelog) @@ -31,12 +31,10 @@ Users relying on the `pinned` strategy can switch to `pinned+mfs` and use MFS al See [`Reprovider.Strategy`](https://github.com/ipfs/kubo/blob/master/docs/config.md#reproviderstrategy) for more details. -#### `Routing.IgnoreProviders` +#### Additional new configuration options -This new option allows ignoring specific peer IDs when returned by the content -routing system as providers of content. See the -[documentation](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingignoreproviders) -for for information. +- [`Internal.Bitswap.ProviderSearchMaxResults`](https://github.com/ipfs/kubo/blob/master/docs/config.md##internalbitswapprovidersearchmaxresults) for adjusting the maximum number of providers bitswap client should aim at before it stops searching for new ones. +- [`Routing.IgnoreProviders`](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingignoreproviders) allows ignoring specific peer IDs when returned by the content routing system as providers of content. #### Grid view in WebUI diff --git a/docs/config.md b/docs/config.md index 8ff11a408d4..367fffb83c7 100644 --- a/docs/config.md +++ b/docs/config.md @@ -79,7 +79,8 @@ config file at runtime. - [`Internal.Bitswap.EngineBlockstoreWorkerCount`](#internalbitswapengineblockstoreworkercount) - [`Internal.Bitswap.EngineTaskWorkerCount`](#internalbitswapenginetaskworkercount) - [`Internal.Bitswap.MaxOutstandingBytesPerPeer`](#internalbitswapmaxoutstandingbytesperpeer) - - [`Internal.Bitswap.ProviderSearchDelay`](#internalbitswapprovidersearchdelay) + - [`Internal.Bitswap.ProviderSearchDelay`](#internalbitswapprovidersearchdelay) + - [`Internal.Bitswap.ProviderSearchMaxResults`](#internalbitswapprovidersearchmaxresults) - [`Internal.UnixFSShardingSizeThreshold`](#internalunixfsshardingsizethreshold) - [`Ipns`](#ipns) - [`Ipns.RepublishPeriod`](#ipnsrepublishperiod) @@ -119,7 +120,7 @@ config file at runtime. - [`Routing.Type`](#routingtype) - [`Routing.AcceleratedDHTClient`](#routingaccelerateddhtclient) - [`Routing.LoopbackAddressesOnLanDHT`](#routingloopbackaddressesonlandht) - - [`Routing.IgnoreProviders`](#routingignoreproviders) + - [`Routing.IgnoreProviders`](#routingignoreproviders) - [`Routing.Routers`](#routingrouters) - [`Routing.Routers: Type`](#routingrouters-type) - [`Routing.Routers: Parameters`](#routingrouters-parameters) @@ -1181,7 +1182,7 @@ deteriorate the quality provided to less aggressively-wanting peers. Type: `optionalInteger` (byte count, `null` means default which is 1MB) -### `Internal.Bitswap.ProviderSearchDelay` +#### `Internal.Bitswap.ProviderSearchDelay` This parameter determines how long to wait before looking for providers outside of bitswap. Other routing systems like the Amino DHT are able to provide results in less than a second, so lowering @@ -1189,6 +1190,13 @@ this number will allow faster peers lookups in some cases. Type: `optionalDuration` (`null` means default which is 1s) +#### `Internal.Bitswap.ProviderSearchMaxResults` + +Maximum number of providers bitswap client should aim at before it stops searching for new ones. +Setting to 0 means unlimited. + +Type: `optionalInteger` (`null` means default which is 10) + ### `Internal.UnixFSShardingSizeThreshold` The sharding threshold used internally to decide whether a UnixFS directory should be sharded or not. From 6b55e649186b27c3b17b680b013dfad3c9d6d601 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 15 Apr 2025 22:56:38 +0200 Subject: [PATCH 20/42] feat(config): `ipfs add` and `Import` options for controling UnixFS DAG Width (#10774) Co-authored-by: Marcin Rataj --- config/import.go | 30 +- config/internal.go | 2 +- config/profile.go | 28 +- core/commands/add.go | 81 +++-- core/coreapi/unixfs.go | 16 + core/coreiface/options/unixfs.go | 59 +++- core/coreunix/add.go | 115 ++++--- core/node/groups.go | 29 +- docs/changelogs/v0.35.md | 39 +++ docs/config.md | 116 ++++++- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +- fuse/readonly/ipfs_test.go | 12 +- go.mod | 2 +- go.sum | 4 +- test/cli/add_test.go | 337 ++++++++++++++++++++- test/cli/harness/ipfs.go | 23 ++ test/cli/harness/pbinspect.go | 54 ++++ test/cli/testutils/random_deterministic.go | 46 +++ test/cli/testutils/random_files.go | 27 +- test/dependencies/go.mod | 6 +- test/dependencies/go.sum | 12 +- test/sharness/t0032-mount-sharded.sh | 2 +- test/sharness/t0250-files-api.sh | 4 +- test/sharness/t0260-sharding.sh | 4 +- 25 files changed, 914 insertions(+), 140 deletions(-) create mode 100644 test/cli/harness/pbinspect.go create mode 100644 test/cli/testutils/random_deterministic.go diff --git a/config/import.go b/config/import.go index 6ea4d060fc2..21bf232c1c0 100644 --- a/config/import.go +++ b/config/import.go @@ -1,11 +1,18 @@ package config +import ( + "github.com/ipfs/boxo/ipld/unixfs/importer/helpers" + "github.com/ipfs/boxo/ipld/unixfs/io" +) + const ( DefaultCidVersion = 0 DefaultUnixFSRawLeaves = false DefaultUnixFSChunker = "size-262144" DefaultHashFunction = "sha2-256" + DefaultUnixFSHAMTDirectorySizeThreshold = "256KiB" // https://github.com/ipfs/boxo/blob/6c5a07602aed248acc86598f30ab61923a54a83e/ipld/unixfs/io/directory.go#L26 + // DefaultBatchMaxNodes controls the maximum number of nodes in a // write-batch. The total size of the batch is limited by // BatchMaxnodes and BatchMaxSize. @@ -14,15 +21,26 @@ const ( // write-batch. The total size of the batch is limited by // BatchMaxnodes and BatchMaxSize. DefaultBatchMaxSize = 100 << 20 // 20MiB + +) + +var ( + DefaultUnixFSFileMaxLinks = int64(helpers.DefaultLinksPerBlock) + DefaultUnixFSDirectoryMaxLinks = int64(0) + DefaultUnixFSHAMTDirectoryMaxFanout = int64(io.DefaultShardWidth) ) // 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 - BatchMaxNodes OptionalInteger - BatchMaxSize OptionalInteger + CidVersion OptionalInteger + UnixFSRawLeaves Flag + UnixFSChunker OptionalString + HashFunction OptionalString + UnixFSFileMaxLinks OptionalInteger + UnixFSDirectoryMaxLinks OptionalInteger + UnixFSHAMTDirectoryMaxFanout OptionalInteger + UnixFSHAMTDirectorySizeThreshold OptionalString + BatchMaxNodes OptionalInteger + BatchMaxSize OptionalInteger } diff --git a/config/internal.go b/config/internal.go index fe7e8432085..f8300f540b9 100644 --- a/config/internal.go +++ b/config/internal.go @@ -3,7 +3,7 @@ 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"` + UnixFSShardingSizeThreshold *OptionalString `json:",omitempty"` // moved to Import.UnixFSHAMTDirectorySizeThreshold Libp2pForceReachability *OptionalString `json:",omitempty"` BackupBootstrapInterval *OptionalDuration `json:",omitempty"` } diff --git a/config/profile.go b/config/profile.go index 69aaf66dcb6..a26d74f99a5 100644 --- a/config/profile.go +++ b/config/profile.go @@ -266,24 +266,44 @@ fetching may be degraded. }, }, "legacy-cid-v0": { - Description: `Makes UnixFS import produce legacy CIDv0 with no raw leaves, sha2-256 and 256 KiB chunks.`, - + Description: `Makes UnixFS import produce legacy CIDv0 with no raw leaves, sha2-256 and 256 KiB chunks. This is likely the least optimal preset, use only if legacy behavior is required.`, 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") + c.Import.UnixFSFileMaxLinks = *NewOptionalInteger(174) + c.Import.UnixFSDirectoryMaxLinks = *NewOptionalInteger(0) + c.Import.UnixFSHAMTDirectoryMaxFanout = *NewOptionalInteger(256) + c.Import.UnixFSHAMTDirectorySizeThreshold = *NewOptionalString("256KiB") return nil }, }, "test-cid-v1": { - Description: `Makes UnixFS import produce modern CIDv1 with raw leaves, sha2-256 and 1 MiB chunks.`, - + Description: `Makes UnixFS import produce CIDv1 with raw leaves, sha2-256 and 1 MiB chunks (max 174 links per file, 256 per HAMT node, switch dir to HAMT above 256KiB).`, 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") + c.Import.UnixFSFileMaxLinks = *NewOptionalInteger(174) + c.Import.UnixFSDirectoryMaxLinks = *NewOptionalInteger(0) + c.Import.UnixFSHAMTDirectoryMaxFanout = *NewOptionalInteger(256) + c.Import.UnixFSHAMTDirectorySizeThreshold = *NewOptionalString("256KiB") + return nil + }, + }, + "test-cid-v1-wide": { + Description: `Makes UnixFS import produce CIDv1 with raw leaves, sha2-256 and 1MiB chunks and wider file DAGs (max 1024 links per every node type, switch dir to HAMT above 1MiB).`, + Transform: func(c *Config) error { + c.Import.CidVersion = *NewOptionalInteger(1) + c.Import.UnixFSRawLeaves = True + c.Import.UnixFSChunker = *NewOptionalString("size-1048576") // 1MiB + c.Import.HashFunction = *NewOptionalString("sha2-256") + c.Import.UnixFSFileMaxLinks = *NewOptionalInteger(1024) + c.Import.UnixFSDirectoryMaxLinks = *NewOptionalInteger(0) // no limit here, use size-based Import.UnixFSHAMTDirectorySizeThreshold instead + c.Import.UnixFSHAMTDirectoryMaxFanout = *NewOptionalInteger(1024) + c.Import.UnixFSHAMTDirectorySizeThreshold = *NewOptionalString("1MiB") // 1MiB return nil }, }, diff --git a/core/commands/add.go b/core/commands/add.go index a1642f127a3..f800e4f42d0 100644 --- a/core/commands/add.go +++ b/core/commands/add.go @@ -37,23 +37,26 @@ type AddEvent struct { } const ( - quietOptionName = "quiet" - quieterOptionName = "quieter" - silentOptionName = "silent" - progressOptionName = "progress" - trickleOptionName = "trickle" - wrapOptionName = "wrap-with-directory" - onlyHashOptionName = "only-hash" - chunkerOptionName = "chunker" - pinOptionName = "pin" - rawLeavesOptionName = "raw-leaves" - noCopyOptionName = "nocopy" - fstoreCacheOptionName = "fscache" - cidVersionOptionName = "cid-version" - hashOptionName = "hash" - inlineOptionName = "inline" - inlineLimitOptionName = "inline-limit" - toFilesOptionName = "to-files" + quietOptionName = "quiet" + quieterOptionName = "quieter" + silentOptionName = "silent" + progressOptionName = "progress" + trickleOptionName = "trickle" + wrapOptionName = "wrap-with-directory" + onlyHashOptionName = "only-hash" + chunkerOptionName = "chunker" + pinOptionName = "pin" + rawLeavesOptionName = "raw-leaves" + maxFileLinksOptionName = "max-file-links" + maxDirectoryLinksOptionName = "max-directory-links" + maxHAMTFanoutOptionName = "max-hamt-fanout" + noCopyOptionName = "nocopy" + fstoreCacheOptionName = "fscache" + cidVersionOptionName = "cid-version" + hashOptionName = "hash" + inlineOptionName = "inline" + inlineLimitOptionName = "inline-limit" + toFilesOptionName = "to-files" preserveModeOptionName = "preserve-mode" preserveMtimeOptionName = "preserve-mtime" @@ -143,6 +146,9 @@ new flags may be added in the future. It is not guaranteed for the implicit defaults of 'ipfs add' to remain the same in future Kubo releases, or for other IPFS software to use the same import parameters as Kubo. +Use Import.* configuration options to override global implicit defaults: +https://github.com/ipfs/kubo/blob/master/docs/config.md#import + If you need to back up or transport content-addressed data using a non-IPFS medium, CID can be preserved with CAR files. See 'dag export' and 'dag import' for more information. @@ -166,12 +172,15 @@ 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"), - cmds.BoolOption(rawLeavesOptionName, "Use raw blocks for leaf nodes."), + cmds.StringOption(chunkerOptionName, "s", "Chunking algorithm, size-[bytes], rabin-[min]-[avg]-[max] or buzhash. Default: Import.UnixFSChunker"), + cmds.BoolOption(rawLeavesOptionName, "Use raw blocks for leaf nodes. Default: Import.UnixFSRawLeaves"), + cmds.IntOption(maxFileLinksOptionName, "Limit the maximum number of links in UnixFS file nodes to this value. (experimental) Default: Import.UnixFSFileMaxLinks"), + cmds.IntOption(maxDirectoryLinksOptionName, "Limit the maximum number of links in UnixFS basic directory nodes to this value. Default: Import.UnixFSDirectoryMaxLinks. WARNING: experimental, Import.UnixFSHAMTThreshold is a safer alternative."), + cmds.IntOption(maxHAMTFanoutOptionName, "Limit the maximum number of links of a UnixFS HAMT directory node to this (power of 2, multiple of 8). Default: Import.UnixFSHAMTDirectoryMaxFanout WARNING: experimental, see Import.UnixFSHAMTDirectorySizeThreshold as well."), 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)"), + 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. Default: Import.CidVersion"), + cmds.StringOption(hashOptionName, "Hash function to use. Implies CIDv1 if not sha2-256. Default: Import.HashFunction"), 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), @@ -222,6 +231,9 @@ See 'dag export' and 'dag import' for more information. chunker, _ := req.Options[chunkerOptionName].(string) dopin, _ := req.Options[pinOptionName].(bool) rawblks, rbset := req.Options[rawLeavesOptionName].(bool) + maxFileLinks, maxFileLinksSet := req.Options[maxFileLinksOptionName].(int) + maxDirectoryLinks, maxDirectoryLinksSet := req.Options[maxDirectoryLinksOptionName].(int) + maxHAMTFanout, maxHAMTFanoutSet := req.Options[maxHAMTFanoutOptionName].(int) nocopy, _ := req.Options[noCopyOptionName].(bool) fscache, _ := req.Options[fstoreCacheOptionName].(bool) cidVer, cidVerSet := req.Options[cidVersionOptionName].(int) @@ -253,6 +265,21 @@ See 'dag export' and 'dag import' for more information. rawblks = cfg.Import.UnixFSRawLeaves.WithDefault(config.DefaultUnixFSRawLeaves) } + if !maxFileLinksSet && !cfg.Import.UnixFSFileMaxLinks.IsDefault() { + maxFileLinksSet = true + maxFileLinks = int(cfg.Import.UnixFSFileMaxLinks.WithDefault(config.DefaultUnixFSFileMaxLinks)) + } + + if !maxDirectoryLinksSet && !cfg.Import.UnixFSDirectoryMaxLinks.IsDefault() { + maxDirectoryLinksSet = true + maxDirectoryLinks = int(cfg.Import.UnixFSDirectoryMaxLinks.WithDefault(config.DefaultUnixFSDirectoryMaxLinks)) + } + + if !maxHAMTFanoutSet && !cfg.Import.UnixFSHAMTDirectoryMaxFanout.IsDefault() { + maxHAMTFanoutSet = true + maxHAMTFanout = int(cfg.Import.UnixFSHAMTDirectoryMaxFanout.WithDefault(config.DefaultUnixFSHAMTDirectoryMaxFanout)) + } + // 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 { @@ -329,6 +356,18 @@ See 'dag export' and 'dag import' for more information. opts = append(opts, options.Unixfs.RawLeaves(rawblks)) } + if maxFileLinksSet { + opts = append(opts, options.Unixfs.MaxFileLinks(maxFileLinks)) + } + + if maxDirectoryLinksSet { + opts = append(opts, options.Unixfs.MaxDirectoryLinks(maxDirectoryLinks)) + } + + if maxHAMTFanoutSet { + opts = append(opts, options.Unixfs.MaxHAMTFanout(maxHAMTFanout)) + } + if trickle { opts = append(opts, options.Unixfs.Layout(options.TrickleLayout)) } diff --git a/core/coreapi/unixfs.go b/core/coreapi/unixfs.go index 3a74d3046c9..eece797a5fa 100644 --- a/core/coreapi/unixfs.go +++ b/core/coreapi/unixfs.go @@ -50,6 +50,12 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options attribute.Int("inlinelimit", settings.InlineLimit), attribute.Bool("rawleaves", settings.RawLeaves), attribute.Bool("rawleavesset", settings.RawLeavesSet), + attribute.Int("maxfilelinks", settings.MaxFileLinks), + attribute.Bool("maxfilelinksset", settings.MaxFileLinksSet), + attribute.Int("maxdirectorylinks", settings.MaxDirectoryLinks), + attribute.Bool("maxdirectorylinksset", settings.MaxDirectoryLinksSet), + attribute.Int("maxhamtfanout", settings.MaxHAMTFanout), + attribute.Bool("maxhamtfanoutset", settings.MaxHAMTFanoutSet), attribute.Int("layout", int(settings.Layout)), attribute.Bool("pin", settings.Pin), attribute.Bool("onlyhash", settings.OnlyHash), @@ -132,6 +138,16 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options fileAdder.Pin = settings.Pin && !settings.OnlyHash fileAdder.Silent = settings.Silent fileAdder.RawLeaves = settings.RawLeaves + if settings.MaxFileLinksSet { + fileAdder.MaxLinks = settings.MaxFileLinks + } + if settings.MaxDirectoryLinksSet { + fileAdder.MaxDirectoryLinks = settings.MaxDirectoryLinks + } + + if settings.MaxHAMTFanoutSet { + fileAdder.MaxHAMTFanout = settings.MaxHAMTFanout + } fileAdder.NoCopy = settings.NoCopy fileAdder.CidBuilder = prefix fileAdder.PreserveMode = settings.PreserveMode diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index c837ec1b2db..20f18d1e04c 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -7,6 +7,8 @@ import ( "time" dag "github.com/ipfs/boxo/ipld/merkledag" + "github.com/ipfs/boxo/ipld/unixfs/importer/helpers" + "github.com/ipfs/boxo/ipld/unixfs/io" cid "github.com/ipfs/go-cid" mh "github.com/multiformats/go-multihash" ) @@ -22,10 +24,16 @@ type UnixfsAddSettings struct { CidVersion int MhType uint64 - Inline bool - InlineLimit int - RawLeaves bool - RawLeavesSet bool + Inline bool + InlineLimit int + RawLeaves bool + RawLeavesSet bool + MaxFileLinks int + MaxFileLinksSet bool + MaxDirectoryLinks int + MaxDirectoryLinksSet bool + MaxHAMTFanout int + MaxHAMTFanoutSet bool Chunker string Layout Layout @@ -60,10 +68,16 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, CidVersion: -1, MhType: mh.SHA2_256, - Inline: false, - InlineLimit: 32, - RawLeaves: false, - RawLeavesSet: false, + Inline: false, + InlineLimit: 32, + RawLeaves: false, + RawLeavesSet: false, + MaxFileLinks: helpers.DefaultLinksPerBlock, + MaxFileLinksSet: false, + MaxDirectoryLinks: 0, + MaxDirectoryLinksSet: false, + MaxHAMTFanout: io.DefaultShardWidth, + MaxHAMTFanoutSet: false, Chunker: "size-262144", Layout: BalancedLayout, @@ -190,6 +204,35 @@ func (unixfsOpts) RawLeaves(enable bool) UnixfsAddOption { } } +// MaxFileLinks specifies the maximum number of children for UnixFS file +// nodes. +func (unixfsOpts) MaxFileLinks(n int) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.MaxFileLinks = n + settings.MaxFileLinksSet = true + return nil + } +} + +// MaxDirectoryLinks specifies the maximum number of children for UnixFS basic +// directory nodes. +func (unixfsOpts) MaxDirectoryLinks(n int) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.MaxDirectoryLinks = n + settings.MaxDirectoryLinksSet = true + return nil + } +} + +// MaxHAMTFanout specifies the maximum width of the HAMT directory shards. +func (unixfsOpts) MaxHAMTFanout(n int) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.MaxHAMTFanout = n + settings.MaxHAMTFanoutSet = true + return nil + } +} + // Inline tells the adder to inline small blocks into CIDs func (unixfsOpts) Inline(enable bool) UnixfsAddOption { return func(settings *UnixfsAddSettings) error { diff --git a/core/coreunix/add.go b/core/coreunix/add.go index 5f7cbb61065..d9dc555d276 100644 --- a/core/coreunix/add.go +++ b/core/coreunix/add.go @@ -19,6 +19,7 @@ import ( "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" + uio "github.com/ipfs/boxo/ipld/unixfs/io" "github.com/ipfs/boxo/mfs" "github.com/ipfs/boxo/path" pin "github.com/ipfs/boxo/pinning/pinner" @@ -51,38 +52,43 @@ func NewAdder(ctx context.Context, p pin.Pinner, bs bstore.GCLocker, ds ipld.DAG bufferedDS := ipld.NewBufferedDAG(ctx, ds) return &Adder{ - ctx: ctx, - pinning: p, - gcLocker: bs, - dagService: ds, - bufferedDS: bufferedDS, - Progress: false, - Pin: true, - Trickle: false, - Chunker: "", + ctx: ctx, + pinning: p, + gcLocker: bs, + dagService: ds, + bufferedDS: bufferedDS, + Progress: false, + Pin: true, + Trickle: false, + MaxLinks: ihelper.DefaultLinksPerBlock, + MaxHAMTFanout: uio.DefaultShardWidth, + Chunker: "", }, nil } // Adder holds the switches passed to the `add` command. type Adder struct { - ctx context.Context - pinning pin.Pinner - gcLocker bstore.GCLocker - dagService ipld.DAGService - bufferedDS *ipld.BufferedDAG - Out chan<- interface{} - Progress bool - Pin bool - Trickle bool - RawLeaves bool - Silent bool - NoCopy bool - Chunker string - mroot *mfs.Root - unlocker bstore.Unlocker - tempRoot cid.Cid - CidBuilder cid.Builder - liveNodes uint64 + ctx context.Context + pinning pin.Pinner + gcLocker bstore.GCLocker + dagService ipld.DAGService + bufferedDS *ipld.BufferedDAG + Out chan<- interface{} + Progress bool + Pin bool + Trickle bool + RawLeaves bool + MaxLinks int + MaxDirectoryLinks int + MaxHAMTFanout int + Silent bool + NoCopy bool + Chunker string + mroot *mfs.Root + unlocker bstore.Unlocker + tempRoot cid.Cid + CidBuilder cid.Builder + liveNodes uint64 PreserveMode bool PreserveMtime bool @@ -94,12 +100,13 @@ func (adder *Adder) mfsRoot() (*mfs.Root, error) { if adder.mroot != nil { return adder.mroot, nil } - rnode := unixfs.EmptyDirNode() - err := rnode.SetCidBuilder(adder.CidBuilder) - if err != nil { - return nil, err - } - mr, err := mfs.NewRoot(adder.ctx, adder.dagService, rnode, nil) + + // Note, this adds it to DAGService already. + mr, err := mfs.NewEmptyRoot(adder.ctx, adder.dagService, nil, mfs.MkdirOpts{ + CidBuilder: adder.CidBuilder, + MaxLinks: adder.MaxDirectoryLinks, + MaxHAMTFanout: adder.MaxHAMTFanout, + }) if err != nil { return nil, err } @@ -119,10 +126,15 @@ func (adder *Adder) add(reader io.Reader) (ipld.Node, error) { return nil, err } + maxLinks := ihelper.DefaultLinksPerBlock + if adder.MaxLinks > 0 { + maxLinks = adder.MaxLinks + } + params := ihelper.DagBuilderParams{ Dagserv: adder.bufferedDS, RawLeaves: adder.RawLeaves, - Maxlinks: ihelper.DefaultLinksPerBlock, + Maxlinks: maxLinks, NoCopy: adder.NoCopy, CidBuilder: adder.CidBuilder, FileMode: adder.FileMode, @@ -252,12 +264,15 @@ func (adder *Adder) addNode(node ipld.Node, path string) error { if err != nil { return err } + dir := gopath.Dir(path) if dir != "." { opts := mfs.MkdirOpts{ - Mkparents: true, - Flush: false, - CidBuilder: adder.CidBuilder, + Mkparents: true, + Flush: false, + CidBuilder: adder.CidBuilder, + MaxLinks: adder.MaxDirectoryLinks, + MaxHAMTFanout: adder.MaxHAMTFanout, } if err := mfs.Mkdir(mr, dir, opts); err != nil { return err @@ -460,12 +475,14 @@ func (adder *Adder) addDir(ctx context.Context, path string, dir files.Directory // 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) + mr, err := mfs.NewEmptyRoot(ctx, adder.dagService, nil, + mfs.MkdirOpts{ + CidBuilder: adder.CidBuilder, + MaxLinks: adder.MaxDirectoryLinks, + MaxHAMTFanout: adder.MaxHAMTFanout, + ModTime: adder.FileMtime, + Mode: adder.FileMode, + }) if err != nil { return err } @@ -478,11 +495,13 @@ func (adder *Adder) addDir(ctx context.Context, path string, dir files.Directory return err } err = mfs.Mkdir(mr, path, mfs.MkdirOpts{ - Mkparents: true, - Flush: false, - CidBuilder: adder.CidBuilder, - Mode: adder.FileMode, - ModTime: adder.FileMtime, + Mkparents: true, + Flush: false, + CidBuilder: adder.CidBuilder, + Mode: adder.FileMode, + ModTime: adder.FileMtime, + MaxLinks: adder.MaxDirectoryLinks, + MaxHAMTFanout: adder.MaxHAMTFanout, }) if err != nil { return err diff --git a/core/node/groups.go b/core/node/groups.go index e8f9739c36e..4a471f17038 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -408,20 +408,29 @@ func IPFS(ctx context.Context, bcfg *BuildCfg) fx.Option { return fx.Error(err) } + // Migrate users of deprecated Experimental.ShardingEnabled flag + if cfg.Experimental.ShardingEnabled { + logger.Fatal("The `Experimental.ShardingEnabled` field is no longer used, please remove it from the config. Use Import.UnixFSHAMTDirectorySizeThreshold instead.") + } + if !cfg.Internal.UnixFSShardingSizeThreshold.IsDefault() { + msg := "The `Internal.UnixFSShardingSizeThreshold` field was renamed to `Import.UnixFSHAMTDirectorySizeThreshold`. Please update your config.\n" + if !cfg.Import.UnixFSHAMTDirectorySizeThreshold.IsDefault() { + logger.Fatal(msg) // conflicting values, hard fail + } + logger.Error(msg) + cfg.Import.UnixFSHAMTDirectorySizeThreshold = *cfg.Internal.UnixFSShardingSizeThreshold + } + // Auto-sharding settings - shardSizeString := cfg.Internal.UnixFSShardingSizeThreshold.WithDefault("256kiB") - shardSizeInt, err := humanize.ParseBytes(shardSizeString) + shardingThresholdString := cfg.Import.UnixFSHAMTDirectorySizeThreshold.WithDefault(config.DefaultUnixFSHAMTDirectorySizeThreshold) + shardSingThresholdInt, err := humanize.ParseBytes(shardingThresholdString) if err != nil { return fx.Error(err) } - uio.HAMTShardingSize = int(shardSizeInt) - - // Migrate users of deprecated Experimental.ShardingEnabled flag - if cfg.Experimental.ShardingEnabled { - logger.Fatal("The `Experimental.ShardingEnabled` field is no longer used, please remove it from the config.\n" + - "go-ipfs now automatically shards when directory block is bigger than `" + shardSizeString + "`.\n" + - "If you need to restore the old behavior (sharding everything) set `Internal.UnixFSShardingSizeThreshold` to `1B`.\n") - } + shardMaxFanout := cfg.Import.UnixFSHAMTDirectoryMaxFanout.WithDefault(config.DefaultUnixFSHAMTDirectoryMaxFanout) + // TODO: avoid overriding this globally, see if we can extend Directory interface like Get/SetMaxLinks from https://github.com/ipfs/boxo/pull/906 + uio.HAMTShardingSize = int(shardSingThresholdInt) + uio.DefaultShardWidth = int(shardMaxFanout) return fx.Options( bcfgOpts, diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index e9daf0d510a..bc3a857f8b7 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -13,6 +13,10 @@ This release was brought to you by the [Shipyard](http://ipshipyard.com/) team. - [Dedicated `Reprovider.Strategy` for MFS](#dedicated-reproviderstrategy-for-mfs) - [Additional new configuration options](#additional-new-configuration-options) - [Grid view in WebUI](#grid-view-in-webui) + - [Enhanced DAG-Shaping Controls for `ipfs add`](#enhanced-dag-shaping-controls-for-ipfs-add) + - [New `ipfs add` Options](#new-ipfs-add-options) + - [Persistent `Import.*` Configuration](#persistent-import-configuration) + - [Updated Configuration Profiles](#updated-configuration-profiles) - [πŸ“¦οΈ Important dependency updates](#-important-dependency-updates) - [πŸ“ Changelog](#-changelog) - [πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors](#-contributors) @@ -42,6 +46,41 @@ The WebUI, accessible at http://127.0.0.1:5001/webui/, now includes support for > ![image](https://github.com/user-attachments/assets/80dcf0d0-8103-426f-ae91-416fb25d32b6) +#### Enhanced DAG-Shaping Controls for `ipfs add` + +This release advances CIDv1 support by introducing fine-grained control over UnixFS DAG shaping during data ingestion with the `ipfs add` command. + +Wider DAG trees (more links per node, higher fanout, larger thresholds) are beneficial for large files and directories with many files, reducing tree depth and lookup latency in high-latency networks, but they increase node size, straining memory and CPU on resource-constrained devices. Narrower trees (lower link count, lower fanout, smaller thresholds) are preferable for smaller directories, frequent updates, or low-power clients, minimizing overhead and ensuring compatibility, though they may increase traversal steps for very large datasets. + +Kubo now allows users to act on these tradeoffs and customize the width of the DAG created by `ipfs add` command. + +##### New `ipfs add` Options + +Three new options allow you to override default settings for specific import operations: + +- `--max-file-links`: Sets the maximum number of child links for a single file chunk. +- `--max-directory-links`: Defines the maximum number of child entries in a "basic" (single-chunk) directory. + - Note: Directories exceeding this limit or the `Import.UnixFSHAMTDirectorySizeThreshold` are converted to HAMT-based (sharded across multiple blocks) structures. +- `--max-hamt-fanout`: Specifies the maximum number of child nodes for HAMT internal structures. + +##### Persistent `Import.*` Configuration + +You can set default values for these options using the following configuration settings: +- [`Import.UnixFSFileMaxLinks`](https://github.com/ipfs/kubo/blob/master/docs/config.md#importunixfsfilemaxlinks) +- [`Import.UnixFSDirectoryMaxLinks`](https://github.com/ipfs/kubo/blob/master/docs/config.md#importunixfsdirectorymaxlinks) +- [`Import.UnixFSHAMTDirectoryMaxFanout`](https://github.com/ipfs/kubo/blob/master/docs/config.md#importunixfshamtdirectorymaxfanout) +- [`Import.UnixFSHAMTDirectorySizeThreshold`](https://github.com/ipfs/kubo/blob/master/docs/config.md#importunixfshamtdirectorysizethreshold) + +##### Updated Configuration Profiles + +The release updated configuration [profiles](https://github.com/ipfs/kubo/blob/master/docs/config.md#profiles) to incorporate these new `Import.*` settings: +- Updated Profile: `test-cid-v1` now includes current defaults as explicit `Import.UnixFSFileMaxLinks=174`, `Import.UnixFSDirectoryMaxLinks=0`, `Import.UnixFSHAMTDirectoryMaxFanout=256` and `Import.UnixFSHAMTDirectorySizeThreshold=256KiB` +- New Profile: `test-cid-v1-wide` adopts experimental directory DAG-shaping defaults, increasing the maximum file DAG width from 174 to 1024, HAMT fanout from 256 to 1024, and raising the HAMT directory sharding threshold from 256KiB to 1MiB, aligning with 1MiB file chunks. + - Feedback: Try it out and share your thoughts at [discuss.ipfs.tech/t/should-we-profile-cids](https://discuss.ipfs.tech/t/should-we-profile-cids/18507) or [ipfs/specs#499](https://github.com/ipfs/specs/pull/499). + +> [!TIP] +> Apply one of CIDv1 test [profiles](https://github.com/ipfs/kubo/blob/master/docs/config.md#profiles) with `ipfs config profile apply test-cid-v1[-wide]`. + #### πŸ“¦οΈ Important dependency updates - update `ipfs-webui` to [v4.7.0](https://github.com/ipfs/ipfs-webui/releases/tag/v4.7.0) diff --git a/docs/config.md b/docs/config.md index 367fffb83c7..1ec5677db28 100644 --- a/docs/config.md +++ b/docs/config.md @@ -185,6 +185,10 @@ config file at runtime. - [`Import.HashFunction`](#importhashfunction) - [`Import.BatchMaxNodes`](#importbatchmaxnodes) - [`Import.BatchMaxSize`](#importbatchmaxsize) + - [`Import.UnixFSFileMaxLinks`](#importunixfsfilemaxlinks) + - [`Import.UnixFSDirectoryMaxLinks`](#importunixfsdirectorymaxlinks) + - [`Import.UnixFSHAMTDirectoryMaxFanout`](#importunixfshamtdirectorymaxfanout) + - [`Import.UnixFSHAMTDirectorySizeThreshold`](#importunixfshamtdirectorysizethreshold) - [`Version`](#version) - [`Version.AgentSuffix`](#versionagentsuffix) - [`Version.SwarmCheckEnabled`](#versionswarmcheckenabled) @@ -1199,15 +1203,7 @@ Type: `optionalInteger` (`null` means default which is 10) ### `Internal.UnixFSShardingSizeThreshold` -The sharding threshold used internally to decide whether a UnixFS directory should be sharded or not. -This value is not strictly related to the size of the UnixFS directory block and any increases in -the threshold should come with being careful that block sizes stay under 2MiB in order for them to be -reliably transferable through the networking stack (IPFS peers on the public swarm tend to ignore requests for blocks bigger than 2MiB). - -Decreasing this value to 1B is functionally equivalent to the previous experimental sharding option to -shard all directories. - -Type: `optionalBytes` (`null` means default which is 256KiB) +**MOVED:** see [`Import.UnixFSHAMTDirectorySizeThreshold`](#importunixfshamtdirectorysizethreshold) ## `Ipns` @@ -2560,6 +2556,80 @@ Default: `20971520` (20MiB) Type: `optionalInteger` +### `Import.UnixFSFileMaxLinks` + +The maximum number of links that a node part of a UnixFS File can have +when building the DAG while importing. + +This setting controls both the fanout in files that are chunked into several +blocks and grouped as a Unixfs (dag-pb) DAG. + +Default: `174` + +Type: `optionalInteger` + +### `Import.UnixFSDirectoryMaxLinks` + +The maximum number of links that a node part of a UnixFS basic directory can +have when building the DAG while importing. + +This setting controls both the fanout for basic, non-HAMT folder nodes. It +sets a limit after which directories are converted to a HAMT-based structure. + +When unset (0), no limit exists for chilcren. Directories will be converted to +HAMTs based on their estimated size only. + +This setting will cause basic directories to be converted to HAMTs when they +exceed the maximum number of children. This happens transparently during the +add process. The fanout of HAMT nodes is controlled by `MaxHAMTFanout`. + +Commands affected: `ipfs add` + +Default: `0` (no limit, because [`Import.UnixFSHAMTDirectorySizeThreshold`](#importunixfshamtdirectorysizethreshold) triggers controls when to switch to HAMT sharding when a directory grows too big) + +Type: `optionalInteger` + +### `Import.UnixFSHAMTDirectoryMaxFanout` + +The maximum number of children that a node part of a Unixfs HAMT directory +(aka sharded directory) can have. + +HAMT directory have unlimited children and are used when basic directories +become too big or reach `MaxLinks`. A HAMT is an structure made of unixfs +nodes that store the list of elements in the folder. This option controls the +maximum number of children that the HAMT nodes can have. + +Needs to be a power of two (shard entry size) and multiple of 8 (bitfield size). + +Commands affected: `ipfs add`, `ipfs daemon` (globally overrides [`boxo/ipld/unixfs/io.DefaultShardWidth`](https://github.com/ipfs/boxo/blob/6c5a07602aed248acc86598f30ab61923a54a83e/ipld/unixfs/io/directory.go#L30C5-L30C22)) + +Default: `256` + +Type: `optionalInteger` + +### `Import.UnixFSHAMTDirectorySizeThreshold` + +The sharding threshold to decide whether a basic UnixFS directory +should be sharded (converted into HAMT Directory) or not. + +This value is not strictly related to the size of the UnixFS directory block +and any increases in the threshold should come with being careful that block +sizes stay under 2MiB in order for them to be reliably transferable through the +networking stack. At the time of writing this, IPFS peers on the public swarm +tend to ignore requests for blocks bigger than 2MiB. + +Uses implementation from `boxo/ipld/unixfs/io/directory`, where the size is not +the *exact* block size of the encoded directory but just the estimated size +based byte length of DAG-PB Links names and CIDs. + +Setting to `1B` is functionally equivalent to always using HAMT (useful in testing). + +Commands affected: `ipfs add`, `ipfs daemon` (globally overrides [`boxo/ipld/unixfs/io.HAMTShardingSize`](https://github.com/ipfs/boxo/blob/6c5a07602aed248acc86598f30ab61923a54a83e/ipld/unixfs/io/directory.go#L26)) + +Default: `256KiB` (may change, inspect `DefaultUnixFSHAMTDirectorySizeThreshold` to confirm) + +Type: `optionalBytes` + ## `Version` Options to configure agent version announced to the swarm, and leveraging @@ -2742,16 +2812,38 @@ Disables [Reprovider](#reprovider) system (and announcing to Amino DHT). Makes UnixFS import (`ipfs add`) produce legacy CIDv0 with no raw leaves, sha2-256 and 256 KiB chunks. +See for exact [`Import.*`](#import) settings. + > [!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. +Makes UnixFS import (`ipfs add`) produce modern CIDv1 with raw leaves, sha2-256 +and 1 MiB chunks (max 174 links per file, 256 per HAMT node, switch dir to HAMT +above 256KiB). + +See for exact [`Import.*`](#import) settings. + +> [!NOTE] +> [`Import.*`](#import) settings applied by this profile MAY change in future release. Provided for testing purposes. +> +> Follow [kubo#4143](https://github.com/ipfs/kubo/issues/4143) for more details, +> and provide feedback in [discuss.ipfs.tech/t/should-we-profile-cids](https://discuss.ipfs.tech/t/should-we-profile-cids/18507) or [ipfs/specs#499](https://github.com/ipfs/specs/pull/499). + +### `test-cid-v1-wide` profile + +Makes UnixFS import (`ipfs add`) produce modern CIDv1 with raw leaves, sha2-256 +and 1 MiB chunks and wider file DAGs (max 1024 links per every node type, +switch dir to HAMT above 1MiB). + +See for exact [`Import.*`](#import) settings. > [!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. +> [`Import.*`](#import) settings applied by this profile MAY change in future release. Provided for testing purposes. +> +> Follow [kubo#4143](https://github.com/ipfs/kubo/issues/4143) for more details, +> and provide feedback in [discuss.ipfs.tech/t/should-we-profile-cids](https://discuss.ipfs.tech/t/should-we-profile-cids/18507) or [ipfs/specs#499](https://github.com/ipfs/specs/pull/499). ## Types diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index bfaa528c9e7..7adc7c80a81 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.24 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.29.2-0.20250409154342-bbaf2e146dfb + github.com/ipfs/boxo v0.29.2-0.20250415191135-dc60fe747c37 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.41.1 github.com/multiformats/go-multiaddr v0.15.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index eb2997529af..5e2f686a0fb 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -298,8 +298,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 h1:OqNqsGZPX8zh3eFMO8Lf8EHRRnSGBMqcd github.com/ipfs-shipyard/nopfs/ipfs v0.25.0/go.mod h1:BxhUdtBgOXg1B+gAPEplkg/GpyTZY+kCMSfsJvvydqU= 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.29.2-0.20250409154342-bbaf2e146dfb h1:kA7c3CF6/d8tUwGJR/SwIfaRz7Xk7Fbyoh2ePZAFMlw= -github.com/ipfs/boxo v0.29.2-0.20250409154342-bbaf2e146dfb/go.mod h1:omQZmLS7LegSpBy3m4CrAB9/SO7Fq3pfv+5y1FOd+gI= +github.com/ipfs/boxo v0.29.2-0.20250415191135-dc60fe747c37 h1:q3a+2FIbWzZbx/yUqpuG4jLVSa6GvxtRfx9TU5GLiN0= +github.com/ipfs/boxo v0.29.2-0.20250415191135-dc60fe747c37/go.mod h1:omQZmLS7LegSpBy3m4CrAB9/SO7Fq3pfv+5y1FOd+gI= 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/fuse/readonly/ipfs_test.go b/fuse/readonly/ipfs_test.go index 6d667843cdf..e7dfbcb2abd 100644 --- a/fuse/readonly/ipfs_test.go +++ b/fuse/readonly/ipfs_test.go @@ -150,7 +150,10 @@ func TestIpfsStressRead(t *testing.T) { // Now make a bunch of dirs for i := 0; i < ndiriter; i++ { - db := uio.NewDirectory(nd.DAG) + db, err := uio.NewDirectory(nd.DAG) + if err != nil { + t.Fatal(err) + } for j := 0; j < 1+rand.Intn(10); j++ { name := fmt.Sprintf("child%d", j) @@ -245,8 +248,11 @@ func TestIpfsBasicDirRead(t *testing.T) { fi, data := randObj(t, nd, 10000) // Make a directory and put that file in it - db := uio.NewDirectory(nd.DAG) - err := db.AddChild(nd.Context(), "actual", fi) + db, err := uio.NewDirectory(nd.DAG) + if err != nil { + t.Fatal(err) + } + err = db.AddChild(nd.Context(), "actual", fi) if err != nil { t.Fatal(err) } diff --git a/go.mod b/go.mod index 8975eb21054..68e8c7a3f00 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.14 github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 - github.com/ipfs/boxo v0.29.2-0.20250409154342-bbaf2e146dfb + github.com/ipfs/boxo v0.29.2-0.20250415191135-dc60fe747c37 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.5.0 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index e926a459635..cf9c33444e2 100644 --- a/go.sum +++ b/go.sum @@ -362,8 +362,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 h1:OqNqsGZPX8zh3eFMO8Lf8EHRRnSGBMqcd github.com/ipfs-shipyard/nopfs/ipfs v0.25.0/go.mod h1:BxhUdtBgOXg1B+gAPEplkg/GpyTZY+kCMSfsJvvydqU= 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.29.2-0.20250409154342-bbaf2e146dfb h1:kA7c3CF6/d8tUwGJR/SwIfaRz7Xk7Fbyoh2ePZAFMlw= -github.com/ipfs/boxo v0.29.2-0.20250409154342-bbaf2e146dfb/go.mod h1:omQZmLS7LegSpBy3m4CrAB9/SO7Fq3pfv+5y1FOd+gI= +github.com/ipfs/boxo v0.29.2-0.20250415191135-dc60fe747c37 h1:q3a+2FIbWzZbx/yUqpuG4jLVSa6GvxtRfx9TU5GLiN0= +github.com/ipfs/boxo v0.29.2-0.20250415191135-dc60fe747c37/go.mod h1:omQZmLS7LegSpBy3m4CrAB9/SO7Fq3pfv+5y1FOd+gI= 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/add_test.go b/test/cli/add_test.go index ae652989ab5..775a6063baa 100644 --- a/test/cli/add_test.go +++ b/test/cli/add_test.go @@ -1,10 +1,17 @@ package cli import ( + "io" + "os" + "path/filepath" + "strings" "testing" + "github.com/dustin/go-humanize" "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" ) @@ -19,6 +26,11 @@ func TestAdd(t *testing.T) { shortStringCidV1Sha512 = "bafkrgqbqt3gerhas23vuzrapkdeqf4vu2dwxp3srdj6hvg6nhsug2tgyn6mj3u23yx7utftq3i2ckw2fwdh5qmhid5qf3t35yvkc5e5ottlw6" ) + const ( + cidV0Length = 34 // cidv0 sha2-256 + cidV1Length = 36 // cidv1 sha2-256 + ) + t.Run("produced cid version: implicit default (CIDv0)", func(t *testing.T) { t.Parallel() node := harness.NewT(t).NewNode().Init().StartDaemon() @@ -96,6 +108,33 @@ func TestAdd(t *testing.T) { require.Equal(t, shortStringCidV1NoRawLeaves, cidStr) }) + t.Run("produced unixfs max file links: command flag --max-file-links overrides configuration in Import.UnixFSFileMaxLinks", func(t *testing.T) { + t.Parallel() + + // + // UnixFSChunker=size-262144 (256KiB) + // Import.UnixFSFileMaxLinks=174 + node := harness.NewT(t).NewNode().Init("--profile=legacy-cid-v0") // legacy-cid-v0 for determinism across all params + node.UpdateConfig(func(cfg *config.Config) { + cfg.Import.UnixFSChunker = *config.NewOptionalString("size-262144") // 256 KiB chunks + cfg.Import.UnixFSFileMaxLinks = *config.NewOptionalInteger(174) // max 174 per level + }) + node.StartDaemon() + defer node.StopDaemon() + + // Add 174MiB file: + // 1024 * 256KiB should fit in single layer + seed := shortString + cidStr := node.IPFSAddDeterministic("262144KiB", seed, "--max-file-links", "1024") + root, err := node.InspectPBNode(cidStr) + assert.NoError(t, err) + + // Expect 1024 links due to cli parameter raising link limit from 174 to 1024 + require.Equal(t, 1024, len(root.Links)) + // expect same CID every time + require.Equal(t, "QmbBftNHWmjSWKLC49dMVrfnY8pjrJYntiAXirFJ7oJrNk", 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") @@ -106,13 +145,307 @@ func TestAdd(t *testing.T) { require.Equal(t, shortStringCidV0, cidStr) }) - t.Run("ipfs init --profile=test-cid-v1 produces modern CIDv1", func(t *testing.T) { + t.Run("ipfs init --profile=legacy-cid-v0 applies UnixFSChunker=size-262144 and UnixFSFileMaxLinks", func(t *testing.T) { + t.Parallel() + seed := "v0-seed" + profile := "--profile=legacy-cid-v0" + + t.Run("under UnixFSFileMaxLinks=174", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init(profile) + node.StartDaemon() + defer node.StopDaemon() + // Add 44544KiB file: + // 174 * 256KiB should fit in single DAG layer + cidStr := node.IPFSAddDeterministic("44544KiB", seed) + root, err := node.InspectPBNode(cidStr) + assert.NoError(t, err) + require.Equal(t, 174, len(root.Links)) + // expect same CID every time + require.Equal(t, "QmUbBALi174SnogsUzLpYbD4xPiBSFANF4iztWCsHbMKh2", cidStr) + }) + + t.Run("above UnixFSFileMaxLinks=174", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init(profile) + node.StartDaemon() + defer node.StopDaemon() + // add 256KiB (one more block), it should force rebalancing DAG and moving most to second layer + cidStr := node.IPFSAddDeterministic("44800KiB", seed) + root, err := node.InspectPBNode(cidStr) + assert.NoError(t, err) + require.Equal(t, 2, len(root.Links)) + // expect same CID every time + require.Equal(t, "QmepeWtdmS1hHXx1oZXsPUv6bMrfRRKfZcoPPU4eEfjnbf", cidStr) + }) + }) + + t.Run("ipfs init --profile=legacy-cid-v0 applies UnixFSHAMTDirectoryMaxFanout=256 and UnixFSHAMTDirectorySizeThreshold=256KiB", func(t *testing.T) { + t.Parallel() + seed := "hamt-legacy-cid-v0" + profile := "--profile=legacy-cid-v0" + + t.Run("under UnixFSHAMTDirectorySizeThreshold=256KiB", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init(profile) + node.StartDaemon() + defer node.StopDaemon() + + randDir, err := os.MkdirTemp(node.Dir, seed) + require.NoError(t, err) + + // Create directory with a lot of files that have filenames which together take close to UnixFSHAMTDirectorySizeThreshold in total + err = createDirectoryForHAMT(randDir, cidV0Length, "255KiB", seed) + require.NoError(t, err) + cidStr := node.IPFS("add", "-r", "-Q", randDir).Stdout.Trimmed() + + // Confirm the number of links is more than UnixFSHAMTDirectorySizeThreshold (indicating regular "basic" directory" + root, err := node.InspectPBNode(cidStr) + assert.NoError(t, err) + require.Equal(t, 903, len(root.Links)) + }) + + t.Run("above UnixFSHAMTDirectorySizeThreshold=256KiB", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init(profile) + node.StartDaemon() + defer node.StopDaemon() + + randDir, err := os.MkdirTemp(node.Dir, seed) + require.NoError(t, err) + + // Create directory with a lot of files that have filenames which together take close to UnixFSHAMTDirectorySizeThreshold in total + err = createDirectoryForHAMT(randDir, cidV0Length, "257KiB", seed) + require.NoError(t, err) + cidStr := node.IPFS("add", "-r", "-Q", randDir).Stdout.Trimmed() + + // Confirm this time, the number of links is less than UnixFSHAMTDirectorySizeThreshold + root, err := node.InspectPBNode(cidStr) + assert.NoError(t, err) + require.Equal(t, 252, len(root.Links)) + }) + }) + + t.Run("ipfs init --profile=test-cid-v1 produces CIDv1 with raw leaves", 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) + require.Equal(t, shortStringCidV1, cidStr) // raw leaf + }) + + t.Run("ipfs init --profile=test-cid-v1 applies UnixFSChunker=size-1048576", func(t *testing.T) { + t.Parallel() + seed := "v1-seed" + profile := "--profile=test-cid-v1" + + t.Run("under UnixFSFileMaxLinks=174", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init(profile) + node.StartDaemon() + defer node.StopDaemon() + // Add 174MiB file: + // 174 * 1MiB should fit in single layer + cidStr := node.IPFSAddDeterministic("174MiB", seed) + root, err := node.InspectPBNode(cidStr) + assert.NoError(t, err) + require.Equal(t, 174, len(root.Links)) + // expect same CID every time + require.Equal(t, "bafybeigwduxcf2aawppv3isnfeshnimkyplvw3hthxjhr2bdeje4tdaicu", cidStr) + }) + + t.Run("above UnixFSFileMaxLinks=174", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init(profile) + node.StartDaemon() + defer node.StopDaemon() + // add +1MiB (one more block), it should force rebalancing DAG and moving most to second layer + cidStr := node.IPFSAddDeterministic("175MiB", seed) + root, err := node.InspectPBNode(cidStr) + assert.NoError(t, err) + require.Equal(t, 2, len(root.Links)) + // expect same CID every time + require.Equal(t, "bafybeidhd7lo2n2v7lta5yamob3xwhbxcczmmtmhquwhjesi35jntf7mpu", cidStr) + }) + }) + + t.Run("ipfs init --profile=test-cid-v1 applies UnixFSHAMTDirectoryMaxFanout=256 and UnixFSHAMTDirectorySizeThreshold=256KiB", func(t *testing.T) { + t.Parallel() + seed := "hamt-cid-v1" + profile := "--profile=test-cid-v1" + + t.Run("under UnixFSHAMTDirectorySizeThreshold=256KiB", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init(profile) + node.StartDaemon() + defer node.StopDaemon() + + randDir, err := os.MkdirTemp(node.Dir, seed) + require.NoError(t, err) + + // Create directory with a lot of files that have filenames which together take close to UnixFSHAMTDirectorySizeThreshold in total + err = createDirectoryForHAMT(randDir, cidV1Length, "255KiB", seed) + require.NoError(t, err) + cidStr := node.IPFS("add", "-r", "-Q", randDir).Stdout.Trimmed() + + // Confirm the number of links is more than UnixFSHAMTDirectoryMaxFanout (indicating regular "basic" directory" + root, err := node.InspectPBNode(cidStr) + assert.NoError(t, err) + require.Equal(t, 897, len(root.Links)) + }) + + t.Run("above UnixFSHAMTDirectorySizeThreshold=256KiB", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init(profile) + node.StartDaemon() + defer node.StopDaemon() + + randDir, err := os.MkdirTemp(node.Dir, seed) + require.NoError(t, err) + + // Create directory with a lot of files that have filenames which together take close to UnixFSHAMTDirectorySizeThreshold in total + err = createDirectoryForHAMT(randDir, cidV1Length, "257KiB", seed) + require.NoError(t, err) + cidStr := node.IPFS("add", "-r", "-Q", randDir).Stdout.Trimmed() + + // Confirm this time, the number of links is less than UnixFSHAMTDirectoryMaxFanout + root, err := node.InspectPBNode(cidStr) + assert.NoError(t, err) + require.Equal(t, 252, len(root.Links)) + }) + }) + + t.Run("ipfs init --profile=test-cid-v1-wide applies UnixFSChunker=size-1048576 and UnixFSFileMaxLinks=1024", func(t *testing.T) { + t.Parallel() + seed := "v1-seed-1024" + profile := "--profile=test-cid-v1-wide" + + t.Run("under UnixFSFileMaxLinks=1024", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init(profile) + node.StartDaemon() + defer node.StopDaemon() + // Add 174MiB file: + // 1024 * 1MiB should fit in single layer + cidStr := node.IPFSAddDeterministic("1024MiB", seed) + root, err := node.InspectPBNode(cidStr) + assert.NoError(t, err) + require.Equal(t, 1024, len(root.Links)) + // expect same CID every time + require.Equal(t, "bafybeiej5w63ir64oxgkr5htqmlerh5k2rqflurn2howimexrlkae64xru", cidStr) + }) + + t.Run("above UnixFSFileMaxLinks=1024", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init(profile) + node.StartDaemon() + defer node.StopDaemon() + // add +1MiB (one more block), it should force rebalancing DAG and moving most to second layer + cidStr := node.IPFSAddDeterministic("1025MiB", seed) + root, err := node.InspectPBNode(cidStr) + assert.NoError(t, err) + require.Equal(t, 2, len(root.Links)) + // expect same CID every time + require.Equal(t, "bafybeieilp2qx24pe76hxrxe6bpef5meuxto3kj5dd6mhb5kplfeglskdm", cidStr) + }) }) + + t.Run("ipfs init --profile=test-cid-v1-wide applies UnixFSHAMTDirectoryMaxFanout=256 and UnixFSHAMTDirectorySizeThreshold=1MiB", func(t *testing.T) { + t.Parallel() + seed := "hamt-cid-v1" + profile := "--profile=test-cid-v1-wide" + + t.Run("under UnixFSHAMTDirectorySizeThreshold=1MiB", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init(profile) + node.StartDaemon() + defer node.StopDaemon() + + randDir, err := os.MkdirTemp(node.Dir, seed) + require.NoError(t, err) + + // Create directory with a lot of files that have filenames which together take close to UnixFSHAMTDirectorySizeThreshold in total + err = createDirectoryForHAMT(randDir, cidV1Length, "1023KiB", seed) + require.NoError(t, err) + cidStr := node.IPFS("add", "-r", "-Q", randDir).Stdout.Trimmed() + + // Confirm the number of links is more than UnixFSHAMTDirectoryMaxFanout (indicating regular "basic" directory" + root, err := node.InspectPBNode(cidStr) + assert.NoError(t, err) + require.Equal(t, 3599, len(root.Links)) + }) + + t.Run("above UnixFSHAMTDirectorySizeThreshold=1MiB", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init(profile) + node.StartDaemon() + defer node.StopDaemon() + + randDir, err := os.MkdirTemp(node.Dir, seed) + require.NoError(t, err) + + // Create directory with a lot of files that have filenames which together take close to UnixFSHAMTDirectorySizeThreshold in total + err = createDirectoryForHAMT(randDir, cidV1Length, "1025KiB", seed) + require.NoError(t, err) + cidStr := node.IPFS("add", "-r", "-Q", randDir).Stdout.Trimmed() + + // Confirm this time, the number of links is less than UnixFSHAMTDirectoryMaxFanout + root, err := node.InspectPBNode(cidStr) + assert.NoError(t, err) + require.Equal(t, 992, len(root.Links)) + }) + }) + +} + +// createDirectoryForHAMT aims to create enough files with long names for the directory block to be close to the UnixFSHAMTDirectorySizeThreshold. +// The calculation is based on boxo's HAMTShardingSize and sizeBelowThreshold which calculates ballpark size of the block +// by adding length of link names and the binary cid length. +// See https://github.com/ipfs/boxo/blob/6c5a07602aed248acc86598f30ab61923a54a83e/ipld/unixfs/io/directory.go#L491 +func createDirectoryForHAMT(dirPath string, cidLength int, unixfsNodeSizeTarget, seed string) error { + hamtThreshold, err := humanize.ParseBytes(unixfsNodeSizeTarget) + if err != nil { + return err + } + + // Calculate how many files with long filenames are needed to hit UnixFSHAMTDirectorySizeThreshold + nameLen := 255 // max that works across windows/macos/linux + alphabetLen := len(testutils.AlphabetEasy) + numFiles := int(hamtThreshold) / (nameLen + cidLength) + + // Deterministic pseudo-random bytes for static CID + drand, err := testutils.DeterministicRandomReader(unixfsNodeSizeTarget, seed) + if err != nil { + return err + } + + // Create necessary files in a single, flat directory + for i := 0; i < numFiles; i++ { + buf := make([]byte, nameLen) + _, err := io.ReadFull(drand, buf) + if err != nil { + return err + } + + // Convert deterministic pseudo-random bytes to ASCII + var sb strings.Builder + + for _, b := range buf { + // Map byte to printable ASCII range (33-126) + char := testutils.AlphabetEasy[int(b)%alphabetLen] + sb.WriteRune(char) + } + filename := sb.String()[:nameLen] + filePath := filepath.Join(dirPath, filename) + + // Create empty file + f, err := os.Create(filePath) + if err != nil { + return err + } + f.Close() + } + return nil } diff --git a/test/cli/harness/ipfs.go b/test/cli/harness/ipfs.go index 8537e2aa25d..0842d362727 100644 --- a/test/cli/harness/ipfs.go +++ b/test/cli/harness/ipfs.go @@ -76,6 +76,17 @@ func (n *Node) IPFSAddStr(content string, args ...string) string { return n.IPFSAdd(strings.NewReader(content), args...) } +// IPFSAddDeterministic produces a CID of a file of a certain size, filled with deterministically generated bytes based on some seed. +// This ensures deterministic CID on the other end, that can be used in tests. +func (n *Node) IPFSAddDeterministic(size string, seed string, args ...string) string { + log.Debugf("node %d adding %s of deterministic pseudo-random data with seed %q and args: %v", n.ID, size, seed, args) + reader, err := DeterministicRandomReader(size, seed) + if err != nil { + panic(err) + } + return n.IPFSAdd(reader, args...) +} + func (n *Node) IPFSAdd(content io.Reader, args ...string) string { log.Debugf("node %d adding with args: %v", n.ID, args) fullArgs := []string{"add", "-q"} @@ -108,3 +119,15 @@ func (n *Node) IPFSDagImport(content io.Reader, cid string, args ...string) erro }) return res.Err } + +/* +func (n *Node) IPFSDagExport(cid string, car *os.File) error { + log.Debugf("node %d dag export of %s to %q with args: %v", n.ID, cid, car.Name()) + res := n.Runner.MustRun(RunRequest{ + Path: n.IPFSBin, + Args: []string{"dag", "export", cid}, + CmdOpts: []CmdOpt{RunWithStdout(car)}, + }) + return res.Err +} +*/ diff --git a/test/cli/harness/pbinspect.go b/test/cli/harness/pbinspect.go new file mode 100644 index 00000000000..6abddb61f10 --- /dev/null +++ b/test/cli/harness/pbinspect.go @@ -0,0 +1,54 @@ +package harness + +import ( + "bytes" + "encoding/json" +) + +// InspectPBNode uses dag-json output of 'ipfs dag get' to inspect +// "Logical Format" of DAG-PB as defined in +// https://web.archive.org/web/20250403194752/https://ipld.io/specs/codecs/dag-pb/spec/#logical-format +// (mainly used for inspecting Links without depending on any libraries) +func (n *Node) InspectPBNode(cid string) (PBNode, error) { + log.Debugf("node %d dag get %s as dag-json", n.ID, cid) + + var root PBNode + var dagJsonOutput bytes.Buffer + res := n.Runner.MustRun(RunRequest{ + Path: n.IPFSBin, + Args: []string{"dag", "get", "--output-codec=dag-json", cid}, + CmdOpts: []CmdOpt{RunWithStdout(&dagJsonOutput)}, + }) + if res.Err != nil { + return root, res.Err + } + + err := json.Unmarshal(dagJsonOutput.Bytes(), &root) + if err != nil { + return root, err + } + return root, nil + +} + +// Define structs to match the JSON for +type PBHash struct { + Slash string `json:"/"` +} + +type PBLink struct { + Hash PBHash `json:"Hash"` + Name string `json:"Name"` + Tsize int `json:"Tsize"` +} + +type PBData struct { + Slash struct { + Bytes string `json:"bytes"` + } `json:"/"` +} + +type PBNode struct { + Data PBData `json:"Data"` + Links []PBLink `json:"Links"` +} diff --git a/test/cli/testutils/random_deterministic.go b/test/cli/testutils/random_deterministic.go new file mode 100644 index 00000000000..e55404168f6 --- /dev/null +++ b/test/cli/testutils/random_deterministic.go @@ -0,0 +1,46 @@ +package testutils + +import ( + "crypto/sha256" + "io" + + "github.com/dustin/go-humanize" + "golang.org/x/crypto/chacha20" +) + +type randomReader struct { + cipher *chacha20.Cipher + remaining int64 +} + +func (r *randomReader) Read(p []byte) (int, error) { + if r.remaining <= 0 { + return 0, io.EOF + } + n := int64(len(p)) + if n > r.remaining { + n = r.remaining + } + // Generate random bytes directly into the provided buffer + r.cipher.XORKeyStream(p[:n], make([]byte, n)) + r.remaining -= n + return int(n), nil +} + +// createRandomReader produces specified number of pseudo-random bytes +// from a seed. +func DeterministicRandomReader(sizeStr string, seed string) (io.Reader, error) { + size, err := humanize.ParseBytes(sizeStr) + if err != nil { + return nil, err + } + // Hash the seed string to a 32-byte key for ChaCha20 + key := sha256.Sum256([]byte(seed)) + // Use ChaCha20 for deterministic random bytes + var nonce [chacha20.NonceSize]byte // Zero nonce for simplicity + cipher, err := chacha20.NewUnauthenticatedCipher(key[:chacha20.KeySize], nonce[:]) + if err != nil { + return nil, err + } + return &randomReader{cipher: cipher, remaining: int64(size)}, nil +} diff --git a/test/cli/testutils/random_files.go b/test/cli/testutils/random_files.go index c7dca10d6de..7991cad8309 100644 --- a/test/cli/testutils/random_files.go +++ b/test/cli/testutils/random_files.go @@ -24,20 +24,22 @@ type RandFiles struct { FanoutFiles int // how many files per dir FanoutDirs int // how many dirs per dir - RandomSize bool // randomize file sizes - RandomFanout bool // randomize fanout numbers + RandomSize bool // randomize file sizes + RandomNameSize bool // randomize filename lengths + 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, + Rand: rand.New(rand.NewSource(time.Now().UnixNano())), + FileSize: 4096, + FilenameSize: 16, + Alphabet: AlphabetEasy, + FanoutDepth: 2, + FanoutDirs: 5, + FanoutFiles: 10, + RandomSize: true, + RandomNameSize: true, } } @@ -83,7 +85,10 @@ func (r *RandFiles) WriteRandomFile(root string) error { filesize = r.Rand.Int63n(filesize) + 1 } - n := rand.Intn(r.FilenameSize-4) + 4 + n := r.FilenameSize + if r.RandomNameSize { + n = rand.Intn(r.FilenameSize-4) + 4 + } name := r.RandomFilename(n) filepath := path.Join(root, name) f, err := os.Create(filepath) diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 0cf72f9ca8a..fef5063001b 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -33,6 +33,7 @@ require ( 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/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // 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 @@ -57,6 +58,7 @@ require ( github.com/chavacava/garif v0.1.0 // indirect github.com/ckaznocha/intrange v0.1.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect + github.com/crackcomm/go-gitignore v0.0.0-20241020182519-7843d2ba8fdf // 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 @@ -116,7 +118,8 @@ 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.29.2-0.20250409154342-bbaf2e146dfb // indirect + github.com/ipfs/boxo v0.29.2-0.20250415191135-dc60fe747c37 // indirect + github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.5.0 // indirect github.com/ipfs/go-datastore v0.8.2 // indirect @@ -273,6 +276,7 @@ require ( 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/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/xen0n/gosmopolitan v1.2.2 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 4fef97504e1..a0be368440a 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -43,6 +43,8 @@ github.com/alecthomas/go-check-sumtype v0.1.4 h1:WCvlB3l5Vq5dZQTFmodqL2g68uHiSww 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/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/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= @@ -105,6 +107,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma 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/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/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= @@ -294,8 +298,10 @@ 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.29.2-0.20250409154342-bbaf2e146dfb h1:kA7c3CF6/d8tUwGJR/SwIfaRz7Xk7Fbyoh2ePZAFMlw= -github.com/ipfs/boxo v0.29.2-0.20250409154342-bbaf2e146dfb/go.mod h1:omQZmLS7LegSpBy3m4CrAB9/SO7Fq3pfv+5y1FOd+gI= +github.com/ipfs/boxo v0.29.2-0.20250415191135-dc60fe747c37 h1:q3a+2FIbWzZbx/yUqpuG4jLVSa6GvxtRfx9TU5GLiN0= +github.com/ipfs/boxo v0.29.2-0.20250415191135-dc60fe747c37/go.mod h1:omQZmLS7LegSpBy3m4CrAB9/SO7Fq3pfv+5y1FOd+gI= +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-cid v0.5.0 h1:goEKKhaGm0ul11IHA7I6p1GmKz8kEYniqFopaB5Otwg= @@ -767,6 +773,8 @@ github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSD 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/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= 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= diff --git a/test/sharness/t0032-mount-sharded.sh b/test/sharness/t0032-mount-sharded.sh index 10ba421a225..7a3e518585b 100755 --- a/test/sharness/t0032-mount-sharded.sh +++ b/test/sharness/t0032-mount-sharded.sh @@ -16,7 +16,7 @@ fi test_init_ipfs test_expect_success 'force sharding' ' - ipfs config --json Internal.UnixFSShardingSizeThreshold "\"1B\"" + ipfs config --json Import.UnixFSHAMTDirectorySizeThreshold "\"1B\"" ' test_launch_ipfs_daemon diff --git a/test/sharness/t0250-files-api.sh b/test/sharness/t0250-files-api.sh index 9c01a5bcf17..63dacf7d407 100755 --- a/test/sharness/t0250-files-api.sh +++ b/test/sharness/t0250-files-api.sh @@ -849,7 +849,7 @@ tests_for_files_api "with-daemon" test_kill_ipfs_daemon test_expect_success "enable sharding in config" ' - ipfs config --json Internal.UnixFSShardingSizeThreshold "\"1B\"" + ipfs config --json Import.UnixFSHAMTDirectorySizeThreshold "\"1B\"" ' test_launch_ipfs_daemon_without_network @@ -880,7 +880,7 @@ test_expect_success "set up automatic sharding/unsharding data" ' ' test_expect_success "reset automatic sharding" ' - ipfs config --json Internal.UnixFSShardingSizeThreshold null + ipfs config --json Import.UnixFSHAMTDirectorySizeThreshold null ' test_launch_ipfs_daemon_without_network diff --git a/test/sharness/t0260-sharding.sh b/test/sharness/t0260-sharding.sh index 85e4a7ca708..7b0094fd4ea 100755 --- a/test/sharness/t0260-sharding.sh +++ b/test/sharness/t0260-sharding.sh @@ -34,7 +34,7 @@ test_init_ipfs UNSHARDED="QmavrTrQG4VhoJmantURAYuw3bowq3E2WcvP36NRQDAC1N" test_expect_success "force sharding off" ' -ipfs config --json Internal.UnixFSShardingSizeThreshold "\"1G\"" +ipfs config --json Import.UnixFSHAMTDirectorySizeThreshold "\"1G\"" ' test_add_dir "$UNSHARDED" @@ -46,7 +46,7 @@ test_add_dir "$UNSHARDED" test_kill_ipfs_daemon test_expect_success "force sharding on" ' - ipfs config --json Internal.UnixFSShardingSizeThreshold "\"1B\"" + ipfs config --json Import.UnixFSHAMTDirectorySizeThreshold "\"1B\"" ' SHARDED="QmSCJD1KYLhVVHqBK3YyXuoEqHt7vggyJhzoFYbT8v1XYL" From ee5665d37a8d54a520f7af512ad86b435f3af2f9 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Thu, 24 Apr 2025 08:14:10 -0700 Subject: [PATCH 21/42] remove duplicate workds (#10790) --- docs/config.md | 2 +- docs/experimental-features.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/config.md b/docs/config.md index 1ec5677db28..3724487d96b 100644 --- a/docs/config.md +++ b/docs/config.md @@ -367,7 +367,7 @@ secret. > The RPC API is vast. It grants admin-level access to your Kubo IPFS node, including > configuration and secret key management. > -> - If you need secure access to a subset of RPC, make sure you understand the risk, block everything by default and and allow basic auth access with [`API.Authorizations`](#apiauthorizations) or custom auth middleware running in front of the localhost-only port defined in [`Addresses.API`](#addressesapi). +> - If you need secure access to a subset of RPC, make sure you understand the risk, block everything by default and allow basic auth access with [`API.Authorizations`](#apiauthorizations) or custom auth middleware running in front of the localhost-only port defined in [`Addresses.API`](#addressesapi). > - If you are looking for an interface designed for browsers and public internet, use [`Addresses.Gateway`](#addressesgateway) port instead. Default: `null` diff --git a/docs/experimental-features.md b/docs/experimental-features.md index 3fccdad197f..c0832b2e149 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -89,7 +89,7 @@ filestore instead of copying the files into your local IPFS repo. - [ ] Need to address error states and failure conditions - [ ] cleanup of broken filesystem references (if file is deleted) - [ ] tests that confirm ability to override preexisting filesystem links (allowing user to fix broken link) - - [ ] support for a a single block having more than one sources in filesystem (blocks can be shared by unrelated files, and not be broken when some files are unpinned / gc'd) + - [ ] support for a single block having more than one sources in filesystem (blocks can be shared by unrelated files, and not be broken when some files are unpinned / gc'd) - [ ] [other known issues](https://github.com/ipfs/kubo/issues/7161) - [ ] Need to write docs on usage, advantages, disadvantages - [ ] Need to merge utility commands to aid in maintenance and repair of filestore @@ -128,7 +128,7 @@ And then add a file at a specific URL using `ipfs urlstore add ` - [ ] Need to address error states and failure conditions - [ ] cleanup of broken URL+range references (if URL starts returning 404 or error) - [ ] tests that confirm ability to override preexisting URL+range links (allowing user to fix broken link) - - [ ] support for a a single block having more than one URL+range (blocks can be shared by unrelated URLs) + - [ ] support for a single block having more than one URL+range (blocks can be shared by unrelated URLs) - [ ] Need to write docs on usage, advantages, disadvantages - [ ] Need to implement caching - [ ] Need to add metrics to monitor performance From ef399655d6592042de949736a41e07f3a946120e Mon Sep 17 00:00:00 2001 From: Guillaume Michel Date: Tue, 29 Apr 2025 14:26:50 +0000 Subject: [PATCH 22/42] docs: use latest fuse package (#10791) --- docs/fuse.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/fuse.md b/docs/fuse.md index 7744a0d457b..b4b966e5240 100644 --- a/docs/fuse.md +++ b/docs/fuse.md @@ -16,7 +16,7 @@ to your distribution manual to get things working. Install `fuse` with your favorite package manager: ``` -sudo apt-get install fuse +sudo apt-get install fuse3 ``` On some older Linux distributions, you may need to add yourself to the `fuse` group. From 05565083df5446ba3a4001d6c8a0dc28809aaf89 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Wed, 30 Apr 2025 06:07:09 -0700 Subject: [PATCH 23/42] Upgrade to Boxo v0.30.0 (#10794) * Upgrade to Boxo v0.30.0 --- core/commands/stat_provide.go | 4 +- docs/changelogs/v0.35.md | 1 + 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 | 49 +++++------ test/dependencies/go.sum | 113 ++++++++++--------------- 8 files changed, 208 insertions(+), 231 deletions(-) diff --git a/core/commands/stat_provide.go b/core/commands/stat_provide.go index 8a3dcff305a..7a54a79e4f1 100644 --- a/core/commands/stat_provide.go +++ b/core/commands/stat_provide.go @@ -57,8 +57,8 @@ This interface is not stable and may change from release to release. wtr := tabwriter.NewWriter(w, 1, 2, 1, ' ', 0) defer wtr.Flush() - fmt.Fprintf(wtr, "TotalProvides:\t%s\n", humanNumber(s.TotalProvides)) - fmt.Fprintf(wtr, "AvgProvideDuration:\t%s\n", humanDuration(s.AvgProvideDuration)) + fmt.Fprintf(wtr, "TotalReprovides:\t%s\n", humanNumber(s.TotalReprovides)) + fmt.Fprintf(wtr, "AvgReprovideDuration:\t%s\n", humanDuration(s.AvgReprovideDuration)) fmt.Fprintf(wtr, "LastReprovideDuration:\t%s\n", humanDuration(s.LastReprovideDuration)) if !s.LastRun.IsZero() { fmt.Fprintf(wtr, "LastRun:\t%s\n", humanTime(s.LastRun)) diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index bc3a857f8b7..d383fafad26 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -83,6 +83,7 @@ The release updated configuration [profiles](https://github.com/ipfs/kubo/blob/m #### πŸ“¦οΈ Important dependency updates +- update `boxo` to [v0.30.0](https://github.com/ipfs/boxo/releases/tag/v0.30.0) - update `ipfs-webui` to [v4.7.0](https://github.com/ipfs/ipfs-webui/releases/tag/v4.7.0) ### πŸ“ Changelog diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 7adc7c80a81..27e7df28fa4 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.24 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.29.2-0.20250415191135-dc60fe747c37 + github.com/ipfs/boxo v0.30.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.41.1 github.com/multiformats/go-multiaddr v0.15.0 @@ -124,8 +124,8 @@ require ( github.com/libp2p/go-doh-resolver v0.5.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.30.2 // indirect - github.com/libp2p/go-libp2p-kbucket v0.6.5 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.32.0 // indirect + github.com/libp2p/go-libp2p-kbucket v0.7.0 // indirect github.com/libp2p/go-libp2p-pubsub v0.13.0 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.3.1 // indirect @@ -139,7 +139,7 @@ require ( github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mholt/acmez/v3 v3.0.0 // indirect - github.com/miekg/dns v1.1.63 // indirect + github.com/miekg/dns v1.1.65 // 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,10 +181,10 @@ require ( github.com/pion/webrtc/v4 v4.0.10 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_golang v1.21.1 // indirect - github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.62.0 // indirect - github.com/prometheus/procfs v0.15.1 // indirect + github.com/prometheus/client_golang v1.22.0 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.63.0 // indirect + github.com/prometheus/procfs v0.16.1 // indirect github.com/quic-go/qpack v0.5.1 // indirect github.com/quic-go/quic-go v0.50.1 // indirect github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect @@ -205,15 +205,15 @@ require ( go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect - go.opentelemetry.io/otel v1.34.0 // indirect + go.opentelemetry.io/otel v1.35.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.34.0 // indirect + go.opentelemetry.io/otel/metric v1.35.0 // indirect go.opentelemetry.io/otel/sdk v1.31.0 // indirect - go.opentelemetry.io/otel/trace v1.34.0 // indirect + go.opentelemetry.io/otel/trace v1.35.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 @@ -223,20 +223,20 @@ require ( go.uber.org/zap v1.27.0 // indirect go.uber.org/zap/exp v0.3.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.35.0 // indirect - golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/net v0.35.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.22.0 // indirect - golang.org/x/tools v0.30.0 // indirect + golang.org/x/crypto v0.37.0 // indirect + golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect + golang.org/x/mod v0.24.0 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/sync v0.13.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect + golang.org/x/tools v0.32.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect - gonum.org/v1/gonum v0.15.1 // indirect + gonum.org/v1/gonum v0.16.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.36.5 // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.4.0 // indirect ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 5e2f686a0fb..76251bf28d8 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -244,8 +244,8 @@ 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.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= 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= @@ -298,8 +298,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 h1:OqNqsGZPX8zh3eFMO8Lf8EHRRnSGBMqcd github.com/ipfs-shipyard/nopfs/ipfs v0.25.0/go.mod h1:BxhUdtBgOXg1B+gAPEplkg/GpyTZY+kCMSfsJvvydqU= 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.29.2-0.20250415191135-dc60fe747c37 h1:q3a+2FIbWzZbx/yUqpuG4jLVSa6GvxtRfx9TU5GLiN0= -github.com/ipfs/boxo v0.29.2-0.20250415191135-dc60fe747c37/go.mod h1:omQZmLS7LegSpBy3m4CrAB9/SO7Fq3pfv+5y1FOd+gI= +github.com/ipfs/boxo v0.30.0 h1:7afsoxPGGqfoH7Dum/wOTGUB9M5fb8HyKPMlLfBvIEQ= +github.com/ipfs/boxo v0.30.0/go.mod h1:BPqgGGyHB9rZZcPSzah2Dc9C+5Or3U1aQe7EH1H7370= 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= @@ -461,11 +461,11 @@ 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.30.2 h1:K0LJPdXynQ+u3rx6uFlrfNy0i11LE6SOCDzwAAaahys= -github.com/libp2p/go-libp2p-kad-dht v0.30.2/go.mod h1:UV0mxF4ufh/ht05jNg5mcjOMrjK82uecgANa+GKi4y0= +github.com/libp2p/go-libp2p-kad-dht v0.32.0 h1:dpyq7o00od98vPQG0IZvNHpeLnKyuICN1nVzGnVMC9k= +github.com/libp2p/go-libp2p-kad-dht v0.32.0/go.mod h1:vQU5oE9hMHXJhSQawbZapC9u0U9dc+tWC0DYasGmIAA= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= -github.com/libp2p/go-libp2p-kbucket v0.6.5 h1:Fsl1YvZcMwqrR4DYrTO02yo9PGYs2HBQIT3lGXFMTxg= -github.com/libp2p/go-libp2p-kbucket v0.6.5/go.mod h1:U6WOd0BvnSp03IQSrjgM54tg7zh1UUNsXLJqAQzClTA= +github.com/libp2p/go-libp2p-kbucket v0.7.0 h1:vYDvRjkyJPeWunQXqcW2Z6E93Ywx7fX0jgzb/dGOKCs= +github.com/libp2p/go-libp2p-kbucket v0.7.0/go.mod h1:blOINGIj1yiPYlVEX0Rj9QwEkmVnz3EP8LK1dRKBC6g= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= github.com/libp2p/go-libp2p-pubsub v0.13.0 h1:RmFQ2XAy3zQtbt2iNPy7Tt0/3fwTnHpCQSSnmGnt1Ps= github.com/libp2p/go-libp2p-pubsub v0.13.0/go.mod h1:m0gpUOyrXKXdE7c8FNQ9/HLfWbxaEw7xku45w+PaqZo= @@ -512,8 +512,8 @@ github.com/mholt/acmez/v3 v3.0.0 h1:r1NcjuWR0VaKP2BTjDK9LRFBw/WvURx3jlaEUl9Ht8E= github.com/mholt/acmez/v3 v3.0.0/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY= -github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs= +github.com/miekg/dns v1.1.65 h1:0+tIPHzUW0GCge7IiK3guGP57VAw7hoPDfApjkMD1Fc= +github.com/miekg/dns v1.1.65/go.mod h1:Dzw9769uoKVaLuODMDZz9M6ynFU6Em65csPuoi8G0ck= 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= @@ -666,18 +666,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.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk= -github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg= +github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= +github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= 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/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= -github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= +github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= +github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= 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/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= 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.50.1 h1:unsgjFIUqW8a2oopkY7YNONpV1gYND6Nt9hnt1PN94Q= @@ -822,8 +822,8 @@ go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJyS go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= 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.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= -go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= 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= @@ -834,12 +834,12 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0 h1:UGZ1QwZWY67Z6Bm 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.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= -go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= 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.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= -go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= 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.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -890,8 +890,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.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= -golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= 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= @@ -900,8 +900,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-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4= -golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= +golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM= +golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8= 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= @@ -925,8 +925,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.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= +golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= 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= @@ -964,8 +964,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.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= 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= @@ -984,8 +984,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.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= +golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 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= @@ -1039,8 +1039,8 @@ 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.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.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 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= @@ -1060,8 +1060,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.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= 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= @@ -1105,8 +1105,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.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= +golang.org/x/tools v0.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU= +golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s= 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= @@ -1114,8 +1114,8 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T 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.1 h1:FNy7N6OUZVUaWG9pTiD+jlhdQ3lMP+/LcTpJ6+a8sQ0= -gonum.org/v1/gonum v0.15.1/go.mod h1:eZTZuRFrzu5pcyjN5wJhcIhnUdNijYxX1T2IcrOGY0o= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= 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= @@ -1181,8 +1181,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.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= 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 68e8c7a3f00..c6342a48de7 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.14 github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 - github.com/ipfs/boxo v0.29.2-0.20250415191135-dc60fe747c37 + github.com/ipfs/boxo v0.30.0 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.5.0 github.com/ipfs/go-cidutil v0.1.0 @@ -55,8 +55,8 @@ require ( github.com/libp2p/go-doh-resolver v0.5.0 github.com/libp2p/go-libp2p v0.41.1 github.com/libp2p/go-libp2p-http v0.5.0 - github.com/libp2p/go-libp2p-kad-dht v0.30.2 - github.com/libp2p/go-libp2p-kbucket v0.6.5 + github.com/libp2p/go-libp2p-kad-dht v0.32.0 + github.com/libp2p/go-libp2p-kbucket v0.7.0 github.com/libp2p/go-libp2p-pubsub v0.13.0 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.3.1 @@ -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.21.1 + github.com/prometheus/client_golang v1.22.0 github.com/stretchr/testify v1.10.0 github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d github.com/tidwall/gjson v1.16.0 @@ -80,19 +80,19 @@ require ( go.opencensus.io v0.24.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.34.0 + go.opentelemetry.io/otel v1.35.0 go.opentelemetry.io/otel/sdk v1.31.0 - go.opentelemetry.io/otel/trace v1.34.0 + go.opentelemetry.io/otel/trace v1.35.0 go.uber.org/dig v1.18.0 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.35.0 - golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa - golang.org/x/mod v0.23.0 - golang.org/x/sync v0.11.0 - golang.org/x/sys v0.30.0 - google.golang.org/protobuf v1.36.5 + golang.org/x/crypto v0.37.0 + golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 + golang.org/x/mod v0.24.0 + golang.org/x/sync v0.13.0 + golang.org/x/sys v0.32.0 + google.golang.org/protobuf v1.36.6 ) require ( @@ -185,7 +185,7 @@ require ( github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect github.com/mholt/acmez/v3 v3.0.0 // indirect - github.com/miekg/dns v1.1.63 // indirect + github.com/miekg/dns v1.1.65 // 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 @@ -222,9 +222,9 @@ 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/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.62.0 // indirect - github.com/prometheus/procfs v0.15.1 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.63.0 // indirect + github.com/prometheus/procfs v0.16.1 // indirect github.com/prometheus/statsd_exporter v0.27.1 // indirect github.com/quic-go/qpack v0.5.1 // indirect github.com/quic-go/quic-go v0.50.1 // indirect @@ -257,19 +257,19 @@ require ( 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.34.0 // indirect + go.opentelemetry.io/otel/metric v1.35.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 go.uber.org/zap/exp v0.3.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/net v0.35.0 // indirect - golang.org/x/oauth2 v0.24.0 // indirect - golang.org/x/term v0.29.0 // indirect - golang.org/x/text v0.22.0 // indirect - golang.org/x/tools v0.30.0 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/oauth2 v0.25.0 // indirect + golang.org/x/term v0.31.0 // indirect + golang.org/x/text v0.24.0 // indirect + golang.org/x/tools v0.32.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect - gonum.org/v1/gonum v0.15.1 // indirect + gonum.org/v1/gonum v0.16.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 diff --git a/go.sum b/go.sum index cf9c33444e2..313d66cac01 100644 --- a/go.sum +++ b/go.sum @@ -300,8 +300,8 @@ 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.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-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= 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= @@ -362,8 +362,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 h1:OqNqsGZPX8zh3eFMO8Lf8EHRRnSGBMqcd github.com/ipfs-shipyard/nopfs/ipfs v0.25.0/go.mod h1:BxhUdtBgOXg1B+gAPEplkg/GpyTZY+kCMSfsJvvydqU= 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.29.2-0.20250415191135-dc60fe747c37 h1:q3a+2FIbWzZbx/yUqpuG4jLVSa6GvxtRfx9TU5GLiN0= -github.com/ipfs/boxo v0.29.2-0.20250415191135-dc60fe747c37/go.mod h1:omQZmLS7LegSpBy3m4CrAB9/SO7Fq3pfv+5y1FOd+gI= +github.com/ipfs/boxo v0.30.0 h1:7afsoxPGGqfoH7Dum/wOTGUB9M5fb8HyKPMlLfBvIEQ= +github.com/ipfs/boxo v0.30.0/go.mod h1:BPqgGGyHB9rZZcPSzah2Dc9C+5Or3U1aQe7EH1H7370= 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= @@ -547,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.30.2 h1:K0LJPdXynQ+u3rx6uFlrfNy0i11LE6SOCDzwAAaahys= -github.com/libp2p/go-libp2p-kad-dht v0.30.2/go.mod h1:UV0mxF4ufh/ht05jNg5mcjOMrjK82uecgANa+GKi4y0= +github.com/libp2p/go-libp2p-kad-dht v0.32.0 h1:dpyq7o00od98vPQG0IZvNHpeLnKyuICN1nVzGnVMC9k= +github.com/libp2p/go-libp2p-kad-dht v0.32.0/go.mod h1:vQU5oE9hMHXJhSQawbZapC9u0U9dc+tWC0DYasGmIAA= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= -github.com/libp2p/go-libp2p-kbucket v0.6.5 h1:Fsl1YvZcMwqrR4DYrTO02yo9PGYs2HBQIT3lGXFMTxg= -github.com/libp2p/go-libp2p-kbucket v0.6.5/go.mod h1:U6WOd0BvnSp03IQSrjgM54tg7zh1UUNsXLJqAQzClTA= +github.com/libp2p/go-libp2p-kbucket v0.7.0 h1:vYDvRjkyJPeWunQXqcW2Z6E93Ywx7fX0jgzb/dGOKCs= +github.com/libp2p/go-libp2p-kbucket v0.7.0/go.mod h1:blOINGIj1yiPYlVEX0Rj9QwEkmVnz3EP8LK1dRKBC6g= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= github.com/libp2p/go-libp2p-pubsub v0.13.0 h1:RmFQ2XAy3zQtbt2iNPy7Tt0/3fwTnHpCQSSnmGnt1Ps= github.com/libp2p/go-libp2p-pubsub v0.13.0/go.mod h1:m0gpUOyrXKXdE7c8FNQ9/HLfWbxaEw7xku45w+PaqZo= @@ -610,8 +610,8 @@ github.com/mholt/acmez/v3 v3.0.0 h1:r1NcjuWR0VaKP2BTjDK9LRFBw/WvURx3jlaEUl9Ht8E= github.com/mholt/acmez/v3 v3.0.0/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY= -github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs= +github.com/miekg/dns v1.1.65 h1:0+tIPHzUW0GCge7IiK3guGP57VAw7hoPDfApjkMD1Fc= +github.com/miekg/dns v1.1.65/go.mod h1:Dzw9769uoKVaLuODMDZz9M6ynFU6Em65csPuoi8G0ck= 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= @@ -779,14 +779,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.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk= -github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg= +github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= +github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= 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/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= 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= @@ -794,8 +794,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.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= -github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= +github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= +github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= 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= @@ -803,8 +803,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.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/prometheus/statsd_exporter v0.27.1 h1:tcRJOmwlA83HPfWzosAgr2+zEN5XDFv+M2mn/uYkn5Y= github.com/prometheus/statsd_exporter v0.27.1/go.mod h1:vA6ryDfsN7py/3JApEst6nLTJboq66XsNcJGNmC88NQ= @@ -989,8 +989,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.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= -go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= 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= @@ -1001,12 +1001,12 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0 h1:UGZ1QwZWY67Z6Bm 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.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= -go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= 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.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= -go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= 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= @@ -1060,8 +1060,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.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= -golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= 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= @@ -1072,8 +1072,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-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4= -golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= +golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM= +golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8= 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= @@ -1098,8 +1098,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.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= +golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= 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= @@ -1152,8 +1152,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.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= 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= @@ -1163,8 +1163,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.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= -golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= +golang.org/x/oauth2 v0.25.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= @@ -1180,8 +1180,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.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= +golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 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= @@ -1256,8 +1256,8 @@ 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.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.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 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= @@ -1266,8 +1266,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.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= -golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= +golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o= +golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= 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= @@ -1279,8 +1279,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.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= 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= @@ -1341,8 +1341,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.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= +golang.org/x/tools v0.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU= +golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s= 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= @@ -1350,8 +1350,8 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T 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.1 h1:FNy7N6OUZVUaWG9pTiD+jlhdQ3lMP+/LcTpJ6+a8sQ0= -gonum.org/v1/gonum v0.15.1/go.mod h1:eZTZuRFrzu5pcyjN5wJhcIhnUdNijYxX1T2IcrOGY0o= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= 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= @@ -1448,8 +1448,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.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= 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 fef5063001b..bfcb2a5e6c1 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -92,7 +92,6 @@ require ( github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect github.com/gobwas/glob v0.2.3 // 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-20240816233607-d8596aa466a9 // indirect github.com/golangci/misspell v0.6.0 // indirect @@ -100,7 +99,7 @@ require ( 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/go-cmp v0.7.0 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20250208200701-d0013a598941 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect @@ -118,7 +117,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.29.2-0.20250415191135-dc60fe747c37 // indirect + github.com/ipfs/boxo v0.30.0 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.5.0 // indirect @@ -126,7 +125,6 @@ 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 v1.0.5 // indirect github.com/ipfs/go-metrics-interface v0.3.0 // indirect github.com/ipfs/kubo v0.31.0 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect @@ -158,8 +156,8 @@ require ( github.com/libp2p/go-flow-metrics v0.2.0 // indirect github.com/libp2p/go-libp2p v0.41.1 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.30.2 // indirect - github.com/libp2p/go-libp2p-kbucket v0.6.5 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.32.0 // indirect + github.com/libp2p/go-libp2p-kbucket v0.7.0 // indirect github.com/libp2p/go-libp2p-record v0.3.1 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.7.5 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect @@ -177,7 +175,7 @@ require ( github.com/mattn/go-shellwords v1.0.12 // indirect github.com/mgechev/revive v1.3.9 // indirect github.com/mholt/acmez/v3 v3.0.0 // indirect - github.com/miekg/dns v1.1.63 // indirect + github.com/miekg/dns v1.1.65 // 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 @@ -198,7 +196,6 @@ require ( github.com/nunnatsa/ginkgolinter v0.16.2 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/onsi/ginkgo/v2 v2.22.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/v2 v2.2.2 // indirect github.com/pion/datachannel v1.5.10 // indirect @@ -223,10 +220,10 @@ 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.21.1 // indirect - github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.62.0 // indirect - github.com/prometheus/procfs v0.15.1 // indirect + github.com/prometheus/client_golang v1.22.0 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.63.0 // indirect + github.com/prometheus/procfs v0.16.1 // 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 @@ -288,9 +285,9 @@ require ( go-simpler.org/musttag v0.12.2 // indirect go-simpler.org/sloglint v0.7.2 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.34.0 // indirect - go.opentelemetry.io/otel/metric v1.34.0 // indirect - go.opentelemetry.io/otel/trace v1.34.0 // indirect + go.opentelemetry.io/otel v1.35.0 // indirect + go.opentelemetry.io/otel/metric v1.35.0 // indirect + go.opentelemetry.io/otel/trace v1.35.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 @@ -298,18 +295,18 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go.uber.org/zap/exp v0.3.0 // indirect - golang.org/x/crypto v0.35.0 // indirect - golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa // indirect + golang.org/x/crypto v0.37.0 // indirect + golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/net v0.35.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/term v0.29.0 // indirect - golang.org/x/text v0.22.0 // indirect - golang.org/x/tools v0.30.0 // indirect - gonum.org/v1/gonum v0.15.1 // indirect - google.golang.org/protobuf v1.36.5 // indirect + golang.org/x/mod v0.24.0 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/sync v0.13.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/term v0.31.0 // indirect + golang.org/x/text v0.24.0 // indirect + golang.org/x/tools v0.32.0 // indirect + gonum.org/v1/gonum v0.16.0 // indirect + google.golang.org/protobuf v1.36.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 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index a0be368440a..1b4a496128f 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -243,8 +243,9 @@ github.com/google/go-cmp v0.5.4/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.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-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= 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= @@ -253,7 +254,6 @@ 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-20250208200701-d0013a598941 h1:43XjGa6toxLpeksjcxs1jIoIyr+vUfOqY2c6HB4bpoc= github.com/google/pprof v0.0.0-20250208200701-d0013a598941/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= -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.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -298,8 +298,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.29.2-0.20250415191135-dc60fe747c37 h1:q3a+2FIbWzZbx/yUqpuG4jLVSa6GvxtRfx9TU5GLiN0= -github.com/ipfs/boxo v0.29.2-0.20250415191135-dc60fe747c37/go.mod h1:omQZmLS7LegSpBy3m4CrAB9/SO7Fq3pfv+5y1FOd+gI= +github.com/ipfs/boxo v0.30.0 h1:7afsoxPGGqfoH7Dum/wOTGUB9M5fb8HyKPMlLfBvIEQ= +github.com/ipfs/boxo v0.30.0/go.mod h1:BPqgGGyHB9rZZcPSzah2Dc9C+5Or3U1aQe7EH1H7370= 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= @@ -322,9 +322,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.3.0 h1:YwG7/Cy4R94mYDUuwsBfeziJCVm9pBMJ6q/JR9V40TU= @@ -366,7 +363,6 @@ 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.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= @@ -413,10 +409,10 @@ github.com/libp2p/go-libp2p v0.41.1 h1:8ecNQVT5ev/jqALTvisSJeVNvXYJyK4NhQx1nNRXQ github.com/libp2p/go-libp2p v0.41.1/go.mod h1:DcGTovJzQl/I7HMrby5ZRjeD0kQkGiy+9w6aEkSZpRI= 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.30.2 h1:K0LJPdXynQ+u3rx6uFlrfNy0i11LE6SOCDzwAAaahys= -github.com/libp2p/go-libp2p-kad-dht v0.30.2/go.mod h1:UV0mxF4ufh/ht05jNg5mcjOMrjK82uecgANa+GKi4y0= -github.com/libp2p/go-libp2p-kbucket v0.6.5 h1:Fsl1YvZcMwqrR4DYrTO02yo9PGYs2HBQIT3lGXFMTxg= -github.com/libp2p/go-libp2p-kbucket v0.6.5/go.mod h1:U6WOd0BvnSp03IQSrjgM54tg7zh1UUNsXLJqAQzClTA= +github.com/libp2p/go-libp2p-kad-dht v0.32.0 h1:dpyq7o00od98vPQG0IZvNHpeLnKyuICN1nVzGnVMC9k= +github.com/libp2p/go-libp2p-kad-dht v0.32.0/go.mod h1:vQU5oE9hMHXJhSQawbZapC9u0U9dc+tWC0DYasGmIAA= +github.com/libp2p/go-libp2p-kbucket v0.7.0 h1:vYDvRjkyJPeWunQXqcW2Z6E93Ywx7fX0jgzb/dGOKCs= +github.com/libp2p/go-libp2p-kbucket v0.7.0/go.mod h1:blOINGIj1yiPYlVEX0Rj9QwEkmVnz3EP8LK1dRKBC6g= github.com/libp2p/go-libp2p-record v0.3.1 h1:cly48Xi5GjNw5Wq+7gmjfBiG9HCzQVkiZOUZ8kUl+Fg= github.com/libp2p/go-libp2p-record v0.3.1/go.mod h1:T8itUkLcWQLCYMqtX7Th6r7SexyUJpIyPgks757td/E= github.com/libp2p/go-libp2p-routing-helpers v0.7.5 h1:HdwZj9NKovMx0vqq6YNPTh6aaNzey5zHD7HeLJtq6fI= @@ -468,8 +464,8 @@ github.com/mgechev/revive v1.3.9/go.mod h1:+uxEIr5UH0TjXWHTno3xh4u7eg6jDpXKzQccA github.com/mholt/acmez/v3 v3.0.0 h1:r1NcjuWR0VaKP2BTjDK9LRFBw/WvURx3jlaEUl9Ht8E= github.com/mholt/acmez/v3 v3.0.0/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY= -github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs= +github.com/miekg/dns v1.1.65 h1:0+tIPHzUW0GCge7IiK3guGP57VAw7hoPDfApjkMD1Fc= +github.com/miekg/dns v1.1.65/go.mod h1:Dzw9769uoKVaLuODMDZz9M6ynFU6Em65csPuoi8G0ck= 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= @@ -531,8 +527,6 @@ github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= 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/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= @@ -600,17 +594,17 @@ github.com/polyfloyd/go-errorlint v1.6.0/go.mod h1:HR7u8wuP1kb1NeN1zqTd1ZMlqUKPP 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.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk= -github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg= +github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= +github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -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/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= -github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= +github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= +github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= 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/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= 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= @@ -632,7 +626,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.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= @@ -789,7 +782,6 @@ github.com/yeya24/promlinter v0.3.0/go.mod h1:cDfJQQYv9uYciW60QT0eeHlFodotkYZlL+ 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= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= @@ -812,13 +804,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.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= -go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= -go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= -go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= -go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= -go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= -go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= 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= @@ -831,12 +822,9 @@ 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.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= -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= @@ -847,7 +835,6 @@ golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+ 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-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= @@ -863,11 +850,11 @@ golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf 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.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= -golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4= -golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= +golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM= +golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8= 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-20240314144324-c7f7c6466f7f h1:phY1HzDcf18Aq9A8KkmRtY9WvOFIxN8wgfvy6Zm1DV8= @@ -877,7 +864,6 @@ golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 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= @@ -894,8 +880,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.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= +golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= 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 +913,8 @@ 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.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= 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 +934,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.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= +golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 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= @@ -988,8 +974,8 @@ 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.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 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= @@ -1006,8 +992,8 @@ 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.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= -golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= +golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o= +golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= 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= @@ -1022,8 +1008,8 @@ 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.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= 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= @@ -1036,19 +1022,14 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/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-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= 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-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-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/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-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= @@ -1065,14 +1046,14 @@ 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.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= +golang.org/x/tools v0.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU= +golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s= 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.15.1 h1:FNy7N6OUZVUaWG9pTiD+jlhdQ3lMP+/LcTpJ6+a8sQ0= -gonum.org/v1/gonum v0.15.1/go.mod h1:eZTZuRFrzu5pcyjN5wJhcIhnUdNijYxX1T2IcrOGY0o= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= 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= @@ -1089,13 +1070,12 @@ 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/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= 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= 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/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= @@ -1116,7 +1096,6 @@ grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJd 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.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.4.0 h1:xDbKOZCVbnZsfzM6mHSYcGRHZ3YrLDzqz8XnV4uaD5w= From a5997375dbaaceb50d7a7ecb681ef029197c485d Mon Sep 17 00:00:00 2001 From: Guillaume Michel Date: Wed, 30 Apr 2025 13:32:03 +0000 Subject: [PATCH 24/42] feat: `Provider.WorkerCount` and `stats reprovide` (#10779) * adjust ipfs stats provide * update boxo dep * bump boxo * fixing tests * docs/chore: mark stat reprovide as experimental * docs: Provider.Strategy explicitly document it is not used - without this legacy users will have it in their config and be very confused --------- Co-authored-by: Marcin Rataj --- cmd/ipfs/kubo/daemon.go | 3 + config/config_test.go | 4 +- config/provider.go | 9 ++- config/reprovider.go | 2 + core/commands/commands_test.go | 1 + core/commands/stat.go | 11 +-- core/commands/stat_provide.go | 49 ++----------- core/commands/stat_reprovide.go | 104 ++++++++++++++++++++++++++++ core/node/groups.go | 1 + core/node/provider.go | 8 +-- docs/changelogs/v0.35.md | 32 +++++++++ docs/config.md | 37 ++++++++++ test/sharness/t0002-docker-image.sh | 4 +- test/sharness/t0070-user-config.sh | 8 +-- 14 files changed, 213 insertions(+), 60 deletions(-) create mode 100644 core/commands/stat_reprovide.go diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index 7ee5953070c..30e805186c1 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -485,6 +485,9 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment // This should never happen, but better safe than sorry log.Fatal("Private network does not work with Routing.Type=auto. Update your config to Routing.Type=dht (or none, and do manual peering)") } + if cfg.Provider.Strategy.WithDefault("") != "" && cfg.Reprovider.Strategy.IsDefault() { + log.Fatal("Invalid config. Remove unused Provider.Strategy and set Reprovider.Strategy instead. Documentation: https://github.com/ipfs/kubo/blob/master/docs/config.md#reproviderstrategy") + } printLibp2pPorts(node) diff --git a/config/config_test.go b/config/config_test.go index d4f38f08662..16573504370 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -134,9 +134,9 @@ func TestCheckKey(t *testing.T) { t.Fatal("Foo.Bar isn't a valid key in the config") } - err = CheckKey("Provider.Strategy") + err = CheckKey("Reprovider.Strategy") if err != nil { - t.Fatalf("%s: %s", err, "Provider.Strategy is a valid key in the config") + t.Fatalf("%s: %s", err, "Reprovider.Strategy is a valid key in the config") } err = CheckKey("Provider.Foo") diff --git a/config/provider.go b/config/provider.go index f2b5afe05b4..a1c44859889 100644 --- a/config/provider.go +++ b/config/provider.go @@ -1,5 +1,12 @@ package config +const ( + DefaultProviderWorkerCount = 64 +) + +// Provider configuration describes how NEW CIDs are announced the moment they are created. +// For periodical reprovide configuration, see Reprovider.* type Provider struct { - Strategy string // Which keys to announce + Strategy *OptionalString `json:",omitempty"` // Unused, you are likely looking for Reprovider.Strategy instead + WorkerCount *OptionalInteger `json:",omitempty"` // Number of concurrent provides allowed, 0 means unlimited } diff --git a/config/reprovider.go b/config/reprovider.go index dae9ae6dee9..3e8a5b476ca 100644 --- a/config/reprovider.go +++ b/config/reprovider.go @@ -7,6 +7,8 @@ const ( DefaultReproviderStrategy = "all" ) +// Reprovider configuration describes how CID from local datastore are periodically re-announced to routing systems. +// For provide behavior of ad-hoc or newly created CIDs and their first-time announcement, see Provider.* type Reprovider struct { Interval *OptionalDuration `json:",omitempty"` // Time period to reprovide locally stored objects to the network Strategy *OptionalString `json:",omitempty"` // Which keys to announce diff --git a/core/commands/commands_test.go b/core/commands/commands_test.go index 2dda639f545..d8b4c408380 100644 --- a/core/commands/commands_test.go +++ b/core/commands/commands_test.go @@ -184,6 +184,7 @@ func TestCommands(t *testing.T) { "/stats/bw", "/stats/dht", "/stats/provide", + "/stats/reprovide", "/stats/repo", "/swarm", "/swarm/addrs", diff --git a/core/commands/stat.go b/core/commands/stat.go index 2632d6aa257..2b4485a9513 100644 --- a/core/commands/stat.go +++ b/core/commands/stat.go @@ -27,11 +27,12 @@ for your IPFS node.`, }, Subcommands: map[string]*cmds.Command{ - "bw": statBwCmd, - "repo": repoStatCmd, - "bitswap": bitswapStatCmd, - "dht": statDhtCmd, - "provide": statProvideCmd, + "bw": statBwCmd, + "repo": repoStatCmd, + "bitswap": bitswapStatCmd, + "dht": statDhtCmd, + "provide": statProvideCmd, + "reprovide": statReprovideCmd, }, } diff --git a/core/commands/stat_provide.go b/core/commands/stat_provide.go index 7a54a79e4f1..ef06d8e2828 100644 --- a/core/commands/stat_provide.go +++ b/core/commands/stat_provide.go @@ -4,28 +4,20 @@ import ( "fmt" "io" "text/tabwriter" - "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/libp2p/go-libp2p-kad-dht/fullrt" - "golang.org/x/exp/constraints" ) -type reprovideStats struct { - provider.ReproviderStats - fullRT bool -} - var statProvideCmd = &cmds.Command{ + Status: cmds.Deprecated, Helptext: cmds.HelpText{ - Tagline: "Returns statistics about the node's (re)provider system.", + Tagline: "Deprecated command, use 'ipfs stats reprovide' instead.", ShortDescription: ` -Returns statistics about the content the node is advertising. - -This interface is not stable and may change from release to release. +'ipfs stats provide' is deprecated because provide and reprovide operations +are now distinct. This command may be replaced by provide only stats in the +future. `, }, Arguments: []cmds.Argument{}, @@ -57,8 +49,8 @@ This interface is not stable and may change from release to release. wtr := tabwriter.NewWriter(w, 1, 2, 1, ' ', 0) defer wtr.Flush() - fmt.Fprintf(wtr, "TotalReprovides:\t%s\n", humanNumber(s.TotalReprovides)) - fmt.Fprintf(wtr, "AvgReprovideDuration:\t%s\n", humanDuration(s.AvgReprovideDuration)) + fmt.Fprintf(wtr, "TotalProvides:\t%s\n", humanNumber(s.TotalReprovides)) + fmt.Fprintf(wtr, "AvgProvideDuration:\t%s\n", humanDuration(s.AvgReprovideDuration)) fmt.Fprintf(wtr, "LastReprovideDuration:\t%s\n", humanDuration(s.LastReprovideDuration)) if !s.LastRun.IsZero() { fmt.Fprintf(wtr, "LastRun:\t%s\n", humanTime(s.LastRun)) @@ -71,30 +63,3 @@ This interface is not stable and may change from release to release. }, Type: reprovideStats{}, } - -func humanDuration(val time.Duration) string { - return val.Truncate(time.Microsecond).String() -} - -func humanTime(val time.Time) string { - return val.Format("2006-01-02 15:04:05") -} - -func humanNumber[T constraints.Float | constraints.Integer](n T) string { - nf := float64(n) - str := humanSI(nf, 0) - fullStr := humanFull(nf, 0) - if str != fullStr { - return fmt.Sprintf("%s\t(%s)", str, fullStr) - } - return str -} - -func humanSI(val float64, decimals int) string { - v, unit := humanize.ComputeSI(val) - return fmt.Sprintf("%s%s", humanFull(v, decimals), unit) -} - -func humanFull(val float64, decimals int) string { - return humanize.CommafWithDigits(val, decimals) -} diff --git a/core/commands/stat_reprovide.go b/core/commands/stat_reprovide.go new file mode 100644 index 00000000000..10dbc727d38 --- /dev/null +++ b/core/commands/stat_reprovide.go @@ -0,0 +1,104 @@ +package commands + +import ( + "fmt" + "io" + "text/tabwriter" + "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/libp2p/go-libp2p-kad-dht/fullrt" + "golang.org/x/exp/constraints" +) + +type reprovideStats struct { + provider.ReproviderStats + fullRT bool +} + +var statReprovideCmd = &cmds.Command{ + Status: cmds.Experimental, + Helptext: cmds.HelpText{ + Tagline: "Returns statistics about the node's reprovider system.", + ShortDescription: ` +Returns statistics about the content the node is reproviding every +Reprovider.Interval according to Reprovider.Strategy: +https://github.com/ipfs/kubo/blob/master/docs/config.md#reprovider + +This interface is not stable and may change from release to release. + +`, + }, + Arguments: []cmds.Argument{}, + Options: []cmds.Option{}, + 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 + } + + stats, err := nd.Provider.Stat() + if err != nil { + return err + } + _, fullRT := nd.DHTClient.(*fullrt.FullRT) + + if err := res.Emit(reprovideStats{stats, fullRT}); err != nil { + return err + } + + return nil + }, + Encoders: cmds.EncoderMap{ + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, s reprovideStats) error { + wtr := tabwriter.NewWriter(w, 1, 2, 1, ' ', 0) + defer wtr.Flush() + + fmt.Fprintf(wtr, "TotalReprovides:\t%s\n", humanNumber(s.TotalReprovides)) + fmt.Fprintf(wtr, "AvgReprovideDuration:\t%s\n", humanDuration(s.AvgReprovideDuration)) + fmt.Fprintf(wtr, "LastReprovideDuration:\t%s\n", humanDuration(s.LastReprovideDuration)) + if !s.LastRun.IsZero() { + fmt.Fprintf(wtr, "LastReprovide:\t%s\n", humanTime(s.LastRun)) + if s.fullRT { + fmt.Fprintf(wtr, "NextReprovide:\t%s\n", humanTime(s.LastRun.Add(s.ReprovideInterval))) + } + } + return nil + }), + }, + Type: reprovideStats{}, +} + +func humanDuration(val time.Duration) string { + return val.Truncate(time.Microsecond).String() +} + +func humanTime(val time.Time) string { + return val.Format("2006-01-02 15:04:05") +} + +func humanNumber[T constraints.Float | constraints.Integer](n T) string { + nf := float64(n) + str := humanSI(nf, 0) + fullStr := humanFull(nf, 0) + if str != fullStr { + return fmt.Sprintf("%s\t(%s)", str, fullStr) + } + return str +} + +func humanSI(val float64, decimals int) string { + v, unit := humanize.ComputeSI(val) + return fmt.Sprintf("%s%s", humanFull(v, decimals), unit) +} + +func humanFull(val float64, decimals int) string { + return humanize.CommafWithDigits(val, decimals) +} diff --git a/core/node/groups.go b/core/node/groups.go index 4a471f17038..0e28444be95 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -359,6 +359,7 @@ func Online(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part cfg.Reprovider.Strategy.WithDefault(config.DefaultReproviderStrategy), cfg.Reprovider.Interval.WithDefault(config.DefaultReproviderInterval), cfg.Routing.AcceleratedDHTClient.WithDefault(config.DefaultAcceleratedDHTClient), + int(cfg.Provider.WorkerCount.WithDefault(config.DefaultProviderWorkerCount)), ), ) } diff --git a/core/node/provider.go b/core/node/provider.go index 4638aad4dc5..d0081eb0aec 100644 --- a/core/node/provider.go +++ b/core/node/provider.go @@ -21,12 +21,13 @@ import ( // and in 'ipfs stats provide' report. const sampledBatchSize = 1000 -func ProviderSys(reprovideInterval time.Duration, acceleratedDHTClient bool) fx.Option { +func ProviderSys(reprovideInterval time.Duration, acceleratedDHTClient bool, provideWorkerCount int) fx.Option { 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), + provider.ProvideWorkerCount(provideWorkerCount), } if !acceleratedDHTClient && reprovideInterval > 0 { // The estimation kinda suck if you are running with accelerated DHT client, @@ -131,7 +132,7 @@ https://github.com/ipfs/kubo/blob/master/docs/config.md#routingaccelerateddhtcli // ONLINE/OFFLINE // OnlineProviders groups units managing provider routing records online -func OnlineProviders(useStrategicProviding bool, reprovideStrategy string, reprovideInterval time.Duration, acceleratedDHTClient bool) fx.Option { +func OnlineProviders(useStrategicProviding bool, reprovideStrategy string, reprovideInterval time.Duration, acceleratedDHTClient bool, provideWorkerCount int) fx.Option { if useStrategicProviding { return OfflineProviders() } @@ -146,7 +147,7 @@ func OnlineProviders(useStrategicProviding bool, reprovideStrategy string, repro return fx.Options( keyProvider, - ProviderSys(reprovideInterval, acceleratedDHTClient), + ProviderSys(reprovideInterval, acceleratedDHTClient, provideWorkerCount), ) } @@ -169,7 +170,6 @@ func mfsProvider(mfsRoot *mfs.Root, fetcher fetcher.Factory) provider.KeyChanFun kcf := provider.NewDAGProvider(rootNode.Cid(), fetcher) return kcf(ctx) } - } func mfsRootProvider(mfsRoot *mfs.Root) provider.KeyChanFunc { diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index d383fafad26..e20d4759cb0 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -17,6 +17,8 @@ This release was brought to you by the [Shipyard](http://ipshipyard.com/) team. - [New `ipfs add` Options](#new-ipfs-add-options) - [Persistent `Import.*` Configuration](#persistent-import-configuration) - [Updated Configuration Profiles](#updated-configuration-profiles) + - [Optimized, dedicated queue for providing fresh CIDs](#optimized-dedicated-queue-for-providing-fresh-cids) + - [Deprecated `ipfs stats provider`](#deprecated-ipfs-stats-provider) - [πŸ“¦οΈ Important dependency updates](#-important-dependency-updates) - [πŸ“ Changelog](#-changelog) - [πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors](#-contributors) @@ -81,6 +83,36 @@ The release updated configuration [profiles](https://github.com/ipfs/kubo/blob/m > [!TIP] > Apply one of CIDv1 test [profiles](https://github.com/ipfs/kubo/blob/master/docs/config.md#profiles) with `ipfs config profile apply test-cid-v1[-wide]`. +#### Optimized, dedicated queue for providing fresh CIDs + +From `kubo` [`v0.33.0`](https://github.com/ipfs/kubo/releases/tag/v0.33.0), +Bitswap stopped advertising newly added and received blocks to the DHT. Since +then `boxo/provider` is responsible for the provide and reprovide logic. Prior +to `v0.35.0`, provides and reprovides were handled together in batches, leading +to delays in initial advertisements (provides). + +Provides and Reprovides now have separate queues, allowing for immediate +provide of new CIDs and optimised batching of reprovides. + +This change introduces a new configuration option for limiting the number of +concurrent provide operations: +[`Provider.WorkerCount`](https://github.com/ipfs/kubo/blob/master/docs/config.md#providerworkercount). + +> [!TIP] +> Users who need to provide large volumes of content immediately should consider removing the cap on concurrent provide operations and also set `Routing.AcceleratedDHTClient` to `true`. + +##### Deprecated `ipfs stats provider` + +Since the `ipfs stats provider` command was displaying statistics for both +provides and reprovides, this command isn't relevant anymore after separating +the two queues. + +The successor command is `ipfs stats reprovide`, showing the same statistics, +but for reprovides only. + +> [!NOTE] +> `ipfs stats provider` still works, but is marked as deprecated and will be removed in a future release. Be mindful that the command provides only statistics about reprovides (similar to `ipfs stats reprovide`) and not the new provide queue (this will be fixed as a part of wider refactor planned for a future release). + #### πŸ“¦οΈ Important dependency updates - update `boxo` to [v0.30.0](https://github.com/ipfs/boxo/releases/tag/v0.30.0) diff --git a/docs/config.md b/docs/config.md index 3724487d96b..d812f82714d 100644 --- a/docs/config.md +++ b/docs/config.md @@ -105,6 +105,9 @@ config file at runtime. - [`Pinning.RemoteServices: Policies.MFS.Enabled`](#pinningremoteservices-policiesmfsenabled) - [`Pinning.RemoteServices: Policies.MFS.PinName`](#pinningremoteservices-policiesmfspinname) - [`Pinning.RemoteServices: Policies.MFS.RepinInterval`](#pinningremoteservices-policiesmfsrepininterval) + - [`Provider`](#provider) + - [`Provider.Strategy`](#providerstrategy) + - [`Provider.WorkerCount`](#providerworkercount) - [`Pubsub`](#pubsub) - [`Pubsub.Enabled`](#pubsubenabled) - [`Pubsub.Router`](#pubsubrouter) @@ -207,6 +210,7 @@ config file at runtime. - [`announce-on` profile](#announce-on-profile) - [`legacy-cid-v0` profile](#legacy-cid-v0-profile) - [`test-cid-v1` profile](#test-cid-v1-profile) + - [`test-cid-v1-wide` profile](#test-cid-v1-wide-profile) - [Types](#types) - [`flag`](#flag) - [`priority`](#priority) @@ -1404,6 +1408,39 @@ Default: `"5m"` Type: `duration` +## `Provider` + +Configuration applied to the initial one-time announcement of fresh CIDs +created with `ipfs add`, `ipfs files`, `ipfs dag import`, `ipfs block|dag put` +commands. + +For periodical DHT reprovide settings, see [`Reprovide.*`](#reprovider). + +### `Provider.Strategy` + +Legacy, not used at the moment, see [`Reprovider.Strategy`](#reproviderstrategy) instead. + +### `Provider.WorkerCount` + +Sets the maximum number of _concurrent_ DHT provide operations. DHT reprovides +operations do **not** count against that limit. A value of `0` allows an +unlimited number of provide workers. + +If the [accelerated DHT client](#routingaccelerateddhtclient) is enabled, each +provide operation opens ~20 connections in parallel. With the standard DHT +client (accelerated disabled), each provide opens between 20 and 60 +connections, with at most 10 active at once. Provides complete more quickly +when using the accelerated client. Be mindful of how many simultaneous +connections this setting can generate. + +For nodes without strict connection limits that need to provide large volumes +of content immediately, we recommend enabling the `Routing.AcceleratedDHTClient` and +setting `Provider.WorkerCount` to `0` (unlimited). + +Default: `64` + +Type: `integer` (non-negative; `0` means unlimited number of workers) + ## `Pubsub` **DEPRECATED**: See [#9717](https://github.com/ipfs/kubo/issues/9717) diff --git a/test/sharness/t0002-docker-image.sh b/test/sharness/t0002-docker-image.sh index 8812c277a74..81bb8d4493f 100755 --- a/test/sharness/t0002-docker-image.sh +++ b/test/sharness/t0002-docker-image.sh @@ -36,7 +36,7 @@ test_expect_success "docker image build succeeds" ' ' test_expect_success "write init scripts" ' - echo "ipfs config Provider.Strategy Bar" > 001.sh && + echo "ipfs config Mounts.IPFS Bar" > 001.sh && echo "ipfs config Pubsub.Router Qux" > 002.sh && chmod +x 002.sh ' @@ -65,7 +65,7 @@ test_expect_success "check that init scripts were run correctly and in the corre test_expect_success "check that init script configs were applied" ' echo Bar > expected && - docker exec "$DOC_ID" ipfs config Provider.Strategy > actual && + docker exec "$DOC_ID" ipfs config Mounts.IPFS > actual && test_cmp actual expected && echo Qux > expected && docker exec "$DOC_ID" ipfs config Pubsub.Router > actual && diff --git a/test/sharness/t0070-user-config.sh b/test/sharness/t0070-user-config.sh index 1dc4c0369a0..5a8180c7317 100755 --- a/test/sharness/t0070-user-config.sh +++ b/test/sharness/t0070-user-config.sh @@ -11,12 +11,12 @@ test_description="Test user-provided config values" test_init_ipfs test_expect_success "bootstrap doesn't overwrite user-provided config keys (top-level)" ' - ipfs config Provider.Strategy >previous && - ipfs config Provider.Strategy foo && + ipfs config Identity.PeerID >previous && + ipfs config Identity.PeerID foo && ipfs bootstrap rm --all && echo "foo" >expected && - ipfs config Provider.Strategy >actual && - ipfs config Provider.Strategy $(cat previous) && + ipfs config Identity.PeerID >actual && + ipfs config Identity.PeerID $(cat previous) && test_cmp expected actual ' From 472674fd62ae3f8bd9feb7ff0dda8360dd3f44a3 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Wed, 30 Apr 2025 12:13:56 -0700 Subject: [PATCH 25/42] feat(pebble): support pinning `FormatMajorVersion` (#10789) * Upgrade to pebble v2.0.3 - Configure latest pebble database format at init - Do not automatically ratchet database format if set in config - Daemon messge about new available pebble format - Document pebble config with formatMajorVersion - Add warning to users running badger, nudging them to switch to flatfs or pebble - docs: explain Pebble's `FormatMajorVersion` - Use pebbleds instead of badgerds in t0060-daemon.sh - Print badgerds warning message to stderr --- config/init.go | 6 ++-- docs/changelogs/v0.35.md | 15 ++++++++++ docs/datastores.md | 18 +++++++++-- docs/examples/kubo-as-a-library/go.mod | 10 ++++--- docs/examples/kubo-as-a-library/go.sum | 29 ++++++++++++------ go.mod | 10 ++++--- go.sum | 29 ++++++++++++------ plugin/plugins/badgerds/badgerds.go | 1 + plugin/plugins/pebbleds/pebbleds.go | 11 +++++-- test/dependencies/go.mod | 16 ++++++++++ test/dependencies/go.sum | 41 ++++++++++++++++++++++++++ test/sharness/t0060-daemon.sh | 4 +-- 12 files changed, 154 insertions(+), 36 deletions(-) diff --git a/config/init.go b/config/init.go index a0351bd8b18..c32b53e17a3 100644 --- a/config/init.go +++ b/config/init.go @@ -7,6 +7,7 @@ import ( "io" "time" + "github.com/cockroachdb/pebble/v2" "github.com/ipfs/kubo/core/coreiface/options" "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/peer" @@ -144,8 +145,9 @@ func pebbleSpec() map[string]interface{} { "type": "measure", "prefix": "pebble.datastore", "child": map[string]interface{}{ - "type": "pebbleds", - "path": "pebbleds", + "formatMajorVersion": int(pebble.FormatNewest), + "type": "pebbleds", + "path": "pebbleds", }, } } diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index e20d4759cb0..98a7f2af416 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -19,6 +19,7 @@ This release was brought to you by the [Shipyard](http://ipshipyard.com/) team. - [Updated Configuration Profiles](#updated-configuration-profiles) - [Optimized, dedicated queue for providing fresh CIDs](#optimized-dedicated-queue-for-providing-fresh-cids) - [Deprecated `ipfs stats provider`](#deprecated-ipfs-stats-provider) + - [Pebble Database Format Config](#pebble-database-format-config) - [πŸ“¦οΈ Important dependency updates](#-important-dependency-updates) - [πŸ“ Changelog](#-changelog) - [πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors](#-contributors) @@ -113,10 +114,24 @@ but for reprovides only. > [!NOTE] > `ipfs stats provider` still works, but is marked as deprecated and will be removed in a future release. Be mindful that the command provides only statistics about reprovides (similar to `ipfs stats reprovide`) and not the new provide queue (this will be fixed as a part of wider refactor planned for a future release). +#### Pebble Database Format Config + +This Kubo release provides node operators with more control over [Pebble's `FormatMajorVersion`](https://github.com/cockroachdb/pebble/tree/master?tab=readme-ov-file#format-major-versions). This allows testing a new Kubo release without automatically migrating Pebble datastores, keeping the ability to switch back to older Kubo. + +When IPFS is initialized to use the pebbleds datastore (opt-in via `ipfs init --profile=pebbleds`), the latest pebble database format is configured in the pebble datastore config as `"formatMajorVersion"`. Setting this in the datastore config prevents automatically upgrading to the latest available version when Kubo is upgraded. If a later version becomes available, the Kubo daemon prints a startup message to indicate this. The user can them update the config to use the latest format when they are certain a downgrade will not be necessary. + +Without the `"formatMajorVersion"` in the pebble datastore config, the database format is automatically upgraded to the latest version. If this happens, then it is possible a downgrade back to the previous version of Kubo will not work if new format is not compatible with the pebble datastore in the previous version of Kubo. + +When installing a new version of Kubo when `"formatMajorVersion"` is configured, automatic repository migration (`ipfs daemon with --migrate=true`) does not upgrade this to the latest available version. This is done because a user may have reasons not to upgrade the pebble database format, and may want to be able to downgrade Kubo if something else is not working in the new version. If the configured pebble database format in the old Kubo is not supported in the new Kubo, then the configured version must be updated and the old Kubo run, before installing the new Kubo. + +See other caveats and configuration options at [`kubo/docs/datastores.md#pebbleds`](https://github.com/ipfs/kubo/blob/master/docs/datastores.md#pebbleds) + #### πŸ“¦οΈ Important dependency updates - update `boxo` to [v0.30.0](https://github.com/ipfs/boxo/releases/tag/v0.30.0) - update `ipfs-webui` to [v4.7.0](https://github.com/ipfs/ipfs-webui/releases/tag/v4.7.0) +- update `go-ds-pebble` to [v0.5.0](https://github.com/ipfs/go-ds-pebble/releases/tag/v0.5.0) + - update `pebble` to [v2.0.3](https://github.com/cockroachdb/pebble/releases/tag/v2.0.3) ### πŸ“ Changelog diff --git a/docs/datastores.md b/docs/datastores.md index 039088ac318..f574bc6a5dd 100644 --- a/docs/datastores.md +++ b/docs/datastores.md @@ -46,9 +46,6 @@ Uses a leveldb database to store key value pairs. ## pebbleds -> [!WARNING] -> This is still **EXPERIMENTAL** opt-in. Datastore format can be set when first initializing the node via `ipfs init --profile pebbleds`. - Uses [pebble](https://github.com/cockroachdb/pebble) as a key value store. ```json @@ -64,6 +61,7 @@ If they are not configured (or assigned their zero-valued), then default values * `bytesPerSync`: int, Sync sstables periodically in order to smooth out writes to disk. (default: 512KB) * `disableWAL`: 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) +* `formatVersionMajor`: int, Sets the format of pebble on-disk files. If 0 or unset, automatically convert to latest format. * `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. @@ -76,6 +74,20 @@ If they are not configured (or assigned their zero-valued), then default values > [!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`). +Using a pebble datastore can be set when initializing kubo `ipfs init --profile pebbleds`. + +#### Use of `formatMajorVersion` + +[Pebble's `FormatMajorVersion`](https://github.com/cockroachdb/pebble/tree/master?tab=readme-ov-file#format-major-versions) is a constant controlling the format of persisted data. Backwards incompatible changes to durable formats are gated behind new format major versions. + +At any point, a database's format major version may be bumped. However, once a database's format major version is increased, previous versions of Pebble will refuse to open the database. + +When IPFS is initialized to use the pebbleds datastore (`ipfs init --profile=pebbleds`), the latest pebble database format is configured in the pebble datastore config as `"formatMajorVersion"`. Setting this in the datastore config prevents automatically upgrading to the latest available version when kubo is upgraded. If a later version becomes available, the kubo daemon prints a startup message to indicate this. The user can them update the config to use the latest format when they are certain a downgrade will not be necessary. + +Without the `"formatMajorVersion"` in the pebble datastore config, the database format is automatically upgraded to the latest version. If this happens, then it is possible a downgrade back to the previous version of kubo will not work if new format is not compatible with the pebble datastore in the previous version of kubo. + +When installing a new version of kubo when `"formatMajorVersion"` is configured, migration does not upgrade this to the latest available version. This is done because a user may have reasons not to upgrade the pebble database format, and may want to be able to downgrade kubo if something else is not working in the new version. If the configured pebble database format in the old kubo is not supported in the new kubo, then the configured version must be updated and the old kubo run, before installing the new kubo. + ## 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 27e7df28fa4..e94e45c90c1 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -16,7 +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/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e // indirect github.com/Jorropo/jsync v1.0.1 // indirect github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect @@ -28,11 +28,13 @@ require ( github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/ceramicnetwork/go-dag-jose v0.1.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cockroachdb/crlib v0.0.0-20241015224233-894974b3ad94 // 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.4 // indirect + github.com/cockroachdb/pebble/v2 v2.0.3 // indirect github.com/cockroachdb/redact v1.1.5 // indirect + github.com/cockroachdb/swiss v0.0.0-20250327203710-2932b022f6df // 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 @@ -63,7 +65,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.2.4 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/golang/snappy v0.0.4 // indirect + github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20250208200701-d0013a598941 // indirect github.com/google/uuid v1.6.0 // indirect @@ -85,7 +87,7 @@ require ( github.com/ipfs/go-ds-flatfs v0.5.5 // indirect github.com/ipfs/go-ds-leveldb v0.5.2 // indirect github.com/ipfs/go-ds-measure v0.2.2 // indirect - github.com/ipfs/go-ds-pebble v0.4.4 // indirect + github.com/ipfs/go-ds-pebble v0.5.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 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 76251bf28d8..f2bb38f70c6 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -29,11 +29,13 @@ 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/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e h1:ZIWapoIRN1VqT8GR8jAwb1Ie9GyehWjVcGh32Y2MznE= +github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= 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/aclements/go-perfevent v0.0.0-20240301234650-f7843625020f h1:JjxwchlOepwsUWcQwD2mLUAGE9aCp0/ehy6yCHFBOvo= +github.com/aclements/go-perfevent v0.0.0-20240301234650-f7843625020f/go.mod h1:tMDTce/yLLN/SK8gMOxQfnyeMeCg8KGzp0D1cbECEeo= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= 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= @@ -80,18 +82,24 @@ 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/crlib v0.0.0-20241015224233-894974b3ad94 h1:bvJv505UUfjzbaIPdNS4AEkHreDqQk6yuNpsdRHpwFA= +github.com/cockroachdb/crlib v0.0.0-20241015224233-894974b3ad94/go.mod h1:Gq51ZeKaFCXk6QwuGM0w1dnaOqc/F5zKT2zA9D6Xeac= +github.com/cockroachdb/datadriven v1.0.3-0.20240530155848-7682d40af056 h1:slXychO2uDM6hYRu4c0pD0udNI8uObfeKN6UInWViS8= +github.com/cockroachdb/datadriven v1.0.3-0.20240530155848-7682d40af056/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.4 h1:5II1uEP4MyHLDnsrbv/EZ36arcb9Mxg3n+owhZ3GrG8= -github.com/cockroachdb/pebble v1.1.4/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/metamorphic v0.0.0-20231108215700-4ba948b56895 h1:XANOgPYtvELQ/h4IrmPAohXqe2pWA8Bwhejr3VQoZsA= +github.com/cockroachdb/metamorphic v0.0.0-20231108215700-4ba948b56895/go.mod h1:aPd7gM9ov9M8v32Yy5NJrDyOcD8z642dqs+F0CeNXfA= +github.com/cockroachdb/pebble/v2 v2.0.3 h1:YJ3Sc9jRN/q6OOCNyRHPbcpenbxL1DdgdpUqPlPus6o= +github.com/cockroachdb/pebble/v2 v2.0.3/go.mod h1:NgxgNcWwyG/uxkLUZGM2aelshaLIZvc0hCX7SCfaO8s= 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/swiss v0.0.0-20250327203710-2932b022f6df h1:GUJ4KuZtbOcIfRlprHJFFvIqQ4irtQUl+1fJr+yNmPI= +github.com/cockroachdb/swiss v0.0.0-20250327203710-2932b022f6df/go.mod h1:yBRu/cnL4ks9bgy4vAASdjIW+/xMlFwuHKqtmh3GZQg= 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= @@ -172,6 +180,8 @@ github.com/gammazero/deque v1.0.0 h1:LTmimT8H7bXkkCy6gZX7zNLtkbz4NdS2z8LZuor3j34 github.com/gammazero/deque v1.0.0/go.mod h1:iflpYvtGfM3U8S8j+sZEKIak3SAKYpA5/SQewgfXDKo= 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/ghemawat/stream v0.0.0-20171120220530-696b145b53b9 h1:r5GgOLGbza2wVHRzK7aAj6lWZjfbAwiu/RDCVOKjRyM= +github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs= 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= @@ -231,8 +241,9 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu 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= +github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e h1:4bw4WeyTYPp0smaXiJZCNnLrvVBqirQVreixayXezGc= +github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e/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= @@ -332,8 +343,8 @@ github.com/ipfs/go-ds-leveldb v0.5.2 h1:6nmxlQ2zbp4LCNdJVsmHfs9GP0eylfBNxpmY1csp github.com/ipfs/go-ds-leveldb v0.5.2/go.mod h1:2fAwmcvD3WoRT72PzEekHBkQmBDhc39DJGoREiuGmYo= github.com/ipfs/go-ds-measure v0.2.2 h1:4kwvBGbbSXNYe4ANlg7qTIYoZU6mNlqzQHdVqICkqGI= github.com/ipfs/go-ds-measure v0.2.2/go.mod h1:b/87ak0jMgH9Ylt7oH0+XGy4P8jHx9KG09Qz+pOeTIs= -github.com/ipfs/go-ds-pebble v0.4.4 h1:V/QlTCjQ4cTYQUvDRbDBKVZNYaMi4QV7Du4acPoRvg0= -github.com/ipfs/go-ds-pebble v0.4.4/go.mod h1:a4F6QyaamnD/MsgQH1KpYf5s0YvPODw6eOk9PBhLQMg= +github.com/ipfs/go-ds-pebble v0.5.0 h1:lXffYCAKVD7nLLPqwJ9D8IxgO7Kz8woiX021tezdsIM= +github.com/ipfs/go-ds-pebble v0.5.0/go.mod h1:aiCRVcj3K60sxc6k5C+HO9C6rouqiSkjR/WKnbTcMfQ= 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= diff --git a/go.mod b/go.mod index c6342a48de7..3d86274d053 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/cenkalti/backoff/v4 v4.3.0 github.com/ceramicnetwork/go-dag-jose v0.1.1 github.com/cheggaaa/pb v1.0.29 - github.com/cockroachdb/pebble v1.1.4 + github.com/cockroachdb/pebble/v2 v2.0.3 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 @@ -31,7 +31,7 @@ require ( github.com/ipfs/go-ds-flatfs v0.5.5 github.com/ipfs/go-ds-leveldb v0.5.2 github.com/ipfs/go-ds-measure v0.2.2 - github.com/ipfs/go-ds-pebble v0.4.4 + github.com/ipfs/go-ds-pebble v0.5.0 github.com/ipfs/go-fs-lock v0.0.7 github.com/ipfs/go-ipfs-cmds v0.14.1 github.com/ipfs/go-ipld-cbor v0.2.0 @@ -97,7 +97,7 @@ require ( require ( github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect - github.com/DataDog/zstd v1.4.5 // indirect + github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e // indirect github.com/Jorropo/jsync v1.0.1 // indirect github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect @@ -105,10 +105,12 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/caddyserver/zerossl v0.1.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cockroachdb/crlib v0.0.0-20241015224233-894974b3ad94 // 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/swiss v0.0.0-20250327203710-2932b022f6df // 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-20241020182519-7843d2ba8fdf // indirect @@ -139,7 +141,7 @@ require ( github.com/golang/glog v1.2.4 // 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/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20250208200701-d0013a598941 // indirect github.com/gorilla/mux v1.8.1 // indirect diff --git a/go.sum b/go.sum index 313d66cac01..46350b8e30b 100644 --- a/go.sum +++ b/go.sum @@ -47,11 +47,13 @@ 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/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e h1:ZIWapoIRN1VqT8GR8jAwb1Ie9GyehWjVcGh32Y2MznE= +github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= 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/aclements/go-perfevent v0.0.0-20240301234650-f7843625020f h1:JjxwchlOepwsUWcQwD2mLUAGE9aCp0/ehy6yCHFBOvo= +github.com/aclements/go-perfevent v0.0.0-20240301234650-f7843625020f/go.mod h1:tMDTce/yLLN/SK8gMOxQfnyeMeCg8KGzp0D1cbECEeo= 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= @@ -108,18 +110,24 @@ 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/crlib v0.0.0-20241015224233-894974b3ad94 h1:bvJv505UUfjzbaIPdNS4AEkHreDqQk6yuNpsdRHpwFA= +github.com/cockroachdb/crlib v0.0.0-20241015224233-894974b3ad94/go.mod h1:Gq51ZeKaFCXk6QwuGM0w1dnaOqc/F5zKT2zA9D6Xeac= +github.com/cockroachdb/datadriven v1.0.3-0.20240530155848-7682d40af056 h1:slXychO2uDM6hYRu4c0pD0udNI8uObfeKN6UInWViS8= +github.com/cockroachdb/datadriven v1.0.3-0.20240530155848-7682d40af056/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.4 h1:5II1uEP4MyHLDnsrbv/EZ36arcb9Mxg3n+owhZ3GrG8= -github.com/cockroachdb/pebble v1.1.4/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/metamorphic v0.0.0-20231108215700-4ba948b56895 h1:XANOgPYtvELQ/h4IrmPAohXqe2pWA8Bwhejr3VQoZsA= +github.com/cockroachdb/metamorphic v0.0.0-20231108215700-4ba948b56895/go.mod h1:aPd7gM9ov9M8v32Yy5NJrDyOcD8z642dqs+F0CeNXfA= +github.com/cockroachdb/pebble/v2 v2.0.3 h1:YJ3Sc9jRN/q6OOCNyRHPbcpenbxL1DdgdpUqPlPus6o= +github.com/cockroachdb/pebble/v2 v2.0.3/go.mod h1:NgxgNcWwyG/uxkLUZGM2aelshaLIZvc0hCX7SCfaO8s= 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/swiss v0.0.0-20250327203710-2932b022f6df h1:GUJ4KuZtbOcIfRlprHJFFvIqQ4irtQUl+1fJr+yNmPI= +github.com/cockroachdb/swiss v0.0.0-20250327203710-2932b022f6df/go.mod h1:yBRu/cnL4ks9bgy4vAASdjIW+/xMlFwuHKqtmh3GZQg= 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= @@ -206,6 +214,8 @@ github.com/gammazero/deque v1.0.0 h1:LTmimT8H7bXkkCy6gZX7zNLtkbz4NdS2z8LZuor3j34 github.com/gammazero/deque v1.0.0/go.mod h1:iflpYvtGfM3U8S8j+sZEKIak3SAKYpA5/SQewgfXDKo= 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/ghemawat/stream v0.0.0-20171120220530-696b145b53b9 h1:r5GgOLGbza2wVHRzK7aAj6lWZjfbAwiu/RDCVOKjRyM= +github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs= 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= @@ -284,8 +294,9 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu 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= +github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e h1:4bw4WeyTYPp0smaXiJZCNnLrvVBqirQVreixayXezGc= +github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e/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= @@ -396,8 +407,8 @@ github.com/ipfs/go-ds-leveldb v0.5.2 h1:6nmxlQ2zbp4LCNdJVsmHfs9GP0eylfBNxpmY1csp github.com/ipfs/go-ds-leveldb v0.5.2/go.mod h1:2fAwmcvD3WoRT72PzEekHBkQmBDhc39DJGoREiuGmYo= github.com/ipfs/go-ds-measure v0.2.2 h1:4kwvBGbbSXNYe4ANlg7qTIYoZU6mNlqzQHdVqICkqGI= github.com/ipfs/go-ds-measure v0.2.2/go.mod h1:b/87ak0jMgH9Ylt7oH0+XGy4P8jHx9KG09Qz+pOeTIs= -github.com/ipfs/go-ds-pebble v0.4.4 h1:V/QlTCjQ4cTYQUvDRbDBKVZNYaMi4QV7Du4acPoRvg0= -github.com/ipfs/go-ds-pebble v0.4.4/go.mod h1:a4F6QyaamnD/MsgQH1KpYf5s0YvPODw6eOk9PBhLQMg= +github.com/ipfs/go-ds-pebble v0.5.0 h1:lXffYCAKVD7nLLPqwJ9D8IxgO7Kz8woiX021tezdsIM= +github.com/ipfs/go-ds-pebble v0.5.0/go.mod h1:aiCRVcj3K60sxc6k5C+HO9C6rouqiSkjR/WKnbTcMfQ= 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= diff --git a/plugin/plugins/badgerds/badgerds.go b/plugin/plugins/badgerds/badgerds.go index 5f5781f8fc3..2410f196c60 100644 --- a/plugin/plugins/badgerds/badgerds.go +++ b/plugin/plugins/badgerds/badgerds.go @@ -108,6 +108,7 @@ func (c *datastoreConfig) DiskSpec() fsrepo.DiskSpec { } func (c *datastoreConfig) Create(path string) (repo.Datastore, error) { + fmt.Fprintln(os.Stderr, "⚠️ badgerds is based on badger 1.x, which has known bugs and is no longer supported by the upstream team. Please switch to a newer datastore such as pebbleds or flatfs.") p := c.path if !filepath.IsAbs(p) { p = filepath.Join(path, p) diff --git a/plugin/plugins/pebbleds/pebbleds.go b/plugin/plugins/pebbleds/pebbleds.go index 13287a5f34d..fab1cc16a88 100644 --- a/plugin/plugins/pebbleds/pebbleds.go +++ b/plugin/plugins/pebbleds/pebbleds.go @@ -5,7 +5,7 @@ import ( "path/filepath" "time" - "github.com/cockroachdb/pebble" + "github.com/cockroachdb/pebble/v2" pebbleds "github.com/ipfs/go-ds-pebble" "github.com/ipfs/kubo/misc/fsutil" "github.com/ipfs/kubo/plugin" @@ -110,10 +110,15 @@ func (*pebbledsPlugin) DatastoreConfigParser() fsrepo.ConfigFromMap { return nil, err } - // Use latest version by default. This will ensure that format is - // compatible across database upgrades. if formatMajorVersion == 0 { + // Pebble DB format not configured. Automatically ratchet the + // database to the latest format. This may prevent downgrade. formatMajorVersion = pebble.FormatNewest + } else if formatMajorVersion < pebble.FormatNewest { + // Pebble DB format is configured, but is not the latest. + fmt.Println("⚠️ A newer pebble db format is available.") + fmt.Println(" To upgrade, set the following in the pebble datastore config:") + fmt.Println(" \"formatMajorVersion\":", int(pebble.FormatNewest)) } if bytesPerSync != 0 || disableWAL || formatMajorVersion != 0 || l0CompactionThreshold != 0 || l0StopWritesThreshold != 0 || lBaseMaxBytes != 0 || maxConcurrentCompactions != 0 || memTableSize != 0 || memTableStopWritesThreshold != 0 || walBytesPerSync != 0 || walMinSyncSec != 0 { diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index bfcb2a5e6c1..1c617ef835d 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -28,6 +28,7 @@ require ( 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/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e // 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 @@ -57,6 +58,14 @@ 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/cockroachdb/crlib v0.0.0-20241015224233-894974b3ad94 // 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/v2 v2.0.3 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect + github.com/cockroachdb/swiss v0.0.0-20250327203710-2932b022f6df // indirect + github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/crackcomm/go-gitignore v0.0.0-20241020182519-7843d2ba8fdf // indirect github.com/curioswitch/go-reassign v0.2.0 // indirect @@ -76,6 +85,7 @@ require ( github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect github.com/gammazero/deque v1.0.0 // indirect + github.com/getsentry/sentry-go v0.27.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 @@ -92,6 +102,8 @@ require ( github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/gofrs/flock v0.12.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e // indirect github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect github.com/golangci/gofmt v0.0.0-20240816233607-d8596aa466a9 // indirect github.com/golangci/misspell v0.6.0 // indirect @@ -143,6 +155,8 @@ require ( github.com/klauspost/compress v1.18.0 // indirect github.com/klauspost/cpuid/v2 v2.2.10 // indirect github.com/koron/go-ssdp v0.0.5 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // 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 @@ -217,6 +231,7 @@ require ( github.com/pion/transport/v3 v3.0.7 // indirect github.com/pion/turn/v4 v4.0.0 // indirect github.com/pion/webrtc/v4 v4.0.10 // 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 @@ -233,6 +248,7 @@ require ( github.com/quic-go/quic-go v0.50.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/rogpeppe/go-internal v1.13.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryancurrah/gomodguard v1.3.3 // indirect github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 1b4a496128f..5b5eb3a4591 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -27,6 +27,8 @@ github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/k 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/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e h1:ZIWapoIRN1VqT8GR8jAwb1Ie9GyehWjVcGh32Y2MznE= +github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= 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= @@ -37,6 +39,8 @@ github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0 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/aclements/go-perfevent v0.0.0-20240301234650-f7843625020f h1:JjxwchlOepwsUWcQwD2mLUAGE9aCp0/ehy6yCHFBOvo= +github.com/aclements/go-perfevent v0.0.0-20240301234650-f7843625020f/go.mod h1:tMDTce/yLLN/SK8gMOxQfnyeMeCg8KGzp0D1cbECEeo= 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= @@ -97,6 +101,26 @@ github.com/chavacava/garif v0.1.0/go.mod h1:XMyYCkEL58DF0oyW4qDjjnPWONs2HBqYKI+U 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/cockroachdb/crlib v0.0.0-20241015224233-894974b3ad94 h1:bvJv505UUfjzbaIPdNS4AEkHreDqQk6yuNpsdRHpwFA= +github.com/cockroachdb/crlib v0.0.0-20241015224233-894974b3ad94/go.mod h1:Gq51ZeKaFCXk6QwuGM0w1dnaOqc/F5zKT2zA9D6Xeac= +github.com/cockroachdb/datadriven v1.0.3-0.20240530155848-7682d40af056 h1:slXychO2uDM6hYRu4c0pD0udNI8uObfeKN6UInWViS8= +github.com/cockroachdb/datadriven v1.0.3-0.20240530155848-7682d40af056/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/metamorphic v0.0.0-20231108215700-4ba948b56895 h1:XANOgPYtvELQ/h4IrmPAohXqe2pWA8Bwhejr3VQoZsA= +github.com/cockroachdb/metamorphic v0.0.0-20231108215700-4ba948b56895/go.mod h1:aPd7gM9ov9M8v32Yy5NJrDyOcD8z642dqs+F0CeNXfA= +github.com/cockroachdb/pebble/v2 v2.0.3 h1:YJ3Sc9jRN/q6OOCNyRHPbcpenbxL1DdgdpUqPlPus6o= +github.com/cockroachdb/pebble/v2 v2.0.3/go.mod h1:NgxgNcWwyG/uxkLUZGM2aelshaLIZvc0hCX7SCfaO8s= +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/swiss v0.0.0-20250327203710-2932b022f6df h1:GUJ4KuZtbOcIfRlprHJFFvIqQ4irtQUl+1fJr+yNmPI= +github.com/cockroachdb/swiss v0.0.0-20250327203710-2932b022f6df/go.mod h1:yBRu/cnL4ks9bgy4vAASdjIW+/xMlFwuHKqtmh3GZQg= +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 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= @@ -109,6 +133,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 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= github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= @@ -164,6 +189,10 @@ github.com/gammazero/chanqueue v1.1.0 h1:yiwtloc1azhgGLFo2gMloJtQvkYD936Ai7tBfa+ github.com/gammazero/chanqueue v1.1.0/go.mod h1:fMwpwEiuUgpab0sH4VHiVcEoji1pSi+EIzeG4TPeKPc= github.com/gammazero/deque v1.0.0 h1:LTmimT8H7bXkkCy6gZX7zNLtkbz4NdS2z8LZuor3j34= github.com/gammazero/deque v1.0.0/go.mod h1:iflpYvtGfM3U8S8j+sZEKIak3SAKYpA5/SQewgfXDKo= +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/ghemawat/stream v0.0.0-20171120220530-696b145b53b9 h1:r5GgOLGbza2wVHRzK7aAj6lWZjfbAwiu/RDCVOKjRyM= +github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs= 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= @@ -171,6 +200,8 @@ github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aev 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-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= 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= @@ -219,6 +250,8 @@ 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/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/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e h1:4bw4WeyTYPp0smaXiJZCNnLrvVBqirQVreixayXezGc= +github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 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-20240816233607-d8596aa466a9 h1:/1322Qns6BtQxUZDTAT4SdcoxknUki7IAoK4SAXr8ME= @@ -363,6 +396,7 @@ 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.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= @@ -539,6 +573,8 @@ 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/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.10 h1:ly0Q26K1i6ZkGf42W7D4hQYR90pZwzFOjTq5AuCKk4o= github.com/pion/datachannel v1.5.10/go.mod h1:p/jJfC9arb29W7WrxyKbepTU20CFgyx5oLo8Rs4Py/M= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= @@ -581,6 +617,7 @@ github.com/pion/turn/v4 v4.0.0 h1:qxplo3Rxa9Yg1xXDxxH8xaqcyGUtbHYw4QSCvmFWvhM= github.com/pion/turn/v4 v4.0.0/go.mod h1:MuPDkm15nYSklKpN8vWJ9W2M0PlyQZqYt1McGuxG7mA= github.com/pion/webrtc/v4 v4.0.10 h1:Hq/JLjhqLxi+NmCtE8lnRPDr8H4LcNvwg8OxVcdv56Q= github.com/pion/webrtc/v4 v4.0.10/go.mod h1:ViHLVaNpiuvaH8pdiuQxuA9awuE6KVzAXx3vVWilOck= +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= @@ -626,6 +663,7 @@ 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.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= 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= @@ -782,6 +820,7 @@ github.com/yeya24/promlinter v0.3.0/go.mod h1:cDfJQQYv9uYciW60QT0eeHlFodotkYZlL+ 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= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= @@ -1027,9 +1066,11 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 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-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-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/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-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= diff --git a/test/sharness/t0060-daemon.sh b/test/sharness/t0060-daemon.sh index 2a25f5852ab..45788da55d1 100755 --- a/test/sharness/t0060-daemon.sh +++ b/test/sharness/t0060-daemon.sh @@ -9,7 +9,7 @@ test_description="Test daemon command" . lib/test-lib.sh test_expect_success "create badger config" ' - ipfs init --profile=badgerds,test > /dev/null && + ipfs init --profile=pebbleds,test > /dev/null && cp "$IPFS_PATH/config" init-config ' @@ -22,7 +22,7 @@ test_kill_ipfs_daemon test_expect_success "daemon initialization with existing config works" ' ipfs config "Datastore.Spec.child.path" >actual && - test $(cat actual) = "badgerds" && + test $(cat actual) = "pebbleds" && ipfs config Addresses > orig_addrs ' From de168619a5f2fc29c0a19e8af8678d8935393395 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Wed, 30 Apr 2025 12:15:55 -0700 Subject: [PATCH 26/42] feat(pebble): support pinning `FormatMajorVersion` (#10789) * Upgrade to pebble v2.0.3 - Configure latest pebble database format at init - Do not automatically ratchet database format if set in config - Daemon messge about new available pebble format - Document pebble config with formatMajorVersion - Add warning to users running badger, nudging them to switch to flatfs or pebble - docs: explain Pebble's `FormatMajorVersion` - Use pebbleds instead of badgerds in t0060-daemon.sh - Print badgerds warning message to stderr From b3973fa016c3a12d6f866e6c8c538c94a6fe5a8a Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Wed, 30 Apr 2025 13:01:24 -0700 Subject: [PATCH 27/42] refactor: make datastore metrics opt-in (#10788) * datastore: metrics optional and off by default When ipfs is initialized, the datastore metrics wrapper is not configured by default as it previously was. To enable datastore metrics during initialization, specifying the appropriate `--profile` option. To enable datastore metrics tracking wrapper, initialize with datastore profile name + "-measure" suffix. For example: ``` ipfs init --profile flatfs-measure ``` Closes #10767 * fix sharness tests for new datastore dafaults * Add sharness test to check metrics added by flatfs-measure profile * Document updated metrics in changelog * update config doc with new profiles * docs(changelog): separate section * initialize non-measure pebbleds with FormatMajorVersion config * docs: fix typos, add docs link --------- Co-authored-by: gammazero Co-authored-by: Marcin Rataj --- config/init.go | 42 +++++ config/profile.go | 42 +++++ docs/changelogs/v0.35.md | 14 +- docs/config.md | 41 ++++- test/sharness/lib/test-lib.sh | 21 +++ test/sharness/t0060-daemon.sh | 4 +- .../t0119-prometheus-data/prometheus_metrics | 158 ------------------ ...rometheus_metrics_added_by_measure_profile | 158 ++++++++++++++++++ test/sharness/t0119-prometheus.sh | 24 +++ 9 files changed, 341 insertions(+), 163 deletions(-) create mode 100644 test/sharness/t0119-prometheus-data/prometheus_metrics_added_by_measure_profile diff --git a/config/init.go b/config/init.go index c32b53e17a3..1da876313f6 100644 --- a/config/init.go +++ b/config/init.go @@ -141,6 +141,15 @@ func DefaultDatastoreConfig() Datastore { } func pebbleSpec() map[string]interface{} { + return map[string]interface{}{ + "type": "pebbleds", + "prefix": "pebble.datastore", + "path": "pebbleds", + "formatMajorVersion": int(pebble.FormatNewest), + } +} + +func pebbleSpecMeasure() map[string]interface{} { return map[string]interface{}{ "type": "measure", "prefix": "pebble.datastore", @@ -153,6 +162,16 @@ func pebbleSpec() map[string]interface{} { } func badgerSpec() map[string]interface{} { + return map[string]interface{}{ + "type": "badgerds", + "prefix": "badger.datastore", + "path": "badgerds", + "syncWrites": false, + "truncate": true, + } +} + +func badgerSpecMeasure() map[string]interface{} { return map[string]interface{}{ "type": "measure", "prefix": "badger.datastore", @@ -166,6 +185,29 @@ func badgerSpec() map[string]interface{} { } func flatfsSpec() map[string]interface{} { + return map[string]interface{}{ + "type": "mount", + "mounts": []interface{}{ + map[string]interface{}{ + "mountpoint": "/blocks", + "type": "flatfs", + "prefix": "flatfs.datastore", + "path": "blocks", + "sync": false, + "shardFunc": "/repo/flatfs/shard/v1/next-to-last/2", + }, + map[string]interface{}{ + "mountpoint": "/", + "type": "levelds", + "prefix": "leveldb.datastore", + "path": "datastore", + "compression": "none", + }, + }, + } +} + +func flatfsSpecMeasure() map[string]interface{} { return map[string]interface{}{ "type": "mount", "mounts": []interface{}{ diff --git a/config/profile.go b/config/profile.go index a26d74f99a5..605af355529 100644 --- a/config/profile.go +++ b/config/profile.go @@ -150,6 +150,20 @@ NOTE: This profile may only be applied when first initializing node at IPFS_PATH return nil }, }, + "flatfs-measure": { + Description: `Configures the node to use the flatfs datastore with metrics tracking wrapper. +Additional '*_datastore_*' metrics will be exposed on /debug/metrics/prometheus + +NOTE: This profile may only be applied when first initializing node at IPFS_PATH + via 'ipfs init --profile flatfs-measure' +`, + + InitOnly: true, + Transform: func(c *Config) error { + c.Datastore.Spec = flatfsSpecMeasure() + return nil + }, + }, "pebbleds": { Description: `Configures the node to use the pebble high-performance datastore. @@ -176,6 +190,20 @@ NOTE: This profile may only be applied when first initializing node at IPFS_PATH return nil }, }, + "pebbleds-measure": { + Description: `Configures the node to use the pebble datastore with metrics tracking wrapper. +Additional '*_datastore_*' metrics will be exposed on /debug/metrics/prometheus + +NOTE: This profile may only be applied when first initializing node at IPFS_PATH + via 'ipfs init --profile pebbleds-measure' +`, + + InitOnly: true, + Transform: func(c *Config) error { + c.Datastore.Spec = pebbleSpecMeasure() + return nil + }, + }, "badgerds": { Description: `Configures the node to use the legacy badgerv1 datastore. @@ -205,6 +233,20 @@ NOTE: This profile may only be applied when first initializing node at IPFS_PATH return nil }, }, + "badgerds-measure": { + Description: `Configures the node to use the legacy badgerv1 datastore with metrics wrapper. +Additional '*_datastore_*' metrics will be exposed on /debug/metrics/prometheus + +NOTE: This profile may only be applied when first initializing node at IPFS_PATH + via 'ipfs init --profile badgerds-measure' +`, + + InitOnly: true, + Transform: func(c *Config) error { + c.Datastore.Spec = badgerSpecMeasure() + return nil + }, + }, "lowpower": { Description: `Reduces daemon overhead on the system. May affect node functionality - performance of content discovery and data diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index 98a7f2af416..825d536fa6c 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -16,7 +16,8 @@ This release was brought to you by the [Shipyard](http://ipshipyard.com/) team. - [Enhanced DAG-Shaping Controls for `ipfs add`](#enhanced-dag-shaping-controls-for-ipfs-add) - [New `ipfs add` Options](#new-ipfs-add-options) - [Persistent `Import.*` Configuration](#persistent-import-configuration) - - [Updated Configuration Profiles](#updated-configuration-profiles) + - [Updated `Import` Profiles](#updated-import-profiles) + - [`Datastore` Metrics Now Opt-In](#datastore-metrics-now-opt-in) - [Optimized, dedicated queue for providing fresh CIDs](#optimized-dedicated-queue-for-providing-fresh-cids) - [Deprecated `ipfs stats provider`](#deprecated-ipfs-stats-provider) - [Pebble Database Format Config](#pebble-database-format-config) @@ -74,7 +75,7 @@ You can set default values for these options using the following configuration s - [`Import.UnixFSHAMTDirectoryMaxFanout`](https://github.com/ipfs/kubo/blob/master/docs/config.md#importunixfshamtdirectorymaxfanout) - [`Import.UnixFSHAMTDirectorySizeThreshold`](https://github.com/ipfs/kubo/blob/master/docs/config.md#importunixfshamtdirectorysizethreshold) -##### Updated Configuration Profiles +##### Updated `Import` Profiles The release updated configuration [profiles](https://github.com/ipfs/kubo/blob/master/docs/config.md#profiles) to incorporate these new `Import.*` settings: - Updated Profile: `test-cid-v1` now includes current defaults as explicit `Import.UnixFSFileMaxLinks=174`, `Import.UnixFSDirectoryMaxLinks=0`, `Import.UnixFSHAMTDirectoryMaxFanout=256` and `Import.UnixFSHAMTDirectorySizeThreshold=256KiB` @@ -84,6 +85,15 @@ The release updated configuration [profiles](https://github.com/ipfs/kubo/blob/m > [!TIP] > Apply one of CIDv1 test [profiles](https://github.com/ipfs/kubo/blob/master/docs/config.md#profiles) with `ipfs config profile apply test-cid-v1[-wide]`. +#### `Datastore` Metrics Now Opt-In + +To reduce overhead in the default configuration, datastore metrics are no longer enabled by default when initializing a Kubo repository with `ipfs init`. +Metrics prefixed with `_datastore` (e.g., `flatfs_datastore_...`, `leveldb_datastore_...`) are not exposed unless explicitly enabled. For a complete list of affected default metrics, refer to [`prometheus_metrics_added_by_measure_profile`](https://github.com/ipfs/kubo/blob/master/test/sharness/t0119-prometheus-data/prometheus_metrics_added_by_measure_profile). + +Convenience opt-in [profiles](https://github.com/ipfs/kubo/blob/master/docs/config.md#profiles) can be enabled at initialization time with `ipfs init --profile`: `flatfs-measure`, `pebbleds-measure`, `badgerds-measure` + +It is also possible to manually add the `measure` wrapper. See examples in [`Datastore.Spec`](https://github.com/ipfs/kubo/blob/master/docs/config.md#datastorespec) documentation. + #### Optimized, dedicated queue for providing fresh CIDs From `kubo` [`v0.33.0`](https://github.com/ipfs/kubo/releases/tag/v0.33.0), diff --git a/docs/config.md b/docs/config.md index d812f82714d..504597aa298 100644 --- a/docs/config.md +++ b/docs/config.md @@ -203,8 +203,11 @@ config file at runtime. - [`local-discovery` profile](#local-discovery-profile) - [`default-networking` profile](#default-networking-profile) - [`flatfs` profile](#flatfs-profile) + - [`flatfs-measure` profile](#flatfs-measure-profile) - [`pebbleds` profile](#pebbleds-profile) + - [`pebbleds-measure` profile](#pebbleds-measure-profile) - [`badgerds` profile](#badgerds-profile) + - [`badgerds-measure` profile](#badgerds-measure-profile) - [`lowpower` profile](#lowpower-profile) - [`announce-off` profile](#announce-off-profile) - [`announce-on` profile](#announce-on-profile) @@ -735,6 +738,30 @@ datastores to provide extra functionality (eg metrics, logging, or caching). Default: ``` +{ + "mounts": [ + { + "mountpoint": "/blocks", + "path": "blocks", + "prefix": "flatfs.datastore", + "shardFunc": "/repo/flatfs/shard/v1/next-to-last/2", + "sync": false, + "type": "flatfs" + }, + { + "compression": "none", + "mountpoint": "/", + "path": "datastore", + "prefix": "leveldb.datastore", + "type": "levelds" + } + ], + "type": "mount" +} +``` + +With `flatfs-measure` profile: +``` { "mounts": [ { @@ -2773,9 +2800,13 @@ You should use this datastore if: > [!NOTE] > See caveats and configuration options at [`datastores.md#flatfs`](datastores.md#flatfs) +### `flatfs-measure` profile + +Configures the node to use the flatfs datastore with metrics. This is the same as [`flatfs` profile](#flatfs-profile) with the addition of the `measure` datastore wrapper. + ### `pebbleds` profile -Configures the node to use the **EXPERIMENTAL** pebble high-performance datastore. +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: @@ -2793,6 +2824,10 @@ You should use this datastore if: > [!NOTE] > See other caveats and configuration options at [`datastores.md#pebbleds`](datastores.md#pebbleds) +### `pebbleds-measure` profile + +Configures the node to use the pebble datastore with metrics. This is the same as [`pebbleds` profile](#pebble-profile) with the addition of the `measure` datastore wrapper. + ### `badgerds` profile Configures the node to use the **legacy** badgerv1 datastore. @@ -2818,6 +2853,10 @@ Also, be aware that: > [!NOTE] > See other caveats and configuration options at [`datastores.md#pebbleds`](datastores.md#pebbleds) +### `badgerds-measure` profile + +Configures the node to use the **legacy** badgerv1 datastore with metrics. This is the same as [`badgerds` profile](#badger-profile) with the addition of the `measure` datastore wrapper. + ### `lowpower` profile Reduces daemon overhead on the system by disabling optional swarm services. diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index e5714d6223b..12a1f71be11 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -214,6 +214,27 @@ test_init_ipfs() { } +test_init_ipfs_measure() { + args=("$@") + + # we set the Addresses.API config variable. + # the cli client knows to use it, so only need to set. + # todo: in the future, use env? + + test_expect_success "ipfs init succeeds" ' + export IPFS_PATH="$(pwd)/.ipfs" && + ipfs init "${args[@]}" --profile=test,flatfs-measure > /dev/null + ' + + test_expect_success "prepare config -- mounting" ' + mkdir mountdir ipfs ipns && + test_config_set Mounts.IPFS "$(pwd)/ipfs" && + test_config_set Mounts.IPNS "$(pwd)/ipns" || + test_fsh cat "\"$IPFS_PATH/config\"" + ' + +} + test_wait_for_file() { loops=$1 delay=$2 diff --git a/test/sharness/t0060-daemon.sh b/test/sharness/t0060-daemon.sh index 45788da55d1..5dbbd852feb 100755 --- a/test/sharness/t0060-daemon.sh +++ b/test/sharness/t0060-daemon.sh @@ -8,7 +8,7 @@ test_description="Test daemon command" . lib/test-lib.sh -test_expect_success "create badger config" ' +test_expect_success "create pebble config" ' ipfs init --profile=pebbleds,test > /dev/null && cp "$IPFS_PATH/config" init-config ' @@ -21,7 +21,7 @@ test_launch_ipfs_daemon --init --init-config="$(pwd)/init-config" --init-profile test_kill_ipfs_daemon test_expect_success "daemon initialization with existing config works" ' - ipfs config "Datastore.Spec.child.path" >actual && + ipfs config "Datastore.Spec.path" >actual && test $(cat actual) = "pebbleds" && ipfs config Addresses > orig_addrs ' diff --git a/test/sharness/t0119-prometheus-data/prometheus_metrics b/test/sharness/t0119-prometheus-data/prometheus_metrics index 07cd44d8f5c..d0900322b28 100644 --- a/test/sharness/t0119-prometheus-data/prometheus_metrics +++ b/test/sharness/t0119-prometheus-data/prometheus_metrics @@ -7,85 +7,6 @@ exchange_bitswap_wantlists_seconds_bucket exchange_bitswap_wantlists_seconds_count exchange_bitswap_wantlists_seconds_sum exchange_bitswap_wantlists_total -flatfs_datastore_batchcommit_errors_total -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_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_count -flatfs_datastore_batchput_latency_seconds_sum -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_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_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_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_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_count -flatfs_datastore_get_latency_seconds_sum -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_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_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_count -flatfs_datastore_put_latency_seconds_sum -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_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_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_count -flatfs_datastore_sync_latency_seconds_sum -flatfs_datastore_sync_total go_gc_duration_seconds go_gc_duration_seconds_count go_gc_duration_seconds_sum @@ -227,85 +148,6 @@ 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_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_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_count -leveldb_datastore_batchput_latency_seconds_sum -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_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_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_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_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_count -leveldb_datastore_get_latency_seconds_sum -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_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_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_count -leveldb_datastore_put_latency_seconds_sum -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_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_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_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 diff --git a/test/sharness/t0119-prometheus-data/prometheus_metrics_added_by_measure_profile b/test/sharness/t0119-prometheus-data/prometheus_metrics_added_by_measure_profile new file mode 100644 index 00000000000..03f132701f6 --- /dev/null +++ b/test/sharness/t0119-prometheus-data/prometheus_metrics_added_by_measure_profile @@ -0,0 +1,158 @@ +flatfs_datastore_batchcommit_errors_total +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_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_count +flatfs_datastore_batchput_latency_seconds_sum +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_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_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_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_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_count +flatfs_datastore_get_latency_seconds_sum +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_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_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_count +flatfs_datastore_put_latency_seconds_sum +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_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_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_count +flatfs_datastore_sync_latency_seconds_sum +flatfs_datastore_sync_total +leveldb_datastore_batchcommit_errors_total +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_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_count +leveldb_datastore_batchput_latency_seconds_sum +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_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_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_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_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_count +leveldb_datastore_get_latency_seconds_sum +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_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_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_count +leveldb_datastore_put_latency_seconds_sum +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_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_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_count +leveldb_datastore_sync_latency_seconds_sum +leveldb_datastore_sync_total diff --git a/test/sharness/t0119-prometheus.sh b/test/sharness/t0119-prometheus.sh index fef204e2312..4daf8281b7c 100755 --- a/test/sharness/t0119-prometheus.sh +++ b/test/sharness/t0119-prometheus.sh @@ -57,4 +57,28 @@ test_expect_success "make sure initial metrics added by setting ResourceMgr.Enab diff -u ../t0119-prometheus-data/prometheus_metrics_added_by_enabling_rcmgr rcmgr_metrics ' +# Reinitialize ipfs with --profile=flatfs-measure and check metrics. + +test_expect_success "remove ipfs directory" ' + rm -rf .ipfs mountdir ipfs ipns +' + +test_init_ipfs_measure + +test_launch_ipfs_daemon + +test_expect_success "collect metrics" ' + curl "$API_ADDR/debug/metrics/prometheus" > raw_metrics +' +test_kill_ipfs_daemon + +test_expect_success "filter metrics and find ones added by enabling flatfs-measure profile" ' + 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 | LC_ALL=C sort | uniq > measure_metrics +' + +test_expect_success "make sure initial metrics added by initializing with flatfs-measure profile haven't changed" ' + diff -u ../t0119-prometheus-data/prometheus_metrics_added_by_measure_profile measure_metrics +' + test_done From e8ff2d59de68b014ffee2c0d741f33612e5af5a3 Mon Sep 17 00:00:00 2001 From: IGP <84940636+gystemd@users.noreply.github.com> Date: Wed, 30 Apr 2025 22:23:51 +0200 Subject: [PATCH 28/42] feat(config): ability to disable Bitswap fully or just server (#10782) * feat: add Bitswap configuration and related tests * fix: update Bitswap function to use 'provide' parameter for server enablement * docs: update changelog for Bitswap functionality changes * fix: update Bitswap server enablement logic and improve related tests * fix: rename BitswapConfig to Bitswap and update references * docs: config and changelog * fix: `ipfs cat` panic when `Bitswap.Enabled=false` Fixes panic described in: https://github.com/ipfs/kubo/pull/10782#discussion_r2069116219 --------- Co-authored-by: gystemd Co-authored-by: gammazero <11790789+gammazero@users.noreply.github.com> Co-authored-by: Giulio Piva Co-authored-by: Marcin Rataj --- config/bitswap.go | 14 ++++ config/config.go | 2 + core/node/bitswap.go | 52 ++++++++++-- core/node/groups.go | 8 +- docs/changelogs/v0.35.md | 4 +- docs/config.md | 34 ++++++++ test/cli/bitswap_config_test.go | 138 ++++++++++++++++++++++++++++++++ 7 files changed, 241 insertions(+), 11 deletions(-) create mode 100644 config/bitswap.go create mode 100644 test/cli/bitswap_config_test.go diff --git a/config/bitswap.go b/config/bitswap.go new file mode 100644 index 00000000000..38c817577a1 --- /dev/null +++ b/config/bitswap.go @@ -0,0 +1,14 @@ +package config + +// Bitswap holds Bitswap configuration options +type Bitswap struct { + // Enabled controls both client and server (enabled by default) + Enabled Flag `json:",omitempty"` + // ServerEnabled controls if the node responds to WANTs (depends on Enabled, enabled by default) + ServerEnabled Flag `json:",omitempty"` +} + +const ( + DefaultBitswapEnabled = true + DefaultBitswapServerEnabled = true +) diff --git a/config/config.go b/config/config.go index 3db7573d06c..68e57e1c3dd 100644 --- a/config/config.go +++ b/config/config.go @@ -42,6 +42,8 @@ type Config struct { Version Version Internal Internal // experimental/unstable options + + Bitswap Bitswap `json:",omitempty"` } const ( diff --git a/core/node/bitswap.go b/core/node/bitswap.go index 2408fe3715e..b69e7f510f0 100644 --- a/core/node/bitswap.go +++ b/core/node/bitswap.go @@ -2,6 +2,7 @@ package node import ( "context" + "io" "time" "github.com/ipfs/boxo/bitswap" @@ -12,12 +13,16 @@ import ( "github.com/ipfs/boxo/exchange/providing" provider "github.com/ipfs/boxo/provider" rpqm "github.com/ipfs/boxo/routing/providerquerymanager" + "github.com/ipfs/go-cid" + "github.com/ipfs/go-datastore" + ipld "github.com/ipfs/go-ipld-format" "github.com/ipfs/kubo/config" irouting "github.com/ipfs/kubo/routing" "github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/routing" "go.uber.org/fx" + blocks "github.com/ipfs/go-block-format" "github.com/ipfs/kubo/core/node/helpers" ) @@ -72,18 +77,21 @@ type bitswapIn struct { } // Bitswap creates the BitSwap server/client instance. -// Additional options to bitswap.New can be provided via the "bitswap-options" -// group. +// If Bitswap.ServerEnabled is false, the node will act only as a client +// using an empty blockstore to prevent serving blocks to other peers. func Bitswap(provide bool) interface{} { return func(in bitswapIn, lc fx.Lifecycle) (*bitswap.Bitswap, error) { bitswapNetwork := bsnet.NewFromIpfsHost(in.Host) - + var blockstoree blockstore.Blockstore = in.Bs var provider routing.ContentDiscovery + if provide { + var maxProviders int = DefaultMaxProviders if in.Cfg.Internal.Bitswap != nil { maxProviders = int(in.Cfg.Internal.Bitswap.ProviderSearchMaxResults.WithDefault(DefaultMaxProviders)) } + pqm, err := rpqm.New(bitswapNetwork, in.Rt, rpqm.WithMaxProviders(maxProviders), @@ -93,10 +101,16 @@ func Bitswap(provide bool) interface{} { return nil, err } in.BitswapOpts = append(in.BitswapOpts, bitswap.WithClientOption(client.WithDefaultProviderQueryManager(false))) + in.BitswapOpts = append(in.BitswapOpts, bitswap.WithServerEnabled(true)) provider = pqm - + } else { + provider = nil + // When server is disabled, use an empty blockstore to prevent serving blocks + blockstoree = blockstore.NewBlockstore(datastore.NewMapDatastore()) + in.BitswapOpts = append(in.BitswapOpts, bitswap.WithServerEnabled(false)) } - bs := bitswap.New(helpers.LifecycleCtx(in.Mctx, lc), bitswapNetwork, provider, in.Bs, in.BitswapOpts...) + + bs := bitswap.New(helpers.LifecycleCtx(in.Mctx, lc), bitswapNetwork, provider, blockstoree, in.BitswapOpts...) lc.Append(fx.Hook{ OnStop: func(ctx context.Context) error { @@ -108,8 +122,12 @@ func Bitswap(provide bool) interface{} { } // OnlineExchange creates new LibP2P backed block exchange. -func OnlineExchange() interface{} { +// Returns a no-op exchange if Bitswap is disabled. +func OnlineExchange(isBitswapActive bool) interface{} { return func(in *bitswap.Bitswap, lc fx.Lifecycle) exchange.Interface { + if !isBitswapActive { + return &noopExchange{closer: in} + } lc.Append(fx.Hook{ OnStop: func(ctx context.Context) error { return in.Close() @@ -144,3 +162,25 @@ func ProvidingExchange(provide bool) interface{} { return exch } } + +type noopExchange struct { + closer io.Closer +} + +func (e *noopExchange) GetBlock(ctx context.Context, c cid.Cid) (blocks.Block, error) { + return nil, ipld.ErrNotFound{Cid: c} +} + +func (e *noopExchange) GetBlocks(ctx context.Context, cids []cid.Cid) (<-chan blocks.Block, error) { + ch := make(chan blocks.Block) + close(ch) + return ch, nil +} + +func (e *noopExchange) NotifyNewBlocks(ctx context.Context, blocks ...blocks.Block) error { + return nil +} + +func (e *noopExchange) Close() error { + return e.closer.Close() +} diff --git a/core/node/groups.go b/core/node/groups.go index 0e28444be95..f82da293fa6 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -335,13 +335,15 @@ func Online(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part recordLifetime = d } - /* don't provide from bitswap when the strategic provider service is active */ - shouldBitswapProvide := !cfg.Experimental.StrategicProviding + isBitswapEnabled := cfg.Bitswap.Enabled.WithDefault(config.DefaultBitswapEnabled) + isBitswapServerEnabled := cfg.Bitswap.ServerEnabled.WithDefault(config.DefaultBitswapServerEnabled) + // Don't provide from bitswap when the strategic provider service is active + shouldBitswapProvide := isBitswapEnabled && isBitswapServerEnabled && !cfg.Experimental.StrategicProviding return fx.Options( fx.Provide(BitswapOptions(cfg)), fx.Provide(Bitswap(shouldBitswapProvide)), - fx.Provide(OnlineExchange()), + fx.Provide(OnlineExchange(isBitswapEnabled)), // Replace our Exchange with a Providing exchange! fx.Decorate(ProvidingExchange(shouldBitswapProvide)), fx.Provide(DNSResolver), diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index 825d536fa6c..07543b24d33 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -41,7 +41,8 @@ See [`Reprovider.Strategy`](https://github.com/ipfs/kubo/blob/master/docs/config #### Additional new configuration options -- [`Internal.Bitswap.ProviderSearchMaxResults`](https://github.com/ipfs/kubo/blob/master/docs/config.md##internalbitswapprovidersearchmaxresults) for adjusting the maximum number of providers bitswap client should aim at before it stops searching for new ones. +- [`Bitswap`](https://github.com/ipfs/kubo/blob/master/docs/config.md#bitswap) section with `Enabled` and `ServerEnabled` flags determine whether Kubo initializes Bitswap, enabling just the client or both the client and server. +- [`Internal.Bitswap.ProviderSearchMaxResults`](https://github.com/ipfs/kubo/blob/master/docs/config.md#internalbitswapprovidersearchmaxresults) for adjusting the maximum number of providers bitswap client should aim at before it stops searching for new ones. - [`Routing.IgnoreProviders`](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingignoreproviders) allows ignoring specific peer IDs when returned by the content routing system as providers of content. #### Grid view in WebUI @@ -144,5 +145,4 @@ See other caveats and configuration options at [`kubo/docs/datastores.md#pebbled - update `pebble` to [v2.0.3](https://github.com/cockroachdb/pebble/releases/tag/v2.0.3) ### πŸ“ Changelog - ### πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors diff --git a/docs/config.md b/docs/config.md index 504597aa298..770155783dd 100644 --- a/docs/config.md +++ b/docs/config.md @@ -36,6 +36,9 @@ config file at runtime. - [`AutoTLS.RegistrationToken`](#autotlsregistrationtoken) - [`AutoTLS.RegistrationDelay`](#autotlsregistrationdelay) - [`AutoTLS.CAEndpoint`](#autotlscaendpoint) + - [`Bitswap`](#bitswap) + - [`Bitswap.Enabled`](#bitswapenabled) + - [`Bitswap.ServerEnabled`](#bitswapserverenabled) - [`Bootstrap`](#bootstrap) - [`Datastore`](#datastore) - [`Datastore.StorageMax`](#datastorestoragemax) @@ -619,6 +622,33 @@ Default: [certmagic.LetsEncryptProductionCA](https://pkg.go.dev/github.com/caddy Type: `optionalString` +## `Bitswap` + +High level client and server configuration of the [Bitswap Protocol](https://specs.ipfs.tech/bitswap-protocol/). + +For internal configuration see [`Internal.Bitswap`](#internalbitswap). + +### `Bitswap.Enabled` + +Manages both Bitswap client and server functionality. For testing or operating a node without Bitswap requirements. + +> [!WARNING] +> Bitswap is a core component of Kubo, and disabling it completely may cause unpredictable outcomes. Treat this as experimental and use it solely for testing purposes. + +Default: `true` + +Type: `flag` + +### `Bitswap.ServerEnabled` + +Determines whether Kubo functions as a Bitswap server to host and respond to block requests. + +Disabling the server retains client and protocol support in libp2p identify responses but causes Kubo to reply with "don't have" to all block requests. + +Default: `true` + +Type: `flag` + ## `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. @@ -1151,6 +1181,10 @@ This section includes internal knobs for various subsystems to allow advanced us ### `Internal.Bitswap` `Internal.Bitswap` contains knobs for tuning bitswap resource utilization. + +> [!TIP] +> For high level configuration see [`Bitswap`](#bitswap). + The knobs (below) document how their value should related to each other. Whether their values should be raised or lowered should be determined based on the metrics `ipfs_bitswap_active_tasks`, `ipfs_bitswap_pending_tasks`, diff --git a/test/cli/bitswap_config_test.go b/test/cli/bitswap_config_test.go new file mode 100644 index 00000000000..19ae3e34dbe --- /dev/null +++ b/test/cli/bitswap_config_test.go @@ -0,0 +1,138 @@ +package cli + +import ( + "testing" + "time" + + "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 TestBitswapConfig(t *testing.T) { + t.Parallel() + + // Create test data that will be shared between nodes + testData := testutils.RandomBytes(100) + + t.Run("server enabled (default)", func(t *testing.T) { + t.Parallel() + h := harness.NewT(t) + provider := h.NewNode().Init().StartDaemon() + requester := h.NewNode().Init().StartDaemon() + + hash := provider.IPFSAddStr(string(testData)) + requester.Connect(provider) + + res := requester.IPFS("cat", hash) + assert.Equal(t, testData, res.Stdout.Bytes(), "retrieved data should match original") + }) + + t.Run("server disabled", func(t *testing.T) { + t.Parallel() + h := harness.NewT(t) + + provider := h.NewNode().Init() + provider.SetIPFSConfig("Bitswap.ServerEnabled", false) + provider = provider.StartDaemon() + + requester := h.NewNode().Init().StartDaemon() + + hash := provider.IPFSAddStr(string(testData)) + requester.Connect(provider) + + // If the data was available, it would be retrieved immediately. + // Therefore, after the timeout, we can assume the data is not available + // i.e. the server is disabled + timeout := time.After(3 * time.Second) + dataChan := make(chan []byte) + + go func() { + res := requester.RunIPFS("cat", hash) + dataChan <- res.Stdout.Bytes() + }() + + select { + case data := <-dataChan: + assert.NotEqual(t, testData, data, "retrieved data should not match original") + case <-timeout: + t.Log("Test passed: operation timed out after 3 seconds as expected") + } + }) + + t.Run("server disabled and client enabled", func(t *testing.T) { + t.Parallel() + h := harness.NewT(t) + + provider := h.NewNode().Init() + provider.SetIPFSConfig("Bitswap.ServerEnabled", false) + provider.StartDaemon() + + requester := h.NewNode().Init().StartDaemon() + hash := requester.IPFSAddStr(string(testData)) + + provider.Connect(requester) + + // Even when the server is disabled, the client should be able to retrieve data + res := provider.RunIPFS("cat", hash) + assert.Equal(t, testData, res.Stdout.Bytes(), "retrieved data should match original") + }) + + t.Run("bitswap completely disabled", func(t *testing.T) { + t.Parallel() + h := harness.NewT(t) + + requester := h.NewNode().Init() + requester.UpdateConfig(func(cfg *config.Config) { + cfg.Bitswap.Enabled = config.False + cfg.Bitswap.ServerEnabled = config.False + }) + requester.StartDaemon() + + provider := h.NewNode().Init().StartDaemon() + hash := provider.IPFSAddStr(string(testData)) + + requester.Connect(provider) + res := requester.RunIPFS("cat", hash) + assert.Equal(t, []byte{}, res.Stdout.Bytes(), "cat should not return any data") + assert.Contains(t, res.Stderr.String(), "Error: ipld: could not find") + + // Verify that basic operations still work with bitswap disabled + res = requester.IPFS("id") + assert.Equal(t, 0, res.ExitCode(), "basic IPFS operations should work") + res = requester.IPFS("bitswap", "stat") + assert.Equal(t, 0, res.ExitCode(), "bitswap stat should work even with bitswap disabled") + res = requester.IPFS("bitswap", "wantlist") + assert.Equal(t, 0, res.ExitCode(), "bitswap wantlist should work even with bitswap disabled") + + // Verify local operations still work + hashNew := requester.IPFSAddStr("random") + res = requester.IPFS("cat", hashNew) + assert.Equal(t, []byte("random"), res.Stdout.Bytes(), "cat should return the added data") + }) + + // TODO: Disabling Bitswap.Enabled should remove /ifps/bitswap* protocols from `ipfs id` + // t.Run("bitswap protocols disabled", func(t *testing.T) { + // t.Parallel() + // harness.EnableDebugLogging() + // h := harness.NewT(t) + + // provider := h.NewNode().Init() + // provider.SetIPFSConfig("Bitswap.ServerEnabled", false) + // provider = provider.StartDaemon() + // requester := h.NewNode().Init().StartDaemon() + // requester.Connect(provider) + // // Parse and check ID output + // res := provider.IPFS("id", "-f", "") + // protocols := strings.Split(strings.TrimSpace(res.Stdout.String()), "\n") + + // // No bitswap protocols should be present + // for _, proto := range protocols { + // assert.NotContains(t, proto, bsnet.ProtocolBitswap, "bitswap protocol %s should not be advertised when server is disabled", proto) + // assert.NotContains(t, proto, bsnet.ProtocolBitswapNoVers, "bitswap protocol %s should not be advertised when server is disabled", proto) + // assert.NotContains(t, proto, bsnet.ProtocolBitswapOneOne, "bitswap protocol %s should not be advertised when server is disabled", proto) + // assert.NotContains(t, proto, bsnet.ProtocolBitswapOneZero, "bitswap protocol %s should not be advertised when server is disabled", proto) + // } + // }) +} From 705962018189ba2e5843ec8e3303f115d7c1e2f8 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Wed, 30 Apr 2025 13:40:34 -0700 Subject: [PATCH 29/42] Update go-libp2p-pubsub to v0.13.1 (#10795) --- docs/changelogs/v0.35.md | 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 ++-- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index 07543b24d33..5bd49d1d384 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -143,6 +143,7 @@ See other caveats and configuration options at [`kubo/docs/datastores.md#pebbled - update `ipfs-webui` to [v4.7.0](https://github.com/ipfs/ipfs-webui/releases/tag/v4.7.0) - update `go-ds-pebble` to [v0.5.0](https://github.com/ipfs/go-ds-pebble/releases/tag/v0.5.0) - update `pebble` to [v2.0.3](https://github.com/cockroachdb/pebble/releases/tag/v2.0.3) +- update `go-libp2p-pubsub` to [v0.13.1](https://github.com:/libp2p/go-libp2p-pubsub/releases/tag/v0.13.1) ### πŸ“ Changelog ### πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index e94e45c90c1..25442a1c93f 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -128,7 +128,7 @@ require ( github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.32.0 // indirect github.com/libp2p/go-libp2p-kbucket v0.7.0 // indirect - github.com/libp2p/go-libp2p-pubsub v0.13.0 // indirect + github.com/libp2p/go-libp2p-pubsub v0.13.1 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.3.1 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.7.5 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index f2bb38f70c6..00b24d1afb7 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -478,8 +478,8 @@ github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLw github.com/libp2p/go-libp2p-kbucket v0.7.0 h1:vYDvRjkyJPeWunQXqcW2Z6E93Ywx7fX0jgzb/dGOKCs= github.com/libp2p/go-libp2p-kbucket v0.7.0/go.mod h1:blOINGIj1yiPYlVEX0Rj9QwEkmVnz3EP8LK1dRKBC6g= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= -github.com/libp2p/go-libp2p-pubsub v0.13.0 h1:RmFQ2XAy3zQtbt2iNPy7Tt0/3fwTnHpCQSSnmGnt1Ps= -github.com/libp2p/go-libp2p-pubsub v0.13.0/go.mod h1:m0gpUOyrXKXdE7c8FNQ9/HLfWbxaEw7xku45w+PaqZo= +github.com/libp2p/go-libp2p-pubsub v0.13.1 h1:tV3ttzzZSCk0EtEXnxVmWIXgjVxXx+20Jwjbs/Ctzjo= +github.com/libp2p/go-libp2p-pubsub v0.13.1/go.mod h1:MKPU5vMI8RRFyTP0HfdsF9cLmL1nHAeJm44AxJGJx44= 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.3.1 h1:cly48Xi5GjNw5Wq+7gmjfBiG9HCzQVkiZOUZ8kUl+Fg= diff --git a/go.mod b/go.mod index 3d86274d053..4d023579243 100644 --- a/go.mod +++ b/go.mod @@ -57,7 +57,7 @@ require ( github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.32.0 github.com/libp2p/go-libp2p-kbucket v0.7.0 - github.com/libp2p/go-libp2p-pubsub v0.13.0 + github.com/libp2p/go-libp2p-pubsub v0.13.1 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.3.1 github.com/libp2p/go-libp2p-routing-helpers v0.7.5 diff --git a/go.sum b/go.sum index 46350b8e30b..782427eadea 100644 --- a/go.sum +++ b/go.sum @@ -564,8 +564,8 @@ github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLw github.com/libp2p/go-libp2p-kbucket v0.7.0 h1:vYDvRjkyJPeWunQXqcW2Z6E93Ywx7fX0jgzb/dGOKCs= github.com/libp2p/go-libp2p-kbucket v0.7.0/go.mod h1:blOINGIj1yiPYlVEX0Rj9QwEkmVnz3EP8LK1dRKBC6g= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= -github.com/libp2p/go-libp2p-pubsub v0.13.0 h1:RmFQ2XAy3zQtbt2iNPy7Tt0/3fwTnHpCQSSnmGnt1Ps= -github.com/libp2p/go-libp2p-pubsub v0.13.0/go.mod h1:m0gpUOyrXKXdE7c8FNQ9/HLfWbxaEw7xku45w+PaqZo= +github.com/libp2p/go-libp2p-pubsub v0.13.1 h1:tV3ttzzZSCk0EtEXnxVmWIXgjVxXx+20Jwjbs/Ctzjo= +github.com/libp2p/go-libp2p-pubsub v0.13.1/go.mod h1:MKPU5vMI8RRFyTP0HfdsF9cLmL1nHAeJm44AxJGJx44= 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.3.1 h1:cly48Xi5GjNw5Wq+7gmjfBiG9HCzQVkiZOUZ8kUl+Fg= From b5d73695ba0fdbd71147b5c0e874d65a7bea915a Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 6 May 2025 19:06:40 +0200 Subject: [PATCH 30/42] feat: opt-in http retrieval client (#10772) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat: http retrieval as experimental feature This introduces the http-retrieval capability as an experimental feature. It can be enabled in the configuration `Experimental.HTTPRetrieval.Enabled = true`. Documentation and changelog to be added later. * refactor: HTTPRetrieval.Enabled as Flag * docs(config): HTTPRetrieval section * refactor: reusable MockHTTPContentRouter * feat: HTTPRetrieval.TLSInsecureSkipVerify allows self-signed certificates in tests * feat(config): HTTPRetrieval.MaxBlockSize * test: end-to-end HTTPRetrieval.Enabled this spawns two http services on localhost: 1. HTTP router that returns HTTP provider when /routing/v1/providers/cid i queried 2. HTTP provider that returns a block when /ipfs/cid is queried 3. Configures Kubo to use (1) instead of cid.contact this seems to work (running test with DEBUG=true shows (1) was queried for the test CID and returned multiaddr of (2), but Kubo never requested test CID block from (2) – needs investigation * fix: enable /routing/v1/peers for non-cid.contact we artificially limited every delegated routing endpoint because of cid.contact being limited to one endpoint * feat: Routing.DelegatedRouters make it easy to override the hardcoded implicit HTTP routeur URL without having to set the entire custom Router.Routers and Router.Methods (http_retrieval_client_test.go still needs to be fixed in future commit) * test: flag remaining work * docs: review feedback * refactor: providerQueryMgr with bitswapNetworks this fixes two regressions: (1) introduced in https://github.com/ipfs/kubo/issues/10717 where we only used bitswapLib2p query manager (this is why E2E did not act on http provider) (2) introduced in https://github.com/ipfs/kubo/pull/10765 where it was not possible to set binary peerID in IgnoreProviders (we changed to []string) * refactor: Bitswap.Libp2pEnabled replaces Bitswap.Enabled with Bitswap.Libp2pEnabled adds tests that confirm it is possible to disable libp2p bitswap fully and only keep http in client mode also, removes the need for passing empty blockstore in client-only mode * docs: changelog --------- Co-authored-by: Marcin Rataj --- cmd/ipfs/kubo/daemon.go | 1 + config/bitswap.go | 9 +- config/config.go | 15 +- config/http_retrieval.go | 19 +++ config/init.go | 7 - config/routing.go | 23 +-- core/node/bitswap.go | 77 ++++++--- core/node/groups.go | 13 +- core/node/libp2p/routingopt.go | 49 ++++-- docs/changelogs/v0.35.md | 128 ++++++++++++--- docs/config.md | 150 ++++++++++++++++-- docs/delegated-routing.md | 8 + routing/delegated.go | 23 ++- test/cli/bitswap_config_test.go | 106 +++++++++---- test/cli/content_routing_http_test.go | 64 ++------ test/cli/http_retrieval_client_test.go | 145 +++++++++++++++++ .../httprouting/mock_http_content_router.go | 117 ++++++++++++++ 17 files changed, 751 insertions(+), 203 deletions(-) create mode 100644 config/http_retrieval.go create mode 100644 test/cli/http_retrieval_client_test.go create mode 100644 test/cli/testutils/httprouting/mock_http_content_router.go diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index 30e805186c1..3676ed89139 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -458,6 +458,7 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment cfg.Identity.PeerID, cfg.Addresses, cfg.Identity.PrivKey, + cfg.HTTPRetrieval.Enabled.WithDefault(config.DefaultHTTPRetrievalEnabled), ) default: return fmt.Errorf("unrecognized routing option: %s", routingOption) diff --git a/config/bitswap.go b/config/bitswap.go index 38c817577a1..5adcdef9c84 100644 --- a/config/bitswap.go +++ b/config/bitswap.go @@ -2,13 +2,14 @@ package config // Bitswap holds Bitswap configuration options type Bitswap struct { - // Enabled controls both client and server (enabled by default) - Enabled Flag `json:",omitempty"` - // ServerEnabled controls if the node responds to WANTs (depends on Enabled, enabled by default) + // Libp2pEnabled controls if the node initializes bitswap over libp2p (enabled by default) + // (This can be disabled if HTTPRetrieval.Enabled is set to true) + Libp2pEnabled Flag `json:",omitempty"` + // ServerEnabled controls if the node responds to WANTs (depends on Libp2pEnabled, enabled by default) ServerEnabled Flag `json:",omitempty"` } const ( - DefaultBitswapEnabled = true + DefaultBitswapLibp2pEnabled = true DefaultBitswapServerEnabled = true ) diff --git a/config/config.go b/config/config.go index 68e57e1c3dd..eee7e768b6b 100644 --- a/config/config.go +++ b/config/config.go @@ -33,13 +33,14 @@ type Config struct { DNS DNS Migration Migration - Provider Provider - Reprovider Reprovider - Experimental Experiments - Plugins Plugins - Pinning Pinning - Import Import - Version Version + Provider Provider + Reprovider Reprovider + HTTPRetrieval HTTPRetrieval + Experimental Experiments + Plugins Plugins + Pinning Pinning + Import Import + Version Version Internal Internal // experimental/unstable options diff --git a/config/http_retrieval.go b/config/http_retrieval.go new file mode 100644 index 00000000000..a058e26c41c --- /dev/null +++ b/config/http_retrieval.go @@ -0,0 +1,19 @@ +package config + +// HTTPRetrieval is the configuration object for HTTP Retrieval settings. +// Implicit defaults can be found in core/node/bitswap.go +type HTTPRetrieval struct { + Enabled Flag `json:",omitempty"` + Allowlist []string `json:",omitempty"` + Denylist []string `json:",omitempty"` + NumWorkers *OptionalInteger `json:",omitempty"` + MaxBlockSize *OptionalString `json:",omitempty"` + TLSInsecureSkipVerify Flag `json:",omitempty"` +} + +const ( + DefaultHTTPRetrievalEnabled = false // opt-in for now, until we figure out https://github.com/ipfs/specs/issues/496 + DefaultHTTPRetrievalNumWorkers = 16 + DefaultHTTPRetrievalTLSInsecureSkipVerify = false // only for testing with self-signed HTTPS certs + DefaultHTTPRetrievalMaxBlockSize = "2MiB" // matching bitswap: https://specs.ipfs.tech/bitswap-protocol/#block-sizes +) diff --git a/config/init.go b/config/init.go index 1da876313f6..a40efdead28 100644 --- a/config/init.go +++ b/config/init.go @@ -48,13 +48,6 @@ func InitWithIdentity(identity Identity) (*Config, error) { }, }, - Routing: Routing{ - Type: nil, - Methods: nil, - Routers: nil, - IgnoreProviders: []peer.ID{}, - }, - // setup the node mount points. Mounts: Mounts{ IPFS: "/ipfs", diff --git a/config/routing.go b/config/routing.go index a6f899a1ca9..3fe501ee410 100644 --- a/config/routing.go +++ b/config/routing.go @@ -6,27 +6,30 @@ import ( "os" "runtime" "strings" - - peer "github.com/libp2p/go-libp2p/core/peer" ) const ( DefaultAcceleratedDHTClient = false DefaultLoopbackAddressesOnLanDHT = false + CidContactRoutingURL = "https://cid.contact" + PublicGoodDelegatedRoutingURL = "https://delegated-ipfs.dev" // cid.contact + amino dht (incl. IPNS PUTs) + EnvHTTPRouters = "IPFS_HTTP_ROUTERS" + EnvHTTPRoutersFilterProtocols = "IPFS_HTTP_ROUTERS_FILTER_PROTOCOLS" ) var ( // 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 + DefaultHTTPRouters = getEnvOrDefault(EnvHTTPRouters, []string{ + CidContactRoutingURL, // 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{ + DefaultHTTPRoutersFilterProtocols = getEnvOrDefault(EnvHTTPRoutersFilterProtocols, []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 + // http is added dynamically in routing/delegated.go. + // 'transport-ipfs-gateway-http' }) ) @@ -43,11 +46,13 @@ type Routing struct { LoopbackAddressesOnLanDHT Flag `json:",omitempty"` - IgnoreProviders []peer.ID + IgnoreProviders []string `json:",omitempty"` + + DelegatedRouters []string `json:",omitempty"` - Routers Routers + Routers Routers `json:",omitempty"` - Methods Methods + Methods Methods `json:",omitempty"` } type Router struct { diff --git a/core/node/bitswap.go b/core/node/bitswap.go index b69e7f510f0..a52b3e75d34 100644 --- a/core/node/bitswap.go +++ b/core/node/bitswap.go @@ -2,24 +2,28 @@ package node import ( "context" + "errors" "io" "time" + "github.com/dustin/go-humanize" "github.com/ipfs/boxo/bitswap" "github.com/ipfs/boxo/bitswap/client" + "github.com/ipfs/boxo/bitswap/network" bsnet "github.com/ipfs/boxo/bitswap/network/bsnet" + "github.com/ipfs/boxo/bitswap/network/httpnet" blockstore "github.com/ipfs/boxo/blockstore" exchange "github.com/ipfs/boxo/exchange" "github.com/ipfs/boxo/exchange/providing" provider "github.com/ipfs/boxo/provider" rpqm "github.com/ipfs/boxo/routing/providerquerymanager" "github.com/ipfs/go-cid" - "github.com/ipfs/go-datastore" ipld "github.com/ipfs/go-ipld-format" + version "github.com/ipfs/kubo" "github.com/ipfs/kubo/config" irouting "github.com/ipfs/kubo/routing" "github.com/libp2p/go-libp2p/core/host" - "github.com/libp2p/go-libp2p/core/routing" + peer "github.com/libp2p/go-libp2p/core/peer" "go.uber.org/fx" blocks "github.com/ipfs/go-block-format" @@ -79,38 +83,63 @@ type bitswapIn struct { // Bitswap creates the BitSwap server/client instance. // If Bitswap.ServerEnabled is false, the node will act only as a client // using an empty blockstore to prevent serving blocks to other peers. -func Bitswap(provide bool) interface{} { +func Bitswap(serverEnabled bool) interface{} { return func(in bitswapIn, lc fx.Lifecycle) (*bitswap.Bitswap, error) { - bitswapNetwork := bsnet.NewFromIpfsHost(in.Host) - var blockstoree blockstore.Blockstore = in.Bs - var provider routing.ContentDiscovery + var bitswapNetworks, bitswapLibp2p network.BitSwapNetwork + var bitswapBlockstore blockstore.Blockstore = in.Bs - if provide { + libp2pEnabled := in.Cfg.Bitswap.Libp2pEnabled.WithDefault(config.DefaultBitswapLibp2pEnabled) + if libp2pEnabled { + bitswapLibp2p = bsnet.NewFromIpfsHost(in.Host) + } - var maxProviders int = DefaultMaxProviders - if in.Cfg.Internal.Bitswap != nil { - maxProviders = int(in.Cfg.Internal.Bitswap.ProviderSearchMaxResults.WithDefault(DefaultMaxProviders)) + if httpCfg := in.Cfg.HTTPRetrieval; httpCfg.Enabled.WithDefault(config.DefaultHTTPRetrievalEnabled) { + maxBlockSize, err := humanize.ParseBytes(httpCfg.MaxBlockSize.WithDefault(config.DefaultHTTPRetrievalMaxBlockSize)) + if err != nil { + return nil, err } - - pqm, err := rpqm.New(bitswapNetwork, - in.Rt, - rpqm.WithMaxProviders(maxProviders), - rpqm.WithIgnoreProviders(in.Cfg.Routing.IgnoreProviders...), + bitswapHTTP := httpnet.New(in.Host, + httpnet.WithHTTPWorkers(int(httpCfg.NumWorkers.WithDefault(config.DefaultHTTPRetrievalNumWorkers))), + httpnet.WithAllowlist(httpCfg.Allowlist), + httpnet.WithDenylist(httpCfg.Denylist), + httpnet.WithInsecureSkipVerify(httpCfg.TLSInsecureSkipVerify.WithDefault(config.DefaultHTTPRetrievalTLSInsecureSkipVerify)), + httpnet.WithMaxBlockSize(int64(maxBlockSize)), + httpnet.WithUserAgent(version.GetUserAgentVersion()), ) + bitswapNetworks = network.New(in.Host.Peerstore(), bitswapLibp2p, bitswapHTTP) + } else if libp2pEnabled { + bitswapNetworks = bitswapLibp2p + } else { + return nil, errors.New("invalid configuration: Bitswap.Libp2pEnabled and HTTPRetrieval.Enabled are both disabled, unable to initialize Bitswap") + } + + // Kubo uses own, customized ProviderQueryManager + in.BitswapOpts = append(in.BitswapOpts, bitswap.WithClientOption(client.WithDefaultProviderQueryManager(false))) + var maxProviders int = DefaultMaxProviders + if in.Cfg.Internal.Bitswap != nil { + maxProviders = int(in.Cfg.Internal.Bitswap.ProviderSearchMaxResults.WithDefault(DefaultMaxProviders)) + } + ignoredPeerIDs := make([]peer.ID, 0, len(in.Cfg.Routing.IgnoreProviders)) + for _, str := range in.Cfg.Routing.IgnoreProviders { + pid, err := peer.Decode(str) if err != nil { return nil, err } - in.BitswapOpts = append(in.BitswapOpts, bitswap.WithClientOption(client.WithDefaultProviderQueryManager(false))) - in.BitswapOpts = append(in.BitswapOpts, bitswap.WithServerEnabled(true)) - provider = pqm - } else { - provider = nil - // When server is disabled, use an empty blockstore to prevent serving blocks - blockstoree = blockstore.NewBlockstore(datastore.NewMapDatastore()) - in.BitswapOpts = append(in.BitswapOpts, bitswap.WithServerEnabled(false)) + ignoredPeerIDs = append(ignoredPeerIDs, pid) + } + providerQueryMgr, err := rpqm.New(bitswapNetworks, + in.Rt, + rpqm.WithMaxProviders(maxProviders), + rpqm.WithIgnoreProviders(ignoredPeerIDs...), + ) + if err != nil { + return nil, err } - bs := bitswap.New(helpers.LifecycleCtx(in.Mctx, lc), bitswapNetwork, provider, blockstoree, in.BitswapOpts...) + // Explicitly enable/disable server to ensure desired provide mode + in.BitswapOpts = append(in.BitswapOpts, bitswap.WithServerEnabled(serverEnabled)) + + bs := bitswap.New(helpers.LifecycleCtx(in.Mctx, lc), bitswapNetworks, providerQueryMgr, bitswapBlockstore, in.BitswapOpts...) lc.Append(fx.Hook{ OnStop: func(ctx context.Context) error { diff --git a/core/node/groups.go b/core/node/groups.go index f82da293fa6..e4682f6a6bc 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -335,17 +335,18 @@ func Online(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part recordLifetime = d } - isBitswapEnabled := cfg.Bitswap.Enabled.WithDefault(config.DefaultBitswapEnabled) + isBitswapLibp2pEnabled := cfg.Bitswap.Libp2pEnabled.WithDefault(config.DefaultBitswapLibp2pEnabled) isBitswapServerEnabled := cfg.Bitswap.ServerEnabled.WithDefault(config.DefaultBitswapServerEnabled) - // Don't provide from bitswap when the strategic provider service is active - shouldBitswapProvide := isBitswapEnabled && isBitswapServerEnabled && !cfg.Experimental.StrategicProviding + + // Don't provide from bitswap when the legacy noop experiment "strategic provider service" is active + isBitswapServerEnabled = isBitswapServerEnabled && !cfg.Experimental.StrategicProviding return fx.Options( fx.Provide(BitswapOptions(cfg)), - fx.Provide(Bitswap(shouldBitswapProvide)), - fx.Provide(OnlineExchange(isBitswapEnabled)), + fx.Provide(Bitswap(isBitswapServerEnabled)), + fx.Provide(OnlineExchange(isBitswapLibp2pEnabled)), // Replace our Exchange with a Providing exchange! - fx.Decorate(ProvidingExchange(shouldBitswapProvide)), + fx.Decorate(ProvidingExchange(isBitswapServerEnabled)), fx.Provide(DNSResolver), fx.Provide(Namesys(ipnsCacheSize, cfg.Ipns.MaxCacheTTL.WithDefault(config.DefaultIpnsMaxCacheTTL))), fx.Provide(Peering), diff --git a/core/node/libp2p/routingopt.go b/core/node/libp2p/routingopt.go index 292f49fe46e..43565265b37 100644 --- a/core/node/libp2p/routingopt.go +++ b/core/node/libp2p/routingopt.go @@ -2,6 +2,7 @@ package libp2p import ( "context" + "os" "time" "github.com/ipfs/go-datastore" @@ -29,21 +30,44 @@ type RoutingOptionArgs struct { type RoutingOption func(args RoutingOptionArgs) (routing.Routing, error) +var noopRouter = routinghelpers.Null{} + func constructDefaultHTTPRouters(cfg *config.Config) ([]*routinghelpers.ParallelRouter, error) { var routers []*routinghelpers.ParallelRouter + httpRetrievalEnabled := cfg.HTTPRetrieval.Enabled.WithDefault(config.DefaultHTTPRetrievalEnabled) + + // Use config.DefaultHTTPRouters if custom override was sent via config.EnvHTTPRouters + // or if user did not set any preference in cfg.Routing.DelegatedRouters + var httpRouterEndpoints []string + if os.Getenv(config.EnvHTTPRouters) != "" || len(cfg.Routing.DelegatedRouters) == 0 { + httpRouterEndpoints = config.DefaultHTTPRouters + } else { + httpRouterEndpoints = cfg.Routing.DelegatedRouters + } + // Append HTTP routers for additional speed - for _, endpoint := range config.DefaultHTTPRouters { - httpRouter, err := irouting.ConstructHTTPRouter(endpoint, cfg.Identity.PeerID, httpAddrsFromConfig(cfg.Addresses), cfg.Identity.PrivKey) + for _, endpoint := range httpRouterEndpoints { + httpRouter, err := irouting.ConstructHTTPRouter(endpoint, cfg.Identity.PeerID, httpAddrsFromConfig(cfg.Addresses), cfg.Identity.PrivKey, httpRetrievalEnabled) if err != nil { return nil, err } - + // Mapping router to /routing/v1/* endpoints + // https://specs.ipfs.tech/routing/http-routing-v1/ r := &irouting.Composer{ - GetValueRouter: routinghelpers.Null{}, - PutValueRouter: routinghelpers.Null{}, - ProvideRouter: routinghelpers.Null{}, // modify this when indexers supports provide - FindPeersRouter: routinghelpers.Null{}, - FindProvidersRouter: httpRouter, + GetValueRouter: httpRouter, // GET /routing/v1/ipns + PutValueRouter: httpRouter, // PUT /routing/v1/ipns + ProvideRouter: noopRouter, // we don't have spec for sending provides to /routing/v1 (revisit once https://github.com/ipfs/specs/pull/378 or similar is ratified) + FindPeersRouter: httpRouter, // /routing/v1/peers + FindProvidersRouter: httpRouter, // /routing/v1/providers + } + + if endpoint == config.CidContactRoutingURL { + // Special-case: cid.contact only supports /routing/v1/providers/cid + // we disable other endpoints to avoid sending requests that always fail + r.GetValueRouter = noopRouter + r.PutValueRouter = noopRouter + r.ProvideRouter = noopRouter + r.FindPeersRouter = noopRouter } routers = append(routers, &routinghelpers.ParallelRouter{ @@ -119,7 +143,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 config.Addresses, privKey string) RoutingOption { +func ConstructDelegatedRouting(routers config.Routers, methods config.Methods, peerID string, addrs config.Addresses, privKey string, httpRetrieval bool) RoutingOption { return func(args RoutingOptionArgs) (routing.Routing, error) { return irouting.Parse(routers, methods, &irouting.ExtraDHTParams{ @@ -130,9 +154,10 @@ func ConstructDelegatedRouting(routers config.Routers, methods config.Methods, p Context: args.Ctx, }, &irouting.ExtraHTTPParams{ - PeerID: peerID, - Addrs: httpAddrsFromConfig(addrs), - PrivKeyB64: privKey, + PeerID: peerID, + Addrs: httpAddrsFromConfig(addrs), + PrivKeyB64: privKey, + HTTPRetrieval: httpRetrieval, }, ) } diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index 5bd49d1d384..2826541cc57 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -10,25 +10,50 @@ This release was brought to you by the [Shipyard](http://ipshipyard.com/) team. - [Overview](#overview) - [πŸ”¦ Highlights](#-highlights) + - [Opt-in HTTP Retrieval client](#opt-in-http-retrieval-client) - [Dedicated `Reprovider.Strategy` for MFS](#dedicated-reproviderstrategy-for-mfs) - - [Additional new configuration options](#additional-new-configuration-options) - [Grid view in WebUI](#grid-view-in-webui) - - [Enhanced DAG-Shaping Controls for `ipfs add`](#enhanced-dag-shaping-controls-for-ipfs-add) - - [New `ipfs add` Options](#new-ipfs-add-options) - - [Persistent `Import.*` Configuration](#persistent-import-configuration) - - [Updated `Import` Profiles](#updated-import-profiles) + - [Enhanced DAG-Shaping Controls](#enhanced-dag-shaping-controls) + - [New DAG-Shaping `ipfs add` Options](#new-dag-shaping-ipfs-add-options) + - [Persistent DAG-Shaping `Import.*` Configuration](#persistent-dag-shaping-import-configuration) + - [Updated DAG-Shaping `Import` Profiles](#updated-dag-shaping-import-profiles) - [`Datastore` Metrics Now Opt-In](#datastore-metrics-now-opt-in) - - [Optimized, dedicated queue for providing fresh CIDs](#optimized-dedicated-queue-for-providing-fresh-cids) - - [Deprecated `ipfs stats provider`](#deprecated-ipfs-stats-provider) - - [Pebble Database Format Config](#pebble-database-format-config) + - [Improved performance of data onboarding](#improved-performance-of-data-onboarding) + - [Fast `ipfs add` in online mode](#fast-ipfs-add-in-online-mode) + - [Optimized, dedicated queue for providing fresh CIDs](#optimized-dedicated-queue-for-providing-fresh-cids) + - [Deprecated `ipfs stats provider`](#deprecated-ipfs-stats-provider) + - [New `Bitswap` configuration options](#new-bitswap-configuration-options) + - [New `Routing` configuration options](#new-routing-configuration-options) + - [New Pebble database format config](#new-pebble-database-format-config) - [πŸ“¦οΈ Important dependency updates](#-important-dependency-updates) - [πŸ“ Changelog](#-changelog) - [πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors](#-contributors) ### Overview +This release brings significant UX and performance improvements to data onboarding, provisioning, and retrieval systems. + +New configuration options let you customize the shape of UnixFS DAGs generated during the data import, control the scope of DAGs announced on the Amino DHT, select which delegated routing endpoints are queried, and choose whether to enable HTTP retrieval alongside Bitswap over Libp2p. + +Continue reading for more details. + + ### πŸ”¦ Highlights +#### Opt-in HTTP Retrieval client + +This release adds experimental support for retrieving blocks directly over HTTPS (HTTP/2), complementing the existing Bitswap over Libp2p. + +The opt-in client enables Kubo to use [delegated routing](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingdelegatedrouters) results with `/tls/http` multiaddrs, connecting to HTTPS servers that support [Trustless HTTP Gateway](https://specs.ipfs.tech/http-gateways/trustless-gateway)'s Block Responses (`?format=raw`, `application/vnd.ipld.raw`). Fetching blocks via HTTPS (HTTP/2) simplifies infrastructure and reduces costs for storage providers by leveraging HTTP caching and CDNs. + +To enable this feature for testing and feedback, set: + +```console +$ ipfs config --json HTTPRetrieval.Enabled true +``` + +See [`HTTPRetrieval`](https://github.com/ipfs/kubo/blob/master/docs/config.md#httpretrieval) for more details. + #### Dedicated `Reprovider.Strategy` for MFS The [Mutable File System (MFS)](https://docs.ipfs.tech/concepts/glossary/#mfs) in Kubo is a UnixFS filesystem managed with [`ipfs files`](https://docs.ipfs.tech/reference/kubo/cli/#ipfs-files) commands. It supports familiar file operations like cp and mv within a folder-tree structure, automatically updating a MerkleDAG and a "root CID" that reflects the current MFS state. Files in MFS are protected from garbage collection, offering a simpler alternative to `ipfs pin`. This makes it a popular choice for tools like [IPFS Desktop](https://docs.ipfs.tech/install/ipfs-desktop/) and the [WebUI](https://github.com/ipfs/ipfs-webui/#readme). @@ -39,19 +64,13 @@ Users relying on the `pinned` strategy can switch to `pinned+mfs` and use MFS al See [`Reprovider.Strategy`](https://github.com/ipfs/kubo/blob/master/docs/config.md#reproviderstrategy) for more details. -#### Additional new configuration options - -- [`Bitswap`](https://github.com/ipfs/kubo/blob/master/docs/config.md#bitswap) section with `Enabled` and `ServerEnabled` flags determine whether Kubo initializes Bitswap, enabling just the client or both the client and server. -- [`Internal.Bitswap.ProviderSearchMaxResults`](https://github.com/ipfs/kubo/blob/master/docs/config.md#internalbitswapprovidersearchmaxresults) for adjusting the maximum number of providers bitswap client should aim at before it stops searching for new ones. -- [`Routing.IgnoreProviders`](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingignoreproviders) allows ignoring specific peer IDs when returned by the content routing system as providers of content. - #### Grid view in WebUI The WebUI, accessible at http://127.0.0.1:5001/webui/, now includes support for the grid view on the _Files_ screen: > ![image](https://github.com/user-attachments/assets/80dcf0d0-8103-426f-ae91-416fb25d32b6) -#### Enhanced DAG-Shaping Controls for `ipfs add` +#### Enhanced DAG-Shaping Controls This release advances CIDv1 support by introducing fine-grained control over UnixFS DAG shaping during data ingestion with the `ipfs add` command. @@ -59,7 +78,7 @@ Wider DAG trees (more links per node, higher fanout, larger thresholds) are bene Kubo now allows users to act on these tradeoffs and customize the width of the DAG created by `ipfs add` command. -##### New `ipfs add` Options +##### New DAG-Shaping `ipfs add` Options Three new options allow you to override default settings for specific import operations: @@ -68,7 +87,7 @@ Three new options allow you to override default settings for specific import ope - Note: Directories exceeding this limit or the `Import.UnixFSHAMTDirectorySizeThreshold` are converted to HAMT-based (sharded across multiple blocks) structures. - `--max-hamt-fanout`: Specifies the maximum number of child nodes for HAMT internal structures. -##### Persistent `Import.*` Configuration +##### Persistent DAG-Shaping `Import.*` Configuration You can set default values for these options using the following configuration settings: - [`Import.UnixFSFileMaxLinks`](https://github.com/ipfs/kubo/blob/master/docs/config.md#importunixfsfilemaxlinks) @@ -76,7 +95,7 @@ You can set default values for these options using the following configuration s - [`Import.UnixFSHAMTDirectoryMaxFanout`](https://github.com/ipfs/kubo/blob/master/docs/config.md#importunixfshamtdirectorymaxfanout) - [`Import.UnixFSHAMTDirectorySizeThreshold`](https://github.com/ipfs/kubo/blob/master/docs/config.md#importunixfshamtdirectorysizethreshold) -##### Updated `Import` Profiles +##### Updated DAG-Shaping `Import` Profiles The release updated configuration [profiles](https://github.com/ipfs/kubo/blob/master/docs/config.md#profiles) to incorporate these new `Import.*` settings: - Updated Profile: `test-cid-v1` now includes current defaults as explicit `Import.UnixFSFileMaxLinks=174`, `Import.UnixFSDirectoryMaxLinks=0`, `Import.UnixFSHAMTDirectoryMaxFanout=256` and `Import.UnixFSHAMTDirectorySizeThreshold=256KiB` @@ -95,11 +114,55 @@ Convenience opt-in [profiles](https://github.com/ipfs/kubo/blob/master/docs/conf It is also possible to manually add the `measure` wrapper. See examples in [`Datastore.Spec`](https://github.com/ipfs/kubo/blob/master/docs/config.md#datastorespec) documentation. -#### Optimized, dedicated queue for providing fresh CIDs +#### Improved performance of data onboarding + +This Kubo release significantly improves both the speed of ingesting data via `ipfs add` and announcing newly produced CIDs to Amino DHT. + +##### Fast `ipfs add` in online mode + +Adding a large directory of data when `ipfs daemon` was running in online mode took a long time. A significant amount of this time was spent writing to and reading from the persisted provider queue. Due to this, many users had to shut down the daemon and perform data import in offline mode. This release fixes this known limitation, significantly improving the speed of `ipfs add`. + +> [!IMPORTANT] +> Performing `ipfs add` of 10GiB file would take about 30 minutes. +> Now it takes close to 30 seconds. + +Kubo v0.34: + +```console +$ time kubo/cmd/ipfs/ipfs add -r /tmp/testfiles-100M > /dev/null + 100.00 MiB / 100.00 MiB [=====================================================================] 100.00% +real 0m6.464s + +$ time kubo/cmd/ipfs/ipfs add -r /tmp/testfiles-1G > /dev/null + 1000.00 MiB / 1000.00 MiB [===================================================================] 100.00% +real 1m10.542s + +$ time kubo/cmd/ipfs/ipfs add -r /tmp/testfiles-10G > /dev/null + 10.00 GiB / 10.00 GiB [=======================================================================] 100.00% +real 24m5.744s +``` + +Kubo v0.35: + +```console +$ time kubo/cmd/ipfs/ipfs add -r /tmp/testfiles-100M > /dev/null + 100.00 MiB / 100.00 MiB [=====================================================================] 100.00% +real 0m0.326s + +$ time kubo/cmd/ipfs/ipfs add -r /tmp/testfiles-1G > /dev/null + 1.00 GiB / 1.00 GiB [=========================================================================] 100.00% +real 0m2.819s + +$ time kubo/cmd/ipfs/ipfs add -r /tmp/testfiles-10G > /dev/null + 10.00 GiB / 10.00 GiB [=======================================================================] 100.00% +real 0m28.405s +``` + +##### Optimized, dedicated queue for providing fresh CIDs From `kubo` [`v0.33.0`](https://github.com/ipfs/kubo/releases/tag/v0.33.0), Bitswap stopped advertising newly added and received blocks to the DHT. Since -then `boxo/provider` is responsible for the provide and reprovide logic. Prior +then `boxo/provider` is responsible for the first time provide and the recurring reprovide logic. Prior to `v0.35.0`, provides and reprovides were handled together in batches, leading to delays in initial advertisements (provides). @@ -113,7 +176,7 @@ concurrent provide operations: > [!TIP] > Users who need to provide large volumes of content immediately should consider removing the cap on concurrent provide operations and also set `Routing.AcceleratedDHTClient` to `true`. -##### Deprecated `ipfs stats provider` +###### Deprecated `ipfs stats provider` Since the `ipfs stats provider` command was displaying statistics for both provides and reprovides, this command isn't relevant anymore after separating @@ -125,7 +188,28 @@ but for reprovides only. > [!NOTE] > `ipfs stats provider` still works, but is marked as deprecated and will be removed in a future release. Be mindful that the command provides only statistics about reprovides (similar to `ipfs stats reprovide`) and not the new provide queue (this will be fixed as a part of wider refactor planned for a future release). -#### Pebble Database Format Config +#### New `Bitswap` configuration options + +- [`Bitswap.Libp2pEnabled`](https://github.com/ipfs/kubo/blob/master/docs/config.md#bitswaplibp2penabled) determines whether Kubo will use Bitswap over libp2p (both client and server). +- [`Bitswap.ServerEnabled`](https://github.com/ipfs/kubo/blob/master/docs/config.md#bitswapserverenabled) controls whether Kubo functions as a Bitswap server to host and respond to block requests. +- [`Internal.Bitswap.ProviderSearchMaxResults`](https://github.com/ipfs/kubo/blob/master/docs/config.md#internalbitswapprovidersearchmaxresults) for adjusting the maximum number of providers bitswap client should aim at before it stops searching for new ones. + +#### New `Routing` configuration options + +- [`Routing.IgnoreProviders`](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingignoreproviders) allows ignoring specific peer IDs when returned by the content routing system as providers of content. + - Simplifies testing `HTTPRetrieval.Enabled` in setups where Bitswap over Libp2p and HTTP retrieval is served under different PeerIDs. +- [`Routing.DelegatedRouters`](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingdelegatedrouters) allows customizing HTTP routers used by Kubo when `Routing.Type` is set to `auto` or `autoclient`. + - Users are now able to adjust the default routing system and directly query custom routers for increased resiliency or when dataset is too big and CIDs are not announced on Amino DHT. + +> [!TIP] +> +> For example, to use Pinata's routing endpoint in addition to IPNI at `cid.contact`: +> +> ```console +> $ ipfs config --json Routing.DelegatedRouters '["https://cid.contact","https://indexer.pinata.cloud"]' +> ``` + +#### New Pebble database format config This Kubo release provides node operators with more control over [Pebble's `FormatMajorVersion`](https://github.com/cockroachdb/pebble/tree/master?tab=readme-ov-file#format-major-versions). This allows testing a new Kubo release without automatically migrating Pebble datastores, keeping the ability to switch back to older Kubo. diff --git a/docs/config.md b/docs/config.md index 770155783dd..91cefe8dc92 100644 --- a/docs/config.md +++ b/docs/config.md @@ -37,7 +37,7 @@ config file at runtime. - [`AutoTLS.RegistrationDelay`](#autotlsregistrationdelay) - [`AutoTLS.CAEndpoint`](#autotlscaendpoint) - [`Bitswap`](#bitswap) - - [`Bitswap.Enabled`](#bitswapenabled) + - [`Bitswap.Libp2pEnabled`](#bitswaplibp2penabled) - [`Bitswap.ServerEnabled`](#bitswapserverenabled) - [`Bootstrap`](#bootstrap) - [`Datastore`](#datastore) @@ -127,6 +127,7 @@ config file at runtime. - [`Routing.AcceleratedDHTClient`](#routingaccelerateddhtclient) - [`Routing.LoopbackAddressesOnLanDHT`](#routingloopbackaddressesonlandht) - [`Routing.IgnoreProviders`](#routingignoreproviders) + - [`Routing.DelegatedRouters`](#routingdelegatedrouters) - [`Routing.Routers`](#routingrouters) - [`Routing.Routers: Type`](#routingrouters-type) - [`Routing.Routers: Parameters`](#routingrouters-parameters) @@ -184,6 +185,13 @@ config file at runtime. - [`DNS`](#dns) - [`DNS.Resolvers`](#dnsresolvers) - [`DNS.MaxCacheTTL`](#dnsmaxcachettl) + - [`HTTPRetrieval`](#httpretrieval) + - [`HTTPRetrieval.Enabled`](#httpretrievalenabled) + - [`HTTPRetrieval.Allowlist`](#httpretrievalallowlist) + - [`HTTPRetrieval.Denylist`](#httpretrievaldenylist) + - [`HTTPRetrieval.NumWorkers`](#httpretrievalnumworkers) + - [`HTTPRetrieval.MaxBlockSize`](#httpretrievalmaxblocksize) + - [`HTTPRetrieval.TLSInsecureSkipVerify`](#httpretrievaltlsinsecureskipverify) - [`Import`](#import) - [`Import.CidVersion`](#importcidversion) - [`Import.UnixFSRawLeaves`](#importunixfsrawleaves) @@ -624,16 +632,20 @@ Type: `optionalString` ## `Bitswap` -High level client and server configuration of the [Bitswap Protocol](https://specs.ipfs.tech/bitswap-protocol/). +High level client and server configuration of the [Bitswap Protocol](https://specs.ipfs.tech/bitswap-protocol/) over libp2p. For internal configuration see [`Internal.Bitswap`](#internalbitswap). -### `Bitswap.Enabled` +For HTTP version see [`HTTPRetrieval`](#httpretrieval). -Manages both Bitswap client and server functionality. For testing or operating a node without Bitswap requirements. +### `Bitswap.Libp2pEnabled` + +Determines whether Kubo will use Bitswap over libp2p. + +Disabling this, will remove `/ipfs/bitswap/*` protocol support from [libp2p identify](https://github.com/libp2p/specs/blob/master/identify/README.md) responses, effectively shutting down both Bitswap libp2p client and server. > [!WARNING] -> Bitswap is a core component of Kubo, and disabling it completely may cause unpredictable outcomes. Treat this as experimental and use it solely for testing purposes. +> Bitswap over libp2p is a core component of Kubo and the oldest way of exchanging blocks. Disabling it completely may cause unpredictable outcomes, such as retrieval failures, if the only providers were libp2p ones. Treat this as experimental and use it solely for testing purposes with `HTTPRetrieval.Enabled`. Default: `true` @@ -643,9 +655,9 @@ Type: `flag` Determines whether Kubo functions as a Bitswap server to host and respond to block requests. -Disabling the server retains client and protocol support in libp2p identify responses but causes Kubo to reply with "don't have" to all block requests. +Disabling the server retains client and protocol support in [libp2p identify](https://github.com/libp2p/specs/blob/master/identify/README.md) responses but causes Kubo to reply with "don't have" to all block requests. -Default: `true` +Default: `true` (requires `Bitswap.Libp2pEnabled`) Type: `flag` @@ -1725,7 +1737,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 public IPFS DHT (aka "Amino") - and parallel HTTP routers listed below for additional speed. + and parallel [`Routing.DelegatedRouters`](#routingdelegatedrouters) for additional speed. * If set to "autoclient", your node will behave as in "auto" but without running a DHT server. @@ -1755,15 +1767,13 @@ 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 [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) +by leveraging [`Routing.DelegatedRouters`](#routingdelegatedrouters) 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`. +[Advanced routing rules](https://github.com/ipfs/kubo/blob/master/docs/delegated-routing.md) can be configured in `Routing.Routers` after setting `Routing.Type` to `custom`. -Default: `auto` (DHT + IPNI) +Default: `auto` (DHT + [`Routing.DelegatedRouters`](#routingdelegatedrouters)) Type: `optionalString` (`null`/missing means the default) @@ -1828,16 +1838,32 @@ Type: `bool` (missing means `false`) ### `Routing.IgnoreProviders` -An array of peerIDs. Any provider record associated to one of these peer IDs is ignored. +An array of [string-encoded PeerIDs](https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md#string-representation). Any provider record associated to one of these peer IDs is ignored. Apart from ignoring specific providers for reasons like misbehaviour etc. this setting is useful to ignore providers as a way to indicate preference, when the same provider is found under different peerIDs (i.e. one for HTTP and one for Bitswap retrieval). +> [!TIP] +> This denylist operates on PeerIDs. +> To deny specific HTTP Provider URL, use [`HTTPRetrieval.Denylist`](#httpretrievaldenylist) instead. + Default: `[]` -Type: `array[peerID]` +Type: `array[string]` + +### `Routing.DelegatedRouters` +This is an array of URL hostnames that support the [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) which are used alongside the DHT when [`Routing.Type`](#routingtype) is set to `auto` or `autoclient`. + +> [!TIP] +> Delegated routing allows IPFS implementations to offload tasks like content routing, peer routing, and naming to a separate process or server while also benefiting from HTTP caching. +> +> One can run their own delegated router either by implementing the [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) themselves, or by using [Someguy](https://github.com/ipfs/someguy), a turn-key implementation that proxies requests to the Amino DHT and other delegated routing servers, such as the Network Indexer at `cid.contact`. Public utility instance of Someguy is hosted at [`https://delegated-ipfs.dev`](https://docs.ipfs.tech/concepts/public-utilities/#delegated-routing). + +Default: `["https://cid.contact"]` (empty or `nil` will also use this default; to disable delegated routing, set `Routing.Type` to `dht` or `dhtclient`) + +Type: `array[string]` ### `Routing.Routers` @@ -2596,6 +2622,100 @@ Default: Respect DNS Response TTL Type: `optionalDuration` +## `HTTPRetrieval` + +`HTTPRetrieval` is configuration for pure HTTP retrieval based on Trustless HTTP Gateways' +[Block Responses (`application/vnd.ipld.raw`)](https://specs.ipfs.tech/http-gateways/trustless-gateway/#block-responses-application-vnd-ipld-raw) +which can be used in addition to or instead of retrieving blocks with [Bitswap over Libp2p](#bitswap). + +Default: `{}` + +Type: `object` + +### `HTTPRetrieval.Enabled` + +> [!CAUTION] +> This feature is **EXPERIMENTAL** and may change in future release. Enable with caution, and provide feedback via GitHub issues. + +Controls whether HTTP-based block retrieval is enabled. + +When enabled, Kubo will be able to act on `/tls/http` (HTTP/2) providers ([Trustless HTTP Gateways](https://specs.ipfs.tech/http-gateways/trustless-gateway/)) returned by the [`Routing.DelegatedRouters`](#routingdelegatedrouters) +to perform pure HTTP [block retrievals](https://specs.ipfs.tech/http-gateways/trustless-gateway/#block-responses-application-vnd-ipld-raw) +in addition to [Bitswap over Libp2p](#bitswap). + +HTTP requests for `application/vnd.ipld.raw` will be issued instead of Bitswap if a peer has a `/tls/http` multiaddr +and the HTTPS server returns HTTP 200 for the [probe path](https://specs.ipfs.tech/http-gateways/trustless-gateway/#dedicated-probe-paths). + +> [!IMPORTANT] +> - Requires TLS and HTTP/2. +> - This feature works in the same way as Bitswap: connected HTTP-peers receive optimistic block requests even for content that they are not announcing. +> - HTTP client does not follow redirects. Providers should keep announcements up to date. +> - IPFS ecosystem is working towards [supporting HTTP providers on Amino DHT](https://github.com/ipfs/specs/issues/496). Currently, HTTP providers are mostly limited to results from [`Routing.DelegatedRouters`](#routingdelegatedrouters) endpoints and requires `Routing.Type=auto|autoclient`. + +Default: `false` + +Type: `flag` + +### `HTTPRetrieval.Allowlist` + +Optional list of hostnames for which HTTP retrieval is allowed for. +If this list is not empty, only hosts matching these entries will be allowed for HTTP retrieval. + +> [!TIP] +> To limit HTTP retrieval to a provider at `/dns4/example.com/tcp/443/tls/http` (which would serve `HEAD|GET https://example.com/ipfs/cid?format=raw`), set this to `["example.com"]` + +Default: `[]` + +Type: `array[string]` + +### `HTTPRetrieval.Denylist` + +Optional list of hostnames for which HTTP retrieval is not allowed. +Denylist entries take precedence over Allowlist entries. + + +> [!TIP] +> This denylist operates on HTTP endpoint hostnames. +> To deny specific PeerID, use [`Routing.IgnoreProviders`](#routingignoreproviders) instead. + +Default: `[]` + +Type: `array[string]` + +### `HTTPRetrieval.NumWorkers` + +The number of worker goroutines to use for concurrent HTTP retrieval operations. +This setting controls the level of parallelism for HTTP-based block retrieval operations. +Higher values can improve performance when retrieving many blocks but may increase resource usage. + +Default: `16` + +Type: `optionalInteger` + +### `HTTPRetrieval.MaxBlockSize` + +Sets the maximum size of a block that the HTTP retrieval client will accept. + +> [!NOTE] +> This setting is a security feature designed to protect Kubo from malicious providers who might send excessively large or invalid data. +> Increasing this value allows Kubo to retrieve larger blocks from compatible HTTP providers, but doing so reduces interoperability with Bitswap, and increases potential security risks. +> +> Learn more: [Supporting Large IPLD Blocks: Why block limits?](https://discuss.ipfs.tech/t/supporting-large-ipld-blocks/15093#why-block-limits-5) + +Default: `2MiB` (matching [Bitswap size limit](https://specs.ipfs.tech/bitswap-protocol/#block-sizes)) + +Type: `optionalString` + +### `HTTPRetrieval.TLSInsecureSkipVerify` + +Disables TLS certificate validation. +Allows making HTTPS connections to HTTP/2 test servers with self-signed TLS certificates. +Only for testing, do not use in production. + +Default: `false` + +Type: `flag` + ## `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. diff --git a/docs/delegated-routing.md b/docs/delegated-routing.md index 8f80beab671..ddc4e48ed3c 100644 --- a/docs/delegated-routing.md +++ b/docs/delegated-routing.md @@ -16,6 +16,14 @@ which then got changed and standardized as [Routing V1 HTTP API](https://specs.i 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). + +> [!TIP] +> Kubo 0.35 added support for [`Routing.DelegatedRouters`](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingdelegatedrouters). +> +> Most of users are best served by setting delegated HTTP router URLs there and `Routing.Type` to `auto` or `autoclient`, rather than custom routing with complex `Routing.Routers` and `Routing.Methods` directly. +> +> The rest of this documentation should be considered only by advanced users and researchers. + 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. diff --git a/routing/delegated.go b/routing/delegated.go index f5f98a03f25..420f30c832f 100644 --- a/routing/delegated.go +++ b/routing/delegated.go @@ -149,12 +149,13 @@ func parse(visited map[string]bool, } type ExtraHTTPParams struct { - PeerID string - Addrs []string - PrivKeyB64 string + PeerID string + Addrs []string + PrivKeyB64 string + HTTPRetrieval bool } -func ConstructHTTPRouter(endpoint string, peerID string, addrs []string, privKey string) (routing.Routing, error) { +func ConstructHTTPRouter(endpoint string, peerID string, addrs []string, privKey string, httpRetrieval bool) (routing.Routing, error) { return httpRoutingFromConfig( config.Router{ Type: "http", @@ -163,9 +164,10 @@ func ConstructHTTPRouter(endpoint string, peerID string, addrs []string, privKey }, }, &ExtraHTTPParams{ - PeerID: peerID, - Addrs: addrs, - PrivKeyB64: privKey, + PeerID: peerID, + Addrs: addrs, + PrivKeyB64: privKey, + HTTPRetrieval: httpRetrieval, }, ) } @@ -200,13 +202,18 @@ func httpRoutingFromConfig(conf config.Router, extraHTTP *ExtraHTTPParams) (rout return nil, err } + protocols := config.DefaultHTTPRoutersFilterProtocols + if extraHTTP.HTTPRetrieval { + protocols = append(protocols, "transport-ipfs-gateway-http") + } + cli, err := drclient.New( params.Endpoint, drclient.WithHTTPClient(delegateHTTPClient), drclient.WithIdentity(key), drclient.WithProviderInfo(addrInfo.ID, addrInfo.Addrs), drclient.WithUserAgent(version.GetUserAgentVersion()), - drclient.WithProtocolFilter(config.DefaultHTTPRoutersFilterProtocols), + drclient.WithProtocolFilter(protocols), 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 ) diff --git a/test/cli/bitswap_config_test.go b/test/cli/bitswap_config_test.go index 19ae3e34dbe..db7656ef27e 100644 --- a/test/cli/bitswap_config_test.go +++ b/test/cli/bitswap_config_test.go @@ -1,9 +1,11 @@ package cli import ( + "strings" "testing" "time" + "github.com/ipfs/boxo/bitswap/network/bsnet" "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/test/cli/harness" "github.com/ipfs/kubo/test/cli/testutils" @@ -61,32 +63,32 @@ func TestBitswapConfig(t *testing.T) { } }) - t.Run("server disabled and client enabled", func(t *testing.T) { + t.Run("client still works when server disabled", func(t *testing.T) { t.Parallel() h := harness.NewT(t) - provider := h.NewNode().Init() - provider.SetIPFSConfig("Bitswap.ServerEnabled", false) - provider.StartDaemon() - - requester := h.NewNode().Init().StartDaemon() - hash := requester.IPFSAddStr(string(testData)) + requester := h.NewNode().Init() + requester.SetIPFSConfig("Bitswap.ServerEnabled", false) + requester.StartDaemon() - provider.Connect(requester) + provider := h.NewNode().Init().StartDaemon() + hash := provider.IPFSAddStr(string(testData)) + requester.Connect(provider) // Even when the server is disabled, the client should be able to retrieve data - res := provider.RunIPFS("cat", hash) + res := requester.RunIPFS("cat", hash) assert.Equal(t, testData, res.Stdout.Bytes(), "retrieved data should match original") }) - t.Run("bitswap completely disabled", func(t *testing.T) { + t.Run("bitswap over libp2p disabled", func(t *testing.T) { t.Parallel() h := harness.NewT(t) requester := h.NewNode().Init() requester.UpdateConfig(func(cfg *config.Config) { - cfg.Bitswap.Enabled = config.False + cfg.Bitswap.Libp2pEnabled = config.False cfg.Bitswap.ServerEnabled = config.False + cfg.HTTPRetrieval.Enabled = config.True }) requester.StartDaemon() @@ -112,27 +114,63 @@ func TestBitswapConfig(t *testing.T) { assert.Equal(t, []byte("random"), res.Stdout.Bytes(), "cat should return the added data") }) - // TODO: Disabling Bitswap.Enabled should remove /ifps/bitswap* protocols from `ipfs id` - // t.Run("bitswap protocols disabled", func(t *testing.T) { - // t.Parallel() - // harness.EnableDebugLogging() - // h := harness.NewT(t) - - // provider := h.NewNode().Init() - // provider.SetIPFSConfig("Bitswap.ServerEnabled", false) - // provider = provider.StartDaemon() - // requester := h.NewNode().Init().StartDaemon() - // requester.Connect(provider) - // // Parse and check ID output - // res := provider.IPFS("id", "-f", "") - // protocols := strings.Split(strings.TrimSpace(res.Stdout.String()), "\n") - - // // No bitswap protocols should be present - // for _, proto := range protocols { - // assert.NotContains(t, proto, bsnet.ProtocolBitswap, "bitswap protocol %s should not be advertised when server is disabled", proto) - // assert.NotContains(t, proto, bsnet.ProtocolBitswapNoVers, "bitswap protocol %s should not be advertised when server is disabled", proto) - // assert.NotContains(t, proto, bsnet.ProtocolBitswapOneOne, "bitswap protocol %s should not be advertised when server is disabled", proto) - // assert.NotContains(t, proto, bsnet.ProtocolBitswapOneZero, "bitswap protocol %s should not be advertised when server is disabled", proto) - // } - // }) + // Disabling Bitswap.Libp2pEnabled should remove /ipfs/bitswap* protocols from `ipfs id` + t.Run("disabling bitswap over libp2p removes it from identify protocol list", func(t *testing.T) { + t.Parallel() + h := harness.NewT(t) + + provider := h.NewNode().Init() + provider.UpdateConfig(func(cfg *config.Config) { + cfg.Bitswap.Libp2pEnabled = config.False + cfg.Bitswap.ServerEnabled = config.False + cfg.HTTPRetrieval.Enabled = config.True + }) + provider = provider.StartDaemon() + requester := h.NewNode().Init().StartDaemon() + requester.Connect(provider) + + // read libp2p identify from remote peer, and print protocols + res := requester.IPFS("id", "-f", "", provider.PeerID().String()) + protocols := strings.Split(strings.TrimSpace(res.Stdout.String()), "\n") + + // No bitswap protocols should be present + for _, proto := range protocols { + assert.NotContains(t, proto, bsnet.ProtocolBitswap, "bitswap protocol %s should not be advertised when server is disabled", proto) + assert.NotContains(t, proto, bsnet.ProtocolBitswapNoVers, "bitswap protocol %s should not be advertised when server is disabled", proto) + assert.NotContains(t, proto, bsnet.ProtocolBitswapOneOne, "bitswap protocol %s should not be advertised when server is disabled", proto) + assert.NotContains(t, proto, bsnet.ProtocolBitswapOneZero, "bitswap protocol %s should not be advertised when server is disabled", proto) + } + }) + + // HTTPRetrieval uses bitswap engine, we need it + t.Run("errors when both HTTP and libp2p are disabled", func(t *testing.T) { + t.Parallel() + + // init Kubo repo + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.HTTPRetrieval.Enabled = config.False + cfg.Bitswap.Libp2pEnabled = config.False + cfg.Bitswap.ServerEnabled = config.Default + }) + res := node.RunIPFS("daemon") + assert.Contains(t, res.Stderr.Trimmed(), "invalid configuration: Bitswap.Libp2pEnabled and HTTPRetrieval.Enabled are both disabled, unable to initialize Bitswap") + assert.Equal(t, 1, res.ExitCode()) + }) + + // HTTPRetrieval uses bitswap engine, we need it + t.Run("errors when user set conflicting HTTP and libp2p flags", func(t *testing.T) { + t.Parallel() + + // init Kubo repo + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.HTTPRetrieval.Enabled = config.False + cfg.Bitswap.Libp2pEnabled = config.False + cfg.Bitswap.ServerEnabled = config.True // bad user config: cant enable server when libp2p is down + }) + res := node.RunIPFS("daemon") + assert.Contains(t, res.Stderr.Trimmed(), "invalid configuration: Bitswap.Libp2pEnabled and HTTPRetrieval.Enabled are both disabled, unable to initialize Bitswap") + assert.Equal(t, 1, res.ExitCode()) + }) } diff --git a/test/cli/content_routing_http_test.go b/test/cli/content_routing_http_test.go index aea5c41caeb..4b210cfbaef 100644 --- a/test/cli/content_routing_http_test.go +++ b/test/cli/content_routing_http_test.go @@ -1,69 +1,20 @@ package cli import ( - "context" "net/http" "net/http/httptest" "os/exec" - "sync" "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/config" "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/ipfs/kubo/test/cli/testutils/httprouting" "github.com/stretchr/testify/assert" ) -type fakeHTTPContentRouter struct { - m sync.Mutex - provideBitswapCalls int - findProvidersCalls int - findPeersCalls int -} - -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.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.provideBitswapCalls++ - return 0, nil -} - -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.PeerRecord]{}), nil -} - -func (r *fakeHTTPContentRouter) GetIPNS(ctx context.Context, name ipns.Name) (*ipns.Record, error) { - return nil, routing.ErrNotSupported -} - -func (r *fakeHTTPContentRouter) PutIPNS(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() - return r.findProvidersCalls -} - // userAgentRecorder records the user agent of every HTTP request type userAgentRecorder struct { delegate http.Handler @@ -76,16 +27,19 @@ func (r *userAgentRecorder) ServeHTTP(w http.ResponseWriter, req *http.Request) } func TestContentRoutingHTTP(t *testing.T) { - cr := &fakeHTTPContentRouter{} + mockRouter := &httprouting.MockHTTPContentRouter{} // run the content routing HTTP server - userAgentRecorder := &userAgentRecorder{delegate: server.Handler(cr)} + userAgentRecorder := &userAgentRecorder{delegate: server.Handler(mockRouter)} 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.UpdateConfig(func(cfg *config.Config) { + // setup Kubo node to use mocked HTTP Router + cfg.Routing.DelegatedRouters = []string{server.URL} + }) node.StartDaemon() // compute a random CID @@ -107,7 +61,7 @@ func TestContentRoutingHTTP(t *testing.T) { // verify the content router was called assert.Eventually(t, func() bool { - return cr.numFindProvidersCalls() > 0 + return mockRouter.NumFindProvidersCalls() > 0 }, time.Minute, 10*time.Millisecond) assert.NotEmpty(t, userAgentRecorder.userAgents) diff --git a/test/cli/http_retrieval_client_test.go b/test/cli/http_retrieval_client_test.go new file mode 100644 index 00000000000..f845c818ef5 --- /dev/null +++ b/test/cli/http_retrieval_client_test.go @@ -0,0 +1,145 @@ +package cli + +import ( + "fmt" + "net" + "net/http" + "net/http/httptest" + "net/url" + "os" + "strings" + "testing" + + "github.com/ipfs/boxo/routing/http/server" + "github.com/ipfs/boxo/routing/http/types" + "github.com/ipfs/go-cid" + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/test/cli/harness" + "github.com/ipfs/kubo/test/cli/testutils" + "github.com/ipfs/kubo/test/cli/testutils/httprouting" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/multiformats/go-multiaddr" + "github.com/stretchr/testify/assert" +) + +func TestHTTPRetrievalClient(t *testing.T) { + t.Parallel() + + // many moving pieces here, show more when debug is needed + debug := os.Getenv("DEBUG") == "true" + + // usee local /routing/v1/providers/{cid} and + // /ipfs/{cid} HTTP servers to confirm HTTP-only retrieval works end-to-end. + t.Run("works end-to-end with an HTTP-only provider", func(t *testing.T) { + // setup mocked HTTP Router to handle /routing/v1/providers/cid + mockRouter := &httprouting.MockHTTPContentRouter{Debug: debug} + delegatedRoutingServer := httptest.NewServer(server.Handler(mockRouter)) + t.Cleanup(func() { delegatedRoutingServer.Close() }) + + // init Kubo repo + node := harness.NewT(t).NewNode().Init() + + node.UpdateConfig(func(cfg *config.Config) { + // explicitly enable http client + cfg.HTTPRetrieval.Enabled = config.True + // allow NewMockHTTPProviderServer to use self-signed TLS cert + cfg.HTTPRetrieval.TLSInsecureSkipVerify = config.True + // setup client-only routing which asks both HTTP + DHT + // cfg.Routing.Type = config.NewOptionalString("autoclient") + // setup Kubo node to use mocked HTTP Router + cfg.Routing.DelegatedRouters = []string{delegatedRoutingServer.URL} + }) + + // compute a random CID + randStr := string(testutils.RandomBytes(100)) + res := node.PipeStrToIPFS(randStr, "add", "-qn", "--cid-version", "1") // -n means dont add to local repo, just produce CID + wantCIDStr := res.Stdout.Trimmed() + testCid := cid.MustParse(wantCIDStr) + + // setup mock HTTP provider + httpProviderServer := NewMockHTTPProviderServer(testCid, randStr, debug) + t.Cleanup(func() { httpProviderServer.Close() }) + httpHost, httpPort, err := splitHostPort(httpProviderServer.URL) + assert.NoError(t, err) + + // setup /routing/v1/providers/cid result that points at our mocked HTTP provider + mockHTTPProviderPeerID := "12D3KooWCjfPiojcCUmv78Wd1NJzi4Mraj1moxigp7AfQVQvGLwH" // static, it does not matter, we only care about multiaddr + mockHTTPMultiaddr, _ := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/%s/tcp/%s/tls/http", httpHost, httpPort)) + mpid, _ := peer.Decode(mockHTTPProviderPeerID) + mockRouter.AddProvider(testCid, &types.PeerRecord{ + Schema: types.SchemaPeer, + ID: &mpid, + Addrs: []types.Multiaddr{{Multiaddr: mockHTTPMultiaddr}}, + // no explicit Protocols, ensure multiaddr alone is enough + }) + + // Start Kubo + node.StartDaemon() + + if debug { + fmt.Printf("delegatedRoutingServer.URL: %s\n", delegatedRoutingServer.URL) + fmt.Printf("httpProviderServer.URL: %s\n", httpProviderServer.URL) + fmt.Printf("httpProviderServer.Multiaddr: %s\n", mockHTTPMultiaddr) + fmt.Printf("testCid: %s\n", testCid) + } + + // Now, make Kubo to read testCid. it was not added to local blockstore, so it has only one provider -- a HTTP server. + + // First, confirm delegatedRoutingServer returned HTTP provider + findprovsRes := node.IPFS("routing", "findprovs", testCid.String()) + assert.Equal(t, mockHTTPProviderPeerID, findprovsRes.Stdout.Trimmed()) + + // Ok, now attempt retrieval. + // If there was no timeout and returned bytes match expected body, HTTP routing and retrieval worked end-to-end. + catRes := node.IPFS("cat", testCid.String()) + assert.Equal(t, randStr, catRes.Stdout.Trimmed()) + }) +} + +// NewMockHTTPProviderServer pretends to be http provider that supports +// block response https://specs.ipfs.tech/http-gateways/trustless-gateway/#block-responses-application-vnd-ipld-raw +func NewMockHTTPProviderServer(c cid.Cid, body string, debug bool) *httptest.Server { + expectedPathPrefix := "/ipfs/" + c.String() + handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + if debug { + fmt.Printf("NewMockHTTPProviderServer GET %s\n", req.URL.Path) + } + if strings.HasPrefix(req.URL.Path, expectedPathPrefix) { + w.Header().Set("Content-Type", "application/vnd.ipld.raw") + w.WriteHeader(http.StatusOK) + if req.Method == "GET" { + _, err := w.Write([]byte(body)) + if err != nil { + fmt.Fprintf(os.Stderr, "NewMockHTTPProviderServer GET %s error: %v\n", req.URL.Path, err) + } + } + } else if strings.HasPrefix(req.URL.Path, "/ipfs/bafkqaaa") { + // This is probe from https://specs.ipfs.tech/http-gateways/trustless-gateway/#dedicated-probe-paths + w.Header().Set("Content-Type", "application/vnd.ipld.raw") + w.WriteHeader(http.StatusOK) + } else { + http.Error(w, "Not Found", http.StatusNotFound) + } + }) + + // Make it HTTP/2 with self-signed TLS cert + srv := httptest.NewUnstartedServer(handler) + srv.EnableHTTP2 = true + srv.StartTLS() + return srv +} + +func splitHostPort(httpUrl string) (ipAddr string, port string, err error) { + u, err := url.Parse(httpUrl) + if err != nil { + return "", "", err + } + if u.Scheme == "" || u.Host == "" { + return "", "", fmt.Errorf("invalid URL format: missing scheme or host") + } + ipAddr, port, err = net.SplitHostPort(u.Host) + if err != nil { + return "", "", fmt.Errorf("failed to split host and port from %q: %w", u.Host, err) + } + return ipAddr, port, nil +} diff --git a/test/cli/testutils/httprouting/mock_http_content_router.go b/test/cli/testutils/httprouting/mock_http_content_router.go new file mode 100644 index 00000000000..8f6f3102387 --- /dev/null +++ b/test/cli/testutils/httprouting/mock_http_content_router.go @@ -0,0 +1,117 @@ +package httprouting + +import ( + "context" + "fmt" + "sync" + "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/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/routing" +) + +// MockHTTPContentRouter provides /routing/v1 +// (https://specs.ipfs.tech/routing/http-routing-v1/) server implementation +// based on github.com/ipfs/boxo/routing/http/server +type MockHTTPContentRouter struct { + m sync.Mutex + provideBitswapCalls int + findProvidersCalls int + findPeersCalls int + providers map[cid.Cid][]types.Record + peers map[peer.ID][]*types.PeerRecord + Debug bool +} + +func (r *MockHTTPContentRouter) FindProviders(ctx context.Context, key cid.Cid, limit int) (iter.ResultIter[types.Record], error) { + if r.Debug { + fmt.Printf("MockHTTPContentRouter.FindProviders(%s)\n", key.String()) + } + r.m.Lock() + defer r.m.Unlock() + r.findProvidersCalls++ + if r.providers == nil { + r.providers = make(map[cid.Cid][]types.Record) + } + records, found := r.providers[key] + if !found { + return iter.FromSlice([]iter.Result[types.Record]{}), nil + } + results := make([]iter.Result[types.Record], len(records)) + for i, rec := range records { + results[i] = iter.Result[types.Record]{Val: rec} + if r.Debug { + fmt.Printf("MockHTTPContentRouter.FindProviders(%s) result: %+v\n", key.String(), rec) + } + } + return iter.FromSlice(results), nil +} + +// nolint deprecated +func (r *MockHTTPContentRouter) ProvideBitswap(ctx context.Context, req *server.BitswapWriteProvideRequest) (time.Duration, error) { + r.m.Lock() + defer r.m.Unlock() + r.provideBitswapCalls++ + return 0, nil +} + +func (r *MockHTTPContentRouter) FindPeers(ctx context.Context, pid peer.ID, limit int) (iter.ResultIter[*types.PeerRecord], error) { + r.m.Lock() + defer r.m.Unlock() + r.findPeersCalls++ + + if r.peers == nil { + r.peers = make(map[peer.ID][]*types.PeerRecord) + } + records, found := r.peers[pid] + if !found { + return iter.FromSlice([]iter.Result[*types.PeerRecord]{}), nil + } + + results := make([]iter.Result[*types.PeerRecord], len(records)) + for i, rec := range records { + results[i] = iter.Result[*types.PeerRecord]{Val: rec} + if r.Debug { + fmt.Printf("MockHTTPContentRouter.FindPeers(%s) result: %+v\n", pid.String(), rec) + } + } + return iter.FromSlice(results), nil +} + +func (r *MockHTTPContentRouter) GetIPNS(ctx context.Context, name ipns.Name) (*ipns.Record, error) { + return nil, routing.ErrNotSupported +} + +func (r *MockHTTPContentRouter) PutIPNS(ctx context.Context, name ipns.Name, rec *ipns.Record) error { + return routing.ErrNotSupported +} + +func (r *MockHTTPContentRouter) NumFindProvidersCalls() int { + r.m.Lock() + defer r.m.Unlock() + return r.findProvidersCalls +} + +// AddProvider adds a record for a given CID +func (r *MockHTTPContentRouter) AddProvider(key cid.Cid, record types.Record) { + r.m.Lock() + defer r.m.Unlock() + if r.providers == nil { + r.providers = make(map[cid.Cid][]types.Record) + } + r.providers[key] = append(r.providers[key], record) + + peerRecord, ok := record.(*types.PeerRecord) + if ok { + if r.peers == nil { + r.peers = make(map[peer.ID][]*types.PeerRecord) + } + pid := peerRecord.ID + r.peers[*pid] = append(r.peers[*pid], peerRecord) + } +} From 7c844baceadf991ca49f427f4ac17b0eab4b314f Mon Sep 17 00:00:00 2001 From: Sergey Gorbunov Date: Tue, 6 May 2025 22:55:53 +0300 Subject: [PATCH 31/42] feat(fuse): Expose MFS as FUSE mount point (#10781) * Add MFS command line options, extend existing mount functions for MFS, set defaults. * Directory listing and file stat. * Add a read-only MFS view. * Add mkdir and interface checks. * Add remove and rename functionality. * Implement all required write interfaces. * Adjust mount functions for other architechtures. * Merge branch 'master' into feat/10710-mfs-fuse-mount * Write a basic read/write test. * Write more basic tests, add a mutex to the file object, fix modtime. * Add a concurrency test, remove mutexes from file and directory structures. * Refactor naming(mfdir -> mfsdir) and add documentation. * Add CID retrieval through ipfs_cid xattr. * Add docs, add xattr listing, fix bugs for mv and stat, refactor. * Add MFS command line options, extend existing mount functions for MFS, set defaults. * docs phrasing * docs: Mounts.MFS * docs: warn about lazy-loaded DAGs * test: TEST_FUSE=1 ./t0030-mount.sh -v --------- Co-authored-by: Guillaume Michel Co-authored-by: guillaumemichel Co-authored-by: Marcin Rataj --- cmd/ipfs/kubo/daemon.go | 10 +- config/init.go | 1 + config/mounts.go | 1 + core/commands/mount_nofuse.go | 5 +- core/commands/mount_unix.go | 22 +- core/core.go | 1 + docs/changelogs/v0.35.md | 9 + docs/config.md | 16 +- docs/experimental-features.md | 2 +- docs/fuse.md | 28 +- fuse/mfs/mfs_test.go | 342 ++++++++++++++++++++ fuse/mfs/mfs_unix.go | 414 +++++++++++++++++++++++++ fuse/mfs/mount_unix.go | 21 ++ fuse/node/mount_nofuse.go | 2 +- fuse/node/mount_notsupp.go | 2 +- fuse/node/mount_test.go | 4 +- fuse/node/mount_unix.go | 36 ++- fuse/node/mount_windows.go | 2 +- test/3nodetest/bootstrap/config | 3 +- test/3nodetest/client/config | 3 +- test/3nodetest/server/config | 3 +- test/cli/bitswap_config_test.go | 2 +- test/sharness/lib/test-lib.sh | 7 +- test/sharness/t0030-mount.sh | 64 +++- test/sharness/t0270-filestore.sh | 2 +- test/sharness/t0271-filestore-utils.sh | 2 +- 26 files changed, 962 insertions(+), 42 deletions(-) create mode 100644 fuse/mfs/mfs_test.go create mode 100644 fuse/mfs/mfs_unix.go create mode 100644 fuse/mfs/mount_unix.go diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index 3676ed89139..ea6ccfc1dbe 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -56,6 +56,7 @@ const ( initProfileOptionKwd = "init-profile" ipfsMountKwd = "mount-ipfs" ipnsMountKwd = "mount-ipns" + mfsMountKwd = "mount-mfs" migrateKwd = "migrate" mountKwd = "mount" offlineKwd = "offline" // global option @@ -173,6 +174,7 @@ Headers. 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.StringOption(mfsMountKwd, "Path to the mountpoint for MFS (if using --mount). Defaults to config setting."), 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"), @@ -1062,17 +1064,23 @@ func mountFuse(req *cmds.Request, cctx *oldcmds.Context) error { nsdir = cfg.Mounts.IPNS } + mfsdir, found := req.Options[mfsMountKwd].(string) + if !found { + mfsdir = cfg.Mounts.MFS + } + node, err := cctx.ConstructNode() if err != nil { return fmt.Errorf("mountFuse: ConstructNode() failed: %s", err) } - err = nodeMount.Mount(node, fsdir, nsdir) + err = nodeMount.Mount(node, fsdir, nsdir, mfsdir) if err != nil { return err } fmt.Printf("IPFS mounted at: %s\n", fsdir) fmt.Printf("IPNS mounted at: %s\n", nsdir) + fmt.Printf("MFS mounted at: %s\n", mfsdir) return nil } diff --git a/config/init.go b/config/init.go index a40efdead28..40c24bd25d9 100644 --- a/config/init.go +++ b/config/init.go @@ -52,6 +52,7 @@ func InitWithIdentity(identity Identity) (*Config, error) { Mounts: Mounts{ IPFS: "/ipfs", IPNS: "/ipns", + MFS: "/mfs", }, Ipns: Ipns{ diff --git a/config/mounts.go b/config/mounts.go index dfdd1e5bf6c..571316cf386 100644 --- a/config/mounts.go +++ b/config/mounts.go @@ -4,5 +4,6 @@ package config type Mounts struct { IPFS string IPNS string + MFS string FuseAllowOther bool } diff --git a/core/commands/mount_nofuse.go b/core/commands/mount_nofuse.go index c425aff0fcf..103678e77ca 100644 --- a/core/commands/mount_nofuse.go +++ b/core/commands/mount_nofuse.go @@ -14,10 +14,11 @@ var MountCmd = &cmds.Command{ ShortDescription: ` This version of ipfs is compiled without fuse support, which is required for mounting. If you'd like to be able to mount, please use a version of -ipfs compiled with fuse. +Kubo compiled with fuse. For the latest instructions, please check the project's repository: - http://github.com/ipfs/go-ipfs + http://github.com/ipfs/kubo + https://github.com/ipfs/kubo/blob/master/docs/fuse.md `, }, } diff --git a/core/commands/mount_unix.go b/core/commands/mount_unix.go index 52a1b843b80..6051f86aa6f 100644 --- a/core/commands/mount_unix.go +++ b/core/commands/mount_unix.go @@ -18,6 +18,7 @@ import ( const ( mountIPFSPathOptionName = "ipfs-path" mountIPNSPathOptionName = "ipns-path" + mountMFSPathOptionName = "mfs-path" ) var MountCmd = &cmds.Command{ @@ -25,14 +26,14 @@ var MountCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Mounts IPFS to the filesystem (read-only).", ShortDescription: ` -Mount IPFS at a read-only mountpoint on the OS (default: /ipfs and /ipns). +Mount IPFS at a read-only mountpoint on the OS (default: /ipfs, /ipns, /mfs). All IPFS objects will be accessible under that directory. Note that the root will not be listable, as it is virtual. Access known paths directly. You may have to create /ipfs and /ipns before using 'ipfs mount': -> sudo mkdir /ipfs /ipns -> sudo chown $(whoami) /ipfs /ipns +> sudo mkdir /ipfs /ipns /mfs +> sudo chown $(whoami) /ipfs /ipns /mfs > ipfs daemon & > ipfs mount `, @@ -44,8 +45,8 @@ root will not be listable, as it is virtual. Access known paths directly. You may have to create /ipfs and /ipns before using 'ipfs mount': -> sudo mkdir /ipfs /ipns -> sudo chown $(whoami) /ipfs /ipns +> sudo mkdir /ipfs /ipns /mfs +> sudo chown $(whoami) /ipfs /ipns /mfs > ipfs daemon & > ipfs mount @@ -67,6 +68,7 @@ baz > ipfs mount IPFS mounted at: /ipfs IPNS mounted at: /ipns +MFS mounted at: /mfs > cd /ipfs/QmSh5e7S6fdcu75LAbXNZAFY2nGyZUJXyLCJDvn2zRkWyC > ls bar @@ -81,6 +83,7 @@ baz Options: []cmds.Option{ cmds.StringOption(mountIPFSPathOptionName, "f", "The path where IPFS should be mounted."), cmds.StringOption(mountIPNSPathOptionName, "n", "The path where IPNS should be mounted."), + cmds.StringOption(mountMFSPathOptionName, "m", "The path where MFS should be mounted."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { cfg, err := env.(*oldcmds.Context).GetConfig() @@ -109,7 +112,12 @@ baz nsdir = cfg.Mounts.IPNS // NB: be sure to not redeclare! } - err = nodeMount.Mount(nd, fsdir, nsdir) + mfsdir, found := req.Options[mountMFSPathOptionName].(string) + if !found { + mfsdir = cfg.Mounts.MFS + } + + err = nodeMount.Mount(nd, fsdir, nsdir, mfsdir) if err != nil { return err } @@ -117,6 +125,7 @@ baz var output config.Mounts output.IPFS = fsdir output.IPNS = nsdir + output.MFS = mfsdir return cmds.EmitOnce(res, &output) }, Type: config.Mounts{}, @@ -124,6 +133,7 @@ baz cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, mounts *config.Mounts) error { fmt.Fprintf(w, "IPFS mounted at: %s\n", cmdenv.EscNonPrint(mounts.IPFS)) fmt.Fprintf(w, "IPNS mounted at: %s\n", cmdenv.EscNonPrint(mounts.IPNS)) + fmt.Fprintf(w, "MFS mounted at: %s\n", cmdenv.EscNonPrint(mounts.MFS)) return nil }), diff --git a/core/core.go b/core/core.go index 54c98752762..3440895e72b 100644 --- a/core/core.go +++ b/core/core.go @@ -134,6 +134,7 @@ type IpfsNode struct { type Mounts struct { Ipfs mount.Mount Ipns mount.Mount + Mfs mount.Mount } // Close calls Close() on the App object diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index 2826541cc57..c5fccf7ad1e 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -12,6 +12,7 @@ This release was brought to you by the [Shipyard](http://ipshipyard.com/) team. - [πŸ”¦ Highlights](#-highlights) - [Opt-in HTTP Retrieval client](#opt-in-http-retrieval-client) - [Dedicated `Reprovider.Strategy` for MFS](#dedicated-reproviderstrategy-for-mfs) + - [Experimental support for MFS as a FUSE mount point](#experimental-support-for-mfs-as-a-fuse-mount-point) - [Grid view in WebUI](#grid-view-in-webui) - [Enhanced DAG-Shaping Controls](#enhanced-dag-shaping-controls) - [New DAG-Shaping `ipfs add` Options](#new-dag-shaping-ipfs-add-options) @@ -64,6 +65,14 @@ Users relying on the `pinned` strategy can switch to `pinned+mfs` and use MFS al See [`Reprovider.Strategy`](https://github.com/ipfs/kubo/blob/master/docs/config.md#reproviderstrategy) for more details. +#### Experimental support for MFS as a FUSE mount point + +The MFS root (filesystem behind the `ipfs files` API) is now available as a read/write FUSE mount point at `Mounts.MFS`. This filesystem is mounted in the same way as `Mounts.IPFS` and `Mounts.IPNS` when running `ipfs mount` or `ipfs daemon --mount`. + +Note that the operations supported by the MFS FUSE mountpoint are limited, since MFS doesn't store file attributes. + +See [`Mounts`](https://github.com/ipfs/kubo/blob/master/docs/config.md#mounts) and [`docs/fuse.md`](https://github.com/ipfs/kubo/blob/master/docs/fuse.md) for more details. + #### Grid view in WebUI The WebUI, accessible at http://127.0.0.1:5001/webui/, now includes support for the grid view on the _Files_ screen: diff --git a/docs/config.md b/docs/config.md index 91cefe8dc92..3da157d19ac 100644 --- a/docs/config.md +++ b/docs/config.md @@ -97,6 +97,7 @@ config file at runtime. - [`Mounts`](#mounts) - [`Mounts.IPFS`](#mountsipfs) - [`Mounts.IPNS`](#mountsipns) + - [`Mounts.MFS`](#mountsmfs) - [`Mounts.FuseAllowOther`](#mountsfuseallowother) - [`Pinning`](#pinning) - [`Pinning.RemoteServices`](#pinningremoteservices) @@ -1368,7 +1369,8 @@ Default: `cache` ## `Mounts` -**EXPERIMENTAL:** read about current limitations at [fuse.md](./fuse.md). +> [!CAUTION] +> **EXPERIMENTAL:** read about current limitations at [fuse.md](./fuse.md). FUSE mount point configuration options. @@ -1388,6 +1390,18 @@ Default: `/ipns` Type: `string` (filesystem path) +### `Mounts.MFS` + +Mountpoint for Mutable File System (MFS) behind the `ipfs files` API. + +> [!CAUTION] +> - Write support is highly experimental and not recommended for mission-critical deployments. +> - Avoid storing lazy-loaded datasets in MFS. Exposing a partially local, lazy-loaded DAG risks operating system search indexers crawling it, which may trigger unintended network prefetching of non-local DAG components. + +Default: `/mfs` + +Type: `string` (filesystem path) + ### `Mounts.FuseAllowOther` Sets the 'FUSE allow other'-option on the mount point. diff --git a/docs/experimental-features.md b/docs/experimental-features.md index c0832b2e149..7d0069fc6f7 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -404,7 +404,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, +FUSE makes it possible to mount `/ipfs`, `/ipns` and `/mfs` namespaces in your OS, 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/fuse.md b/docs/fuse.md index b4b966e5240..fde9307fd37 100644 --- a/docs/fuse.md +++ b/docs/fuse.md @@ -2,7 +2,7 @@ **EXPERIMENTAL:** FUSE support is limited, YMMV. -Kubo makes it possible to mount `/ipfs` and `/ipns` namespaces in your OS, +Kubo makes it possible to mount `/ipfs`, `/ipns` and `/mfs` namespaces in your OS, allowing arbitrary apps access to IPFS. ## Install FUSE @@ -50,18 +50,20 @@ speak with us, or if you figure something new out, please add to this document! ## Prepare mountpoints -By default ipfs uses `/ipfs` and `/ipns` directories for mounting, this can be -changed in config. You will have to create the `/ipfs` and `/ipns` directories +By default ipfs uses `/ipfs`, `/ipns` and `/mfs` directories for mounting, this can be +changed in config. You will have to create the `/ipfs`, `/ipns` and `/mfs` directories explicitly. Note that modifying root requires sudo permissions. ```sh # make the directories sudo mkdir /ipfs sudo mkdir /ipns +sudo mkdir /mfs # chown them so ipfs can use them without root permissions sudo chown /ipfs sudo chown /ipns +sudo chown /mfs ``` Depending on whether you are using OSX or Linux, follow the proceeding instructions. @@ -105,6 +107,25 @@ ipfs config --json Mounts.FuseAllowOther true ipfs daemon --mount ``` +## MFS mountpoint + +Kubo v0.35.0 and later supports mounting the MFS (Mutable File System) root as +a FUSE filesystem, enabling manipulation of content-addressed data like regular +files. The CID for any file or directory is retrievable via the `ipfs_cid` +extended attribute. + +```sh +getfattr -n ipfs_cid /mfs/welcome-to-IPFS.jpg +getfattr: Removing leading '/' from absolute path names +# file: mfs/welcome-to-IPFS.jpg +ipfs_cid="QmaeXDdwpUeKQcMy7d5SFBfVB4y7LtREbhm5KizawPsBSH" +``` + +Please note that the operations supported by the MFS FUSE mountpoint are +limited. Since the MFS wasn't designed to store file attributes like ownership +information, permissions and creation date, some applications like `vim` and +`sed` may misbehave due to missing functionality. + ## Troubleshooting #### `Permission denied` or `fusermount: user has no write access to mountpoint` error in Linux @@ -145,6 +166,7 @@ set for user running `ipfs mount` command. ``` sudo umount /ipfs sudo umount /ipns +sudo umount /mfs ``` #### Mounting fails with "error mounting: could not resolve name" diff --git a/fuse/mfs/mfs_test.go b/fuse/mfs/mfs_test.go new file mode 100644 index 00000000000..cedbe996723 --- /dev/null +++ b/fuse/mfs/mfs_test.go @@ -0,0 +1,342 @@ +//go:build !nofuse && !openbsd && !netbsd && !plan9 +// +build !nofuse,!openbsd,!netbsd,!plan9 + +package mfs + +import ( + "bytes" + "context" + "crypto/rand" + "errors" + iofs "io/fs" + "os" + "slices" + "strconv" + "testing" + "time" + + "bazil.org/fuse" + "bazil.org/fuse/fs" + "bazil.org/fuse/fs/fstestutil" + "github.com/ipfs/kubo/core" + "github.com/ipfs/kubo/core/node" + "github.com/libp2p/go-libp2p-testing/ci" +) + +// Create an Ipfs.Node, a filesystem and a mount point. +func setUp(t *testing.T, ipfs *core.IpfsNode) (fs.FS, *fstestutil.Mount) { + if ci.NoFuse() { + t.Skip("Skipping FUSE tests") + } + + if ipfs == nil { + var err error + ipfs, err = core.NewNode(context.Background(), &node.BuildCfg{}) + if err != nil { + t.Fatal(err) + } + } + + fs := NewFileSystem(ipfs) + mnt, err := fstestutil.MountedT(t, fs, nil) + if err == fuse.ErrOSXFUSENotFound { + t.Skip(err) + } + if err != nil { + t.Fatal(err) + } + + return fs, mnt +} + +// Test reading and writing a file. +func TestReadWrite(t *testing.T) { + _, mnt := setUp(t, nil) + defer mnt.Close() + + path := mnt.Dir + "/testrw" + content := make([]byte, 8196) + _, err := rand.Read(content) + if err != nil { + t.Fatal(err) + } + + t.Run("write", func(t *testing.T) { + f, err := os.Create(path) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + _, err = f.Write(content) + if err != nil { + t.Fatal(err) + } + }) + t.Run("read", func(t *testing.T) { + f, err := os.Open(path) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + buf := make([]byte, 8196) + l, err := f.Read(buf) + if err != nil { + t.Fatal(err) + } + if bytes.Equal(content, buf[:l]) != true { + t.Fatal("read and write not equal") + } + }) +} + +// Test creating a directory. +func TestMkdir(t *testing.T) { + _, mnt := setUp(t, nil) + defer mnt.Close() + + path := mnt.Dir + "/foo/bar/baz/qux/quux" + + t.Run("write", func(t *testing.T) { + err := os.MkdirAll(path, iofs.ModeDir) + if err != nil { + t.Fatal(err) + } + }) + t.Run("read", func(t *testing.T) { + stat, err := os.Stat(path) + if err != nil { + t.Fatal(err) + } + if !stat.IsDir() { + t.Fatal("not dir") + } + }) +} + +// Test file persistence across mounts. +func TestPersistence(t *testing.T) { + ipfs, err := core.NewNode(context.Background(), &node.BuildCfg{}) + if err != nil { + t.Fatal(err) + } + + content := make([]byte, 8196) + _, err = rand.Read(content) + if err != nil { + t.Fatal(err) + } + + t.Run("write", func(t *testing.T) { + _, mnt := setUp(t, ipfs) + defer mnt.Close() + path := mnt.Dir + "/testpersistence" + + f, err := os.Create(path) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + _, err = f.Write(content) + if err != nil { + t.Fatal(err) + } + }) + t.Run("read", func(t *testing.T) { + _, mnt := setUp(t, ipfs) + defer mnt.Close() + path := mnt.Dir + "/testpersistence" + + f, err := os.Open(path) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + buf := make([]byte, 8196) + l, err := f.Read(buf) + if err != nil { + t.Fatal(err) + } + if bytes.Equal(content, buf[:l]) != true { + t.Fatal("read and write not equal") + } + }) +} + +// Test getting the file attributes. +func TestAttr(t *testing.T) { + _, mnt := setUp(t, nil) + defer mnt.Close() + + path := mnt.Dir + "/testattr" + content := make([]byte, 8196) + _, err := rand.Read(content) + if err != nil { + t.Fatal(err) + } + + t.Run("write", func(t *testing.T) { + f, err := os.Create(path) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + _, err = f.Write(content) + if err != nil { + t.Fatal(err) + } + }) + t.Run("read", func(t *testing.T) { + fi, err := os.Stat(path) + if err != nil { + t.Fatal(err) + } + + if fi.IsDir() { + t.Fatal("file is a directory") + } + + if fi.ModTime().After(time.Now()) { + t.Fatal("future modtime") + } + if time.Since(fi.ModTime()) > time.Second { + t.Fatal("past modtime") + } + + if fi.Name() != "testattr" { + t.Fatal("invalid filename") + } + + if fi.Size() != 8196 { + t.Fatal("invalid size") + } + }) +} + +// Test concurrent access to the filesystem. +func TestConcurrentRW(t *testing.T) { + _, mnt := setUp(t, nil) + defer mnt.Close() + + files := 5 + fileWorkers := 5 + + path := mnt.Dir + "/testconcurrent" + content := make([][]byte, files) + + for i := range content { + content[i] = make([]byte, 8196) + _, err := rand.Read(content[i]) + if err != nil { + t.Fatal(err) + } + } + + t.Run("write", func(t *testing.T) { + errs := make(chan (error), 1) + for i := 0; i < files; i++ { + go func() { + var err error + defer func() { errs <- err }() + + f, err := os.Create(path + strconv.Itoa(i)) + if err != nil { + return + } + defer f.Close() + + _, err = f.Write(content[i]) + if err != nil { + return + } + }() + } + for i := 0; i < files; i++ { + err := <-errs + if err != nil { + t.Fatal(err) + } + } + }) + t.Run("read", func(t *testing.T) { + errs := make(chan (error), 1) + for i := 0; i < files*fileWorkers; i++ { + go func() { + var err error + defer func() { errs <- err }() + + f, err := os.Open(path + strconv.Itoa(i/fileWorkers)) + if err != nil { + return + } + defer f.Close() + + buf := make([]byte, 8196) + l, err := f.Read(buf) + if err != nil { + return + } + if bytes.Equal(content[i/fileWorkers], buf[:l]) != true { + err = errors.New("read and write not equal") + return + } + }() + } + for i := 0; i < files; i++ { + err := <-errs + if err != nil { + t.Fatal(err) + } + } + }) +} + +// Test ipfs_cid extended attribute +func TestMFSRootXattr(t *testing.T) { + ipfs, err := core.NewNode(context.Background(), &node.BuildCfg{}) + if err != nil { + t.Fatal(err) + } + + fs, mnt := setUp(t, ipfs) + defer mnt.Close() + + node, err := fs.Root() + if err != nil { + t.Fatal(err) + } + + root := node.(*Dir) + + listReq := fuse.ListxattrRequest{} + listRes := fuse.ListxattrResponse{} + err = root.Listxattr(context.Background(), &listReq, &listRes) + if err != nil { + t.Fatal(err) + } + if slices.Compare(listRes.Xattr, []byte("ipfs_cid\x00")) != 0 { + t.Fatal("list xattr returns invalid value") + } + + getReq := fuse.GetxattrRequest{ + Name: "ipfs_cid", + } + getRes := fuse.GetxattrResponse{} + err = root.Getxattr(context.Background(), &getReq, &getRes) + if err != nil { + t.Fatal(err) + } + + ipldNode, err := ipfs.FilesRoot.GetDirectory().GetNode() + if err != nil { + t.Fatal(err) + } + + if slices.Compare(getRes.Xattr, []byte(ipldNode.Cid().String())) != 0 { + t.Fatal("xattr cid not equal to mfs root cid") + } +} diff --git a/fuse/mfs/mfs_unix.go b/fuse/mfs/mfs_unix.go new file mode 100644 index 00000000000..91cad257d92 --- /dev/null +++ b/fuse/mfs/mfs_unix.go @@ -0,0 +1,414 @@ +//go:build (linux || darwin || freebsd || netbsd || openbsd) && !nofuse +// +build linux darwin freebsd netbsd openbsd +// +build !nofuse + +package mfs + +import ( + "context" + "io" + "os" + "sync" + "syscall" + "time" + + "bazil.org/fuse" + "bazil.org/fuse/fs" + + dag "github.com/ipfs/boxo/ipld/merkledag" + ft "github.com/ipfs/boxo/ipld/unixfs" + "github.com/ipfs/boxo/mfs" + "github.com/ipfs/kubo/core" +) + +const ( + ipfsCIDXattr = "ipfs_cid" + mfsDirMode = os.ModeDir | 0755 + mfsFileMode = 0644 + blockSize = 512 + dirSize = 8 +) + +// FUSE filesystem mounted at /mfs. +type FileSystem struct { + root Dir +} + +// Get filesystem root. +func (fs *FileSystem) Root() (fs.Node, error) { + return &fs.root, nil +} + +// FUSE Adapter for MFS directories. +type Dir struct { + mfsDir *mfs.Directory +} + +// Directory attributes (stat). +func (dir *Dir) Attr(ctx context.Context, attr *fuse.Attr) error { + attr.Mode = mfsDirMode + attr.Size = dirSize * blockSize + attr.Blocks = dirSize + return nil +} + +// Access files in a directory. +func (dir *Dir) Lookup(ctx context.Context, req *fuse.LookupRequest, resp *fuse.LookupResponse) (fs.Node, error) { + mfsNode, err := dir.mfsDir.Child(req.Name) + switch err { + case os.ErrNotExist: + return nil, syscall.Errno(syscall.ENOENT) + case nil: + default: + return nil, err + } + + switch mfsNode.Type() { + case mfs.TDir: + result := Dir{ + mfsDir: mfsNode.(*mfs.Directory), + } + return &result, nil + case mfs.TFile: + result := File{ + mfsFile: mfsNode.(*mfs.File), + } + return &result, nil + } + + return nil, syscall.Errno(syscall.ENOENT) +} + +// List (ls) MFS directory. +func (dir *Dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { + var res []fuse.Dirent + nodes, err := dir.mfsDir.List(ctx) + if err != nil { + return nil, err + } + + for _, node := range nodes { + nodeType := fuse.DT_File + if node.Type == 1 { + nodeType = fuse.DT_Dir + } + res = append(res, fuse.Dirent{ + Type: nodeType, + Name: node.Name, + }) + } + return res, nil +} + +// Mkdir (mkdir) in MFS. +func (dir *Dir) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) { + mfsDir, err := dir.mfsDir.Mkdir(req.Name) + if err != nil { + return nil, err + } + return &Dir{ + mfsDir: mfsDir, + }, nil +} + +// Remove (rm/rmdir) an MFS file. +func (dir *Dir) Remove(ctx context.Context, req *fuse.RemoveRequest) error { + // Check for empty directory. + if req.Dir { + targetNode, err := dir.mfsDir.Child(req.Name) + if err != nil { + return err + } + target := targetNode.(*mfs.Directory) + + children, err := target.ListNames(ctx) + if err != nil { + return err + } + if len(children) > 0 { + return os.ErrExist + } + } + err := dir.mfsDir.Unlink(req.Name) + if err != nil { + return err + } + return dir.mfsDir.Flush() +} + +// Move (mv) an MFS file. +func (dir *Dir) Rename(ctx context.Context, req *fuse.RenameRequest, newDir fs.Node) error { + file, err := dir.mfsDir.Child(req.OldName) + if err != nil { + return err + } + node, err := file.GetNode() + if err != nil { + return err + } + targetDir := newDir.(*Dir) + + // Remove file if exists + err = targetDir.mfsDir.Unlink(req.NewName) + if err != nil && err != os.ErrNotExist { + return err + } + + err = targetDir.mfsDir.AddChild(req.NewName, node) + if err != nil { + return err + } + + err = dir.mfsDir.Unlink(req.OldName) + if err != nil { + return err + } + + return dir.mfsDir.Flush() +} + +// Create (touch) an MFS file. +func (dir *Dir) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (fs.Node, fs.Handle, error) { + node := dag.NodeWithData(ft.FilePBData(nil, 0)) + if err := node.SetCidBuilder(dir.mfsDir.GetCidBuilder()); err != nil { + return nil, nil, err + } + + if err := dir.mfsDir.AddChild(req.Name, node); err != nil { + return nil, nil, err + } + + if err := dir.mfsDir.Flush(); err != nil { + return nil, nil, err + } + + mfsNode, err := dir.mfsDir.Child(req.Name) + if err != nil { + return nil, nil, err + } + if err := mfsNode.SetModTime(time.Now()); err != nil { + return nil, nil, err + } + + mfsFile := mfsNode.(*mfs.File) + + file := File{ + mfsFile: mfsFile, + } + + // Read access flags and create a handler. + accessMode := req.Flags & fuse.OpenAccessModeMask + flags := mfs.Flags{ + Read: accessMode == fuse.OpenReadOnly || accessMode == fuse.OpenReadWrite, + Write: accessMode == fuse.OpenWriteOnly || accessMode == fuse.OpenReadWrite, + Sync: req.Flags|fuse.OpenSync > 0, + } + + fd, err := mfsFile.Open(flags) + if err != nil { + return nil, nil, err + } + handler := FileHandler{ + mfsFD: fd, + } + + return &file, &handler, nil +} + +// List dir xattr. +func (dir *Dir) Listxattr(ctx context.Context, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error { + resp.Append(ipfsCIDXattr) + return nil +} + +// Get dir xattr. +func (dir *Dir) Getxattr(ctx context.Context, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error { + switch req.Name { + case ipfsCIDXattr: + node, err := dir.mfsDir.GetNode() + if err != nil { + return err + } + resp.Xattr = []byte(node.Cid().String()) + return nil + default: + return fuse.ErrNoXattr + } +} + +// FUSE adapter for MFS files. +type File struct { + mfsFile *mfs.File +} + +// File attributes. +func (file *File) Attr(ctx context.Context, attr *fuse.Attr) error { + size, _ := file.mfsFile.Size() + + attr.Size = uint64(size) + if size%blockSize == 0 { + attr.Blocks = uint64(size / blockSize) + } else { + attr.Blocks = uint64(size/blockSize + 1) + } + + mtime, _ := file.mfsFile.ModTime() + attr.Mtime = mtime + + attr.Mode = mfsFileMode + return nil +} + +// Open an MFS file. +func (file *File) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) { + accessMode := req.Flags & fuse.OpenAccessModeMask + flags := mfs.Flags{ + Read: accessMode == fuse.OpenReadOnly || accessMode == fuse.OpenReadWrite, + Write: accessMode == fuse.OpenWriteOnly || accessMode == fuse.OpenReadWrite, + Sync: req.Flags|fuse.OpenSync > 0, + } + fd, err := file.mfsFile.Open(flags) + if err != nil { + return nil, err + } + + if flags.Write { + if err := file.mfsFile.SetModTime(time.Now()); err != nil { + return nil, err + } + } + + return &FileHandler{ + mfsFD: fd, + }, nil +} + +// Sync the file's contents to MFS. +func (file *File) Fsync(ctx context.Context, req *fuse.FsyncRequest) error { + return file.mfsFile.Sync() +} + +// List file xattr. +func (file *File) Listxattr(ctx context.Context, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error { + resp.Append(ipfsCIDXattr) + return nil +} + +// Get file xattr. +func (file *File) Getxattr(ctx context.Context, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error { + switch req.Name { + case ipfsCIDXattr: + node, err := file.mfsFile.GetNode() + if err != nil { + return err + } + resp.Xattr = []byte(node.Cid().String()) + return nil + default: + return fuse.ErrNoXattr + } +} + +// Wrapper for MFS's file descriptor that conforms to the FUSE fs.Handler +// interface. +type FileHandler struct { + mfsFD mfs.FileDescriptor + mu sync.Mutex +} + +// Read a opened MFS file. +func (fh *FileHandler) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error { + fh.mu.Lock() + defer fh.mu.Unlock() + + _, err := fh.mfsFD.Seek(req.Offset, io.SeekStart) + if err != nil { + return err + } + + buf := make([]byte, req.Size) + l, err := fh.mfsFD.Read(buf) + + resp.Data = buf[:l] + + switch err { + case nil, io.EOF, io.ErrUnexpectedEOF: + return nil + default: + return err + } +} + +// Write writes to an opened MFS file. +func (fh *FileHandler) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error { + fh.mu.Lock() + defer fh.mu.Unlock() + + l, err := fh.mfsFD.WriteAt(req.Data, req.Offset) + if err != nil { + return err + } + resp.Size = l + + return nil +} + +// Flushes the file's buffer. +func (fh *FileHandler) Flush(ctx context.Context, req *fuse.FlushRequest) error { + fh.mu.Lock() + defer fh.mu.Unlock() + + return fh.mfsFD.Flush() +} + +// Closes the file. +func (fh *FileHandler) Release(ctx context.Context, req *fuse.ReleaseRequest) error { + fh.mu.Lock() + defer fh.mu.Unlock() + + return fh.mfsFD.Close() +} + +// Create new filesystem. +func NewFileSystem(ipfs *core.IpfsNode) fs.FS { + return &FileSystem{ + root: Dir{ + mfsDir: ipfs.FilesRoot.GetDirectory(), + }, + } +} + +// Check that our structs implement all the interfaces we want. +type mfsDir interface { + fs.Node + fs.NodeGetxattrer + fs.NodeListxattrer + fs.HandleReadDirAller + fs.NodeRequestLookuper + fs.NodeMkdirer + fs.NodeRenamer + fs.NodeRemover + fs.NodeCreater +} + +var _ mfsDir = (*Dir)(nil) + +type mfsFile interface { + fs.Node + fs.NodeGetxattrer + fs.NodeListxattrer + fs.NodeOpener + fs.NodeFsyncer +} + +var _ mfsFile = (*File)(nil) + +type mfsHandler interface { + fs.Handle + fs.HandleReader + fs.HandleWriter + fs.HandleFlusher + fs.HandleReleaser +} + +var _ mfsHandler = (*FileHandler)(nil) diff --git a/fuse/mfs/mount_unix.go b/fuse/mfs/mount_unix.go new file mode 100644 index 00000000000..7fe72e8df17 --- /dev/null +++ b/fuse/mfs/mount_unix.go @@ -0,0 +1,21 @@ +//go:build (linux || darwin || freebsd || netbsd || openbsd) && !nofuse +// +build linux darwin freebsd netbsd openbsd +// +build !nofuse + +package mfs + +import ( + core "github.com/ipfs/kubo/core" + mount "github.com/ipfs/kubo/fuse/mount" +) + +// Mount mounts MFS at a given location, and returns a mount.Mount instance. +func Mount(ipfs *core.IpfsNode, mountpoint string) (mount.Mount, error) { + cfg, err := ipfs.Repo.Config() + if err != nil { + return nil, err + } + allowOther := cfg.Mounts.FuseAllowOther + fsys := NewFileSystem(ipfs) + return mount.NewMount(ipfs.Process, fsys, mountpoint, allowOther) +} diff --git a/fuse/node/mount_nofuse.go b/fuse/node/mount_nofuse.go index e6f512f8eef..7423cb24d34 100644 --- a/fuse/node/mount_nofuse.go +++ b/fuse/node/mount_nofuse.go @@ -9,6 +9,6 @@ import ( core "github.com/ipfs/kubo/core" ) -func Mount(node *core.IpfsNode, fsdir, nsdir string) error { +func Mount(node *core.IpfsNode, fsdir, nsdir, mfsdir string) error { return errors.New("not compiled in") } diff --git a/fuse/node/mount_notsupp.go b/fuse/node/mount_notsupp.go index e9762a3e4bd..79ac0e79165 100644 --- a/fuse/node/mount_notsupp.go +++ b/fuse/node/mount_notsupp.go @@ -9,6 +9,6 @@ import ( core "github.com/ipfs/kubo/core" ) -func Mount(node *core.IpfsNode, fsdir, nsdir string) error { +func Mount(node *core.IpfsNode, fsdir, nsdir, mfsdir string) error { return errors.New("FUSE not supported on OpenBSD or NetBSD. See #5334 (https://github.com/ipfs/kubo/issues/5334).") } diff --git a/fuse/node/mount_test.go b/fuse/node/mount_test.go index 178fddcf665..1947f759ffa 100644 --- a/fuse/node/mount_test.go +++ b/fuse/node/mount_test.go @@ -56,10 +56,12 @@ func TestExternalUnmount(t *testing.T) { ipfsDir := dir + "/ipfs" ipnsDir := dir + "/ipns" + mfsDir := dir + "/mfs" mkdir(t, ipfsDir) mkdir(t, ipnsDir) + mkdir(t, mfsDir) - err = Mount(node, ipfsDir, ipnsDir) + err = Mount(node, ipfsDir, ipnsDir, mfsDir) if err != nil { if strings.Contains(err.Error(), "unable to check fuse version") || err == fuse.ErrOSXFUSENotFound { t.Skip(err) diff --git a/fuse/node/mount_unix.go b/fuse/node/mount_unix.go index a5a2a371688..9846d7a42db 100644 --- a/fuse/node/mount_unix.go +++ b/fuse/node/mount_unix.go @@ -11,6 +11,7 @@ import ( core "github.com/ipfs/kubo/core" ipns "github.com/ipfs/kubo/fuse/ipns" + mfs "github.com/ipfs/kubo/fuse/mfs" mount "github.com/ipfs/kubo/fuse/mount" rofs "github.com/ipfs/kubo/fuse/readonly" @@ -31,7 +32,7 @@ var platformFuseChecks = func(*core.IpfsNode) error { return nil } -func Mount(node *core.IpfsNode, fsdir, nsdir string) error { +func Mount(node *core.IpfsNode, fsdir, nsdir, mfsdir string) error { // check if we already have live mounts. // if the user said "Mount", then there must be something wrong. // so, close them and try again. @@ -43,15 +44,19 @@ func Mount(node *core.IpfsNode, fsdir, nsdir string) error { // best effort _ = node.Mounts.Ipns.Unmount() } + if node.Mounts.Mfs != nil && node.Mounts.Mfs.IsActive() { + // best effort + _ = node.Mounts.Mfs.Unmount() + } if err := platformFuseChecks(node); err != nil { return err } - return doMount(node, fsdir, nsdir) + return doMount(node, fsdir, nsdir, mfsdir) } -func doMount(node *core.IpfsNode, fsdir, nsdir string) error { +func doMount(node *core.IpfsNode, fsdir, nsdir, mfsdir string) error { fmtFuseErr := func(err error, mountpoint string) error { s := err.Error() if strings.Contains(s, fuseNoDirectory) { @@ -67,8 +72,8 @@ func doMount(node *core.IpfsNode, fsdir, nsdir string) error { } // this sync stuff is so that both can be mounted simultaneously. - var fsmount, nsmount mount.Mount - var err1, err2 error + var fsmount, nsmount, mfmount mount.Mount + var err1, err2, err3 error var wg sync.WaitGroup @@ -86,6 +91,12 @@ func doMount(node *core.IpfsNode, fsdir, nsdir string) error { }() } + wg.Add(1) + go func() { + defer wg.Done() + mfmount, err3 = mfs.Mount(node, mfsdir) + }() + wg.Wait() if err1 != nil { @@ -96,22 +107,33 @@ func doMount(node *core.IpfsNode, fsdir, nsdir string) error { log.Errorf("error mounting IPNS %s for IPFS %s: %s", nsdir, fsdir, err2) } - if err1 != nil || err2 != nil { + if err3 != nil { + log.Errorf("error mounting MFS %s: %s", mfsdir, err3) + } + + if err1 != nil || err2 != nil || err3 != nil { if fsmount != nil { _ = fsmount.Unmount() } if nsmount != nil { _ = nsmount.Unmount() } + if mfmount != nil { + _ = mfmount.Unmount() + } if err1 != nil { return fmtFuseErr(err1, fsdir) } - return fmtFuseErr(err2, nsdir) + if err2 != nil { + return fmtFuseErr(err2, nsdir) + } + return fmtFuseErr(err3, mfsdir) } // setup node state, so that it can be canceled node.Mounts.Ipfs = fsmount node.Mounts.Ipns = nsmount + node.Mounts.Mfs = mfmount return nil } diff --git a/fuse/node/mount_windows.go b/fuse/node/mount_windows.go index 33393f99a90..42e6bc10b9b 100644 --- a/fuse/node/mount_windows.go +++ b/fuse/node/mount_windows.go @@ -4,7 +4,7 @@ import ( "github.com/ipfs/kubo/core" ) -func Mount(node *core.IpfsNode, fsdir, nsdir string) error { +func Mount(node *core.IpfsNode, fsdir, nsdir, mfsdir string) error { // TODO // currently a no-op, but we don't want to return an error return nil diff --git a/test/3nodetest/bootstrap/config b/test/3nodetest/bootstrap/config index ac441a19f16..e22f25e909b 100644 --- a/test/3nodetest/bootstrap/config +++ b/test/3nodetest/bootstrap/config @@ -15,7 +15,8 @@ }, "Mounts": { "IPFS": "/ipfs", - "IPNS": "/ipns" + "IPNS": "/ipns", + "MFS": "/mfs" }, "Version": { "Current": "0.1.7", diff --git a/test/3nodetest/client/config b/test/3nodetest/client/config index 86ef0668d72..fa8f923d5c3 100644 --- a/test/3nodetest/client/config +++ b/test/3nodetest/client/config @@ -17,7 +17,8 @@ }, "Mounts": { "IPFS": "/ipfs", - "IPNS": "/ipns" + "IPNS": "/ipns", + "MFS": "/mfs" }, "Version": { "AutoUpdate": "minor", diff --git a/test/3nodetest/server/config b/test/3nodetest/server/config index fb16a6d7a87..1e9db2a6332 100644 --- a/test/3nodetest/server/config +++ b/test/3nodetest/server/config @@ -17,7 +17,8 @@ }, "Mounts": { "IPFS": "/ipfs", - "IPNS": "/ipns" + "IPNS": "/ipns", + "MFS": "/mfs" }, "Version": { "AutoUpdate": "minor", diff --git a/test/cli/bitswap_config_test.go b/test/cli/bitswap_config_test.go index db7656ef27e..9674d3cb6b3 100644 --- a/test/cli/bitswap_config_test.go +++ b/test/cli/bitswap_config_test.go @@ -167,7 +167,7 @@ func TestBitswapConfig(t *testing.T) { node.UpdateConfig(func(cfg *config.Config) { cfg.HTTPRetrieval.Enabled = config.False cfg.Bitswap.Libp2pEnabled = config.False - cfg.Bitswap.ServerEnabled = config.True // bad user config: cant enable server when libp2p is down + cfg.Bitswap.ServerEnabled = config.True // bad user config: can't enable server when libp2p is down }) res := node.RunIPFS("daemon") assert.Contains(t, res.Stderr.Trimmed(), "invalid configuration: Bitswap.Libp2pEnabled and HTTPRetrieval.Enabled are both disabled, unable to initialize Bitswap") diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index 12a1f71be11..f9292cb237c 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -206,9 +206,10 @@ test_init_ipfs() { ' test_expect_success "prepare config -- mounting" ' - mkdir mountdir ipfs ipns && + mkdir mountdir ipfs ipns mfs && test_config_set Mounts.IPFS "$(pwd)/ipfs" && - test_config_set Mounts.IPNS "$(pwd)/ipns" || + test_config_set Mounts.IPNS "$(pwd)/ipns" && + test_config_set Mounts.MFS "$(pwd)/mfs" || test_fsh cat "\"$IPFS_PATH/config\"" ' @@ -321,12 +322,14 @@ test_mount_ipfs() { test_expect_success FUSE "'ipfs mount' succeeds" ' do_umount "$(pwd)/ipfs" || true && do_umount "$(pwd)/ipns" || true && + do_umount "$(pwd)/mfs" || true && ipfs mount >actual ' test_expect_success FUSE "'ipfs mount' output looks good" ' echo "IPFS mounted at: $(pwd)/ipfs" >expected && echo "IPNS mounted at: $(pwd)/ipns" >>expected && + echo "MFS mounted at: $(pwd)/mfs" >>expected && test_cmp expected actual ' diff --git a/test/sharness/t0030-mount.sh b/test/sharness/t0030-mount.sh index 0c0983d0c41..6df7a26bbef 100755 --- a/test/sharness/t0030-mount.sh +++ b/test/sharness/t0030-mount.sh @@ -16,7 +16,8 @@ if ! test_have_prereq FUSE; then fi -export IPFS_NS_MAP="welcome.example.com:/ipfs/$HASH_WELCOME_DOCS" +# echo -n "ipfs" > expected && ipfs add --cid-version 1 -Q -w expected +export IPFS_NS_MAP="welcome.example.com:/ipfs/bafybeicq7bvn5lz42qlmghaoiwrve74pzi53auqetbantp5kajucsabike" # start iptb + wait for peering NUM_NODES=5 @@ -27,17 +28,17 @@ startup_cluster $NUM_NODES # test mount failure before mounting properly. test_expect_success "'ipfs mount' fails when there is no mount dir" ' - tmp_ipfs_mount() { ipfsi 0 mount -f=not_ipfs -n=not_ipns >output 2>output.err; } && + tmp_ipfs_mount() { ipfsi 0 mount -f=not_ipfs -n=not_ipns -m=not_mfs >output 2>output.err; } && test_must_fail tmp_ipfs_mount ' test_expect_success "'ipfs mount' output looks good" ' test_must_be_empty output && - test_should_contain "not_ipns\|not_ipfs" output.err + test_should_contain "not_ipns\|not_ipfs\|not_mfs" output.err ' test_expect_success "setup and publish default IPNS value" ' - mkdir "$(pwd)/ipfs" "$(pwd)/ipns" && + mkdir "$(pwd)/ipfs" "$(pwd)/ipns" "$(pwd)/mfs" && ipfsi 0 name publish QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn ' @@ -46,12 +47,14 @@ test_expect_success "setup and publish default IPNS value" ' test_expect_success FUSE "'ipfs mount' succeeds" ' do_umount "$(pwd)/ipfs" || true && do_umount "$(pwd)/ipns" || true && - ipfsi 0 mount -f "$(pwd)/ipfs" -n "$(pwd)/ipns" >actual + do_umount "$(pwd)/mfs" || true && + ipfsi 0 mount -f "$(pwd)/ipfs" -n "$(pwd)/ipns" -m "$(pwd)/mfs" >actual ' test_expect_success FUSE "'ipfs mount' output looks good" ' echo "IPFS mounted at: $(pwd)/ipfs" >expected && echo "IPNS mounted at: $(pwd)/ipns" >>expected && + echo "MFS mounted at: $(pwd)/mfs" >>expected && test_cmp expected actual ' @@ -63,21 +66,64 @@ test_expect_success FUSE "local symlink works" ' test_expect_success FUSE "can resolve ipns names" ' echo -n "ipfs" > expected && - cat ipns/welcome.example.com/ping > actual && + ipfsi 0 add --cid-version 1 -Q -w expected && + cat ipns/welcome.example.com/expected > actual && test_cmp expected actual ' +test_expect_success FUSE "create mfs file via fuse" ' + touch mfs/testfile && + ipfsi 0 files ls | grep testfile +' + +test_expect_success FUSE "create mfs dir via fuse" ' + mkdir mfs/testdir && + ipfsi 0 files ls | grep testdir +' + +test_expect_success FUSE "read mfs file from fuse" ' + echo content > mfs/testfile && + getfattr -n ipfs_cid mfs/testfile +' +test_expect_success FUSE "ipfs add file and read it back via fuse" ' + echo content3 | ipfsi 0 files write -e /testfile3 && + grep content3 mfs/testfile3 +' + +test_expect_success FUSE "ipfs add file and read it back via fuse" ' + echo content > testfile2 && + ipfsi 0 add --to-files /testfile2 testfile2 && + grep content mfs/testfile2 +' + +test_expect_success FUSE "test file xattr" ' + echo content > mfs/testfile && + getfattr -n ipfs_cid mfs/testfile +' + +test_expect_success FUSE "test file removal" ' + touch mfs/testfile && + rm mfs/testfile +' + +test_expect_success FUSE "test nested dirs" ' + mkdir -p mfs/foo/bar/baz/qux && + echo content > mfs/foo/bar/baz/qux/quux && + ipfsi 0 files stat /foo/bar/baz/qux/quux +' + test_expect_success "mount directories cannot be removed while active" ' - test_must_fail rmdir ipfs ipns 2>/dev/null + test_must_fail rmdir ipfs ipns mfs 2>/dev/null ' test_expect_success "unmount directories" ' do_umount "$(pwd)/ipfs" && - do_umount "$(pwd)/ipns" + do_umount "$(pwd)/ipns" && + do_umount "$(pwd)/mfs" ' test_expect_success "mount directories can be removed after shutdown" ' - rmdir ipfs ipns + rmdir ipfs ipns mfs ' test_expect_success 'stop iptb' ' diff --git a/test/sharness/t0270-filestore.sh b/test/sharness/t0270-filestore.sh index f2f63b0de80..fc377c2d264 100755 --- a/test/sharness/t0270-filestore.sh +++ b/test/sharness/t0270-filestore.sh @@ -63,7 +63,7 @@ test_filestore_adds() { init_ipfs_filestore() { test_expect_success "clean up old node" ' - rm -rf "$IPFS_PATH" mountdir ipfs ipns + rm -rf "$IPFS_PATH" mountdir ipfs ipns mfs ' test_init_ipfs diff --git a/test/sharness/t0271-filestore-utils.sh b/test/sharness/t0271-filestore-utils.sh index e7c11646cda..5fd33565932 100755 --- a/test/sharness/t0271-filestore-utils.sh +++ b/test/sharness/t0271-filestore-utils.sh @@ -10,7 +10,7 @@ test_description="Test out the filestore nocopy functionality" test_init_filestore() { test_expect_success "clean up old node" ' - rm -rf "$IPFS_PATH" mountdir ipfs ipns + rm -rf "$IPFS_PATH" mountdir ipfs ipns mfs ' test_init_ipfs From fffdec35849ece4ae9be7dcbf7e4608ff9a4aec1 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 6 May 2025 21:39:43 +0200 Subject: [PATCH 32/42] chore: ensure /mfs is present in docker --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1465e5d02d1..98e44a1b647 100644 --- a/Dockerfile +++ b/Dockerfile @@ -80,8 +80,8 @@ RUN mkdir -p $IPFS_PATH \ && chown ipfs:users $IPFS_PATH # Create mount points for `ipfs mount` command -RUN mkdir /ipfs /ipns \ - && chown ipfs:users /ipfs /ipns +RUN mkdir /ipfs /ipns /mfs \ + && chown ipfs:users /ipfs /ipns /mfs # Create the init scripts directory RUN mkdir /container-init.d \ From 4e326775389a8dba6eca08d16ccb816c856ed6b9 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Wed, 7 May 2025 05:37:22 -0700 Subject: [PATCH 33/42] logging: upgrade to go-log/v2 v2.6.0 (#10798) --- docs/changelogs/v0.35.md | 9 +++++++++ docs/examples/kubo-as-a-library/go.mod | 4 ++-- docs/examples/kubo-as-a-library/go.sum | 22 ++++------------------ go.mod | 4 ++-- go.sum | 22 ++++------------------ test/dependencies/go.mod | 4 ++-- test/dependencies/go.sum | 20 ++++---------------- 7 files changed, 27 insertions(+), 58 deletions(-) diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index c5fccf7ad1e..92ae64bdd7d 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -230,6 +230,14 @@ When installing a new version of Kubo when `"formatMajorVersion"` is configured, See other caveats and configuration options at [`kubo/docs/datastores.md#pebbleds`](https://github.com/ipfs/kubo/blob/master/docs/datastores.md#pebbleds) +#### Improved Log Output Setting + +When stderr and/or stdout options are configured or specified by the `GOLOG_OUTPUT` environ variable, log only to the output(s) specified. For example: + +- `GOLOG_OUTPUT="stderr"` logs only to stderr +- `GOLOG_OUTPUT="stdout"` logs only to stdout +- `GOLOG_OUTPUT="stderr+stdout"` logs to both stderr and stdout + #### πŸ“¦οΈ Important dependency updates - update `boxo` to [v0.30.0](https://github.com/ipfs/boxo/releases/tag/v0.30.0) @@ -237,6 +245,7 @@ See other caveats and configuration options at [`kubo/docs/datastores.md#pebbled - update `go-ds-pebble` to [v0.5.0](https://github.com/ipfs/go-ds-pebble/releases/tag/v0.5.0) - update `pebble` to [v2.0.3](https://github.com/cockroachdb/pebble/releases/tag/v2.0.3) - update `go-libp2p-pubsub` to [v0.13.1](https://github.com:/libp2p/go-libp2p-pubsub/releases/tag/v0.13.1) +- update `go-log` to [v2.6.0](https://github.com/ipfs/go-log/releases/tag/v2.6.0) ### πŸ“ Changelog ### πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 25442a1c93f..84b77f97be1 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -101,7 +101,7 @@ require ( 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 - github.com/ipfs/go-log/v2 v2.5.1 // indirect + github.com/ipfs/go-log/v2 v2.6.0 // indirect github.com/ipfs/go-merkledag v0.11.0 // indirect github.com/ipfs/go-metrics-interface v0.3.0 // indirect github.com/ipfs/go-peertaskqueue v0.8.2 // indirect @@ -230,7 +230,7 @@ require ( golang.org/x/mod v0.24.0 // indirect golang.org/x/net v0.39.0 // indirect golang.org/x/sync v0.13.0 // indirect - golang.org/x/sys v0.32.0 // indirect + golang.org/x/sys v0.33.0 // indirect golang.org/x/text v0.24.0 // indirect golang.org/x/tools v0.32.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 00b24d1afb7..ddd8f8329f0 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -43,7 +43,6 @@ 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/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= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -383,8 +382,8 @@ 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.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-log/v2 v2.6.0 h1:2Nu1KKQQ2ayonKp4MPo6pXCjqw1ULc9iohRqWV5EYqg= +github.com/ipfs/go-log/v2 v2.6.0/go.mod h1:p+Efr3qaY5YXpx9TX7MoLCSEZX5boSWj9wh86P5HJa8= 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.3.0 h1:YwG7/Cy4R94mYDUuwsBfeziJCVm9pBMJ6q/JR9V40TU= @@ -514,7 +513,6 @@ github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcncea 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.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.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= @@ -764,7 +762,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.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= @@ -813,7 +810,6 @@ github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7V github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.27/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= github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY= github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= @@ -861,7 +857,6 @@ 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.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.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= @@ -872,7 +867,6 @@ 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= go.uber.org/zap/exp v0.3.0 h1:6JYzdifzYkGmTdRR59oYH+Ng7k49H9qVpWwNSsGJj3U= @@ -933,7 +927,6 @@ 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.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.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= @@ -963,7 +956,6 @@ 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-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= @@ -1033,12 +1025,9 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w 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= 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-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= @@ -1050,8 +1039,8 @@ 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.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.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= -golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 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= @@ -1113,7 +1102,6 @@ golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapK 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= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU= @@ -1209,12 +1197,10 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD 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.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= diff --git a/go.mod b/go.mod index 4d023579243..61f1a204560 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,7 @@ require ( 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 - github.com/ipfs/go-log/v2 v2.5.1 + github.com/ipfs/go-log/v2 v2.6.0 github.com/ipfs/go-metrics-interface v0.3.0 github.com/ipfs/go-metrics-prometheus v0.1.0 github.com/ipfs/go-test v0.2.1 @@ -91,7 +91,7 @@ require ( golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 golang.org/x/mod v0.24.0 golang.org/x/sync v0.13.0 - golang.org/x/sys v0.32.0 + golang.org/x/sys v0.33.0 google.golang.org/protobuf v1.36.6 ) diff --git a/go.sum b/go.sum index 782427eadea..585763c5fce 100644 --- a/go.sum +++ b/go.sum @@ -67,7 +67,6 @@ 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/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= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -451,8 +450,8 @@ github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JP github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= 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-log/v2 v2.6.0 h1:2Nu1KKQQ2ayonKp4MPo6pXCjqw1ULc9iohRqWV5EYqg= +github.com/ipfs/go-log/v2 v2.6.0/go.mod h1:p+Efr3qaY5YXpx9TX7MoLCSEZX5boSWj9wh86P5HJa8= 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.3.0 h1:YwG7/Cy4R94mYDUuwsBfeziJCVm9pBMJ6q/JR9V40TU= @@ -607,7 +606,6 @@ 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.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/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= @@ -902,7 +900,6 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV 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= @@ -968,7 +965,6 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de 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= github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY= github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= @@ -1029,7 +1025,6 @@ 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.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.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= @@ -1042,7 +1037,6 @@ 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.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= 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= go.uber.org/zap/exp v0.3.0 h1:6JYzdifzYkGmTdRR59oYH+Ng7k49H9qVpWwNSsGJj3U= @@ -1106,7 +1100,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB 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.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.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= @@ -1149,7 +1142,6 @@ 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-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= @@ -1246,13 +1238,10 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w 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-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1267,8 +1256,8 @@ 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.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.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= -golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 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= @@ -1349,7 +1338,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.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.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU= @@ -1478,12 +1466,10 @@ 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= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 1c617ef835d..dc66b2708be 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -8,7 +8,7 @@ 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/v2 v2.5.1 + github.com/ipfs/go-log/v2 v2.6.0 github.com/ipfs/go-test v0.2.1 github.com/ipfs/hang-fds v0.1.0 github.com/ipfs/iptb v1.4.1 @@ -317,7 +317,7 @@ require ( golang.org/x/mod v0.24.0 // indirect golang.org/x/net v0.39.0 // indirect golang.org/x/sync v0.13.0 // indirect - golang.org/x/sys v0.32.0 // indirect + golang.org/x/sys v0.33.0 // indirect golang.org/x/term v0.31.0 // indirect golang.org/x/text v0.24.0 // indirect golang.org/x/tools v0.32.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 5b5eb3a4591..adc5ae5d604 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -60,7 +60,6 @@ github.com/ashanbrown/forbidigo v1.6.0 h1:D3aewfM37Yb3pxHujIPSpTf6oQk9sc9WZi8ger 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.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= @@ -355,8 +354,8 @@ 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/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= -github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= +github.com/ipfs/go-log/v2 v2.6.0 h1:2Nu1KKQQ2ayonKp4MPo6pXCjqw1ULc9iohRqWV5EYqg= +github.com/ipfs/go-log/v2 v2.6.0/go.mod h1:p+Efr3qaY5YXpx9TX7MoLCSEZX5boSWj9wh86P5HJa8= github.com/ipfs/go-metrics-interface v0.3.0 h1:YwG7/Cy4R94mYDUuwsBfeziJCVm9pBMJ6q/JR9V40TU= github.com/ipfs/go-metrics-interface v0.3.0/go.mod h1:OxxQjZDGocXVdyTPocns6cOLwHieqej/jos7H4POwoY= github.com/ipfs/go-peertaskqueue v0.8.2 h1:PaHFRaVFdxQk1Qo3OKiHPYjmmusQy7gKQUaL8JDszAU= @@ -481,7 +480,6 @@ 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.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -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= @@ -849,22 +847,18 @@ go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/ go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= -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.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= 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.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= -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= go.uber.org/zap/exp v0.3.0 h1:6JYzdifzYkGmTdRR59oYH+Ng7k49H9qVpWwNSsGJj3U= @@ -901,7 +895,6 @@ golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f/go.mod h1:AbB0pIl 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-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.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -991,7 +984,6 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w 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= 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-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1013,8 +1005,8 @@ 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.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= -golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 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= @@ -1058,7 +1050,6 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm 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= 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-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1114,7 +1105,6 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= 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= 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= @@ -1122,11 +1112,9 @@ 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= 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 v1.12.0 h1:CmwtaGDkHxrZm4Ib0Vob89MTfpc3GrEFMJKovliPwGk= From f7e0568a50fd008f33722b4e925203ce3aed7420 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Wed, 7 May 2025 07:28:43 -0700 Subject: [PATCH 34/42] feat: IPFS_WAIT_REPO_LOCK (#10797) * repo: optionally wait to acquire repo lock Retry acquiring repo lock for a specified amount of time. Retry once per second until time is expired ro lock is acquired. Lock wait timeout is specified using the environment variable `IPFS_WAIT_REPO_LOCK` and assigning it a value that is parsable as a golang `time.Duration`. For example: ``` IPFS_WAIT_REPO_LOCK="5s" ``` Closes #10482 * document IPFS_WAIT_REPO_LOCK --------- Co-authored-by: Marcin Rataj --- docs/changelogs/v0.35.md | 18 ++++++++++- docs/environment-variables.md | 44 ++++++++++++++++++++++++++ docs/examples/kubo-as-a-library/go.mod | 4 +-- docs/examples/kubo-as-a-library/go.sum | 14 +++----- go.mod | 4 +-- go.sum | 12 +++---- repo/fsrepo/fsrepo.go | 19 ++++++++++- test/dependencies/go.mod | 3 +- test/dependencies/go.sum | 6 ++-- 9 files changed, 94 insertions(+), 30 deletions(-) diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index 92ae64bdd7d..9314390ad88 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -26,6 +26,9 @@ This release was brought to you by the [Shipyard](http://ipshipyard.com/) team. - [New `Bitswap` configuration options](#new-bitswap-configuration-options) - [New `Routing` configuration options](#new-routing-configuration-options) - [New Pebble database format config](#new-pebble-database-format-config) + - [New environment variables](#new-environment-variables) + - [Improved Log Output Setting](#improved-log-output-setting) + - [New Repo Lock Optional Wait](#new-repo-lock-optional-wait) - [πŸ“¦οΈ Important dependency updates](#-important-dependency-updates) - [πŸ“ Changelog](#-changelog) - [πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors](#-contributors) @@ -230,7 +233,11 @@ When installing a new version of Kubo when `"formatMajorVersion"` is configured, See other caveats and configuration options at [`kubo/docs/datastores.md#pebbleds`](https://github.com/ipfs/kubo/blob/master/docs/datastores.md#pebbleds) -#### Improved Log Output Setting +#### New environment variables + +The [`environment-variables.md`](https://github.com/ipfs/kubo/blob/master/docs/environment-variables.md) was extended with two new features: + +##### Improved Log Output Setting When stderr and/or stdout options are configured or specified by the `GOLOG_OUTPUT` environ variable, log only to the output(s) specified. For example: @@ -238,6 +245,15 @@ When stderr and/or stdout options are configured or specified by the `GOLOG_OUTP - `GOLOG_OUTPUT="stdout"` logs only to stdout - `GOLOG_OUTPUT="stderr+stdout"` logs to both stderr and stdout +##### New Repo Lock Optional Wait + +The environment variable `IPFS_WAIT_REPO_LOCK` specifies the amount of time to wait for the repo lock. Set the value of this variable to a string that can be [parsed](https://pkg.go.dev/time@go1.24.3#ParseDuration) as a golang `time.Duration`. For example: +``` +IPFS_WAIT_REPO_LOCK="15s" +``` + +If the lock cannot be acquired because someone else has the lock, and `IPFS_WAIT_REPO_LOCK` is set to a valid value, then acquiring the lock is retried every second until the lock is acquired or the specified wait time has elapsed. + #### πŸ“¦οΈ Important dependency updates - update `boxo` to [v0.30.0](https://github.com/ipfs/boxo/releases/tag/v0.30.0) diff --git a/docs/environment-variables.md b/docs/environment-variables.md index bbbc6662669..2b763721b00 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -1,5 +1,32 @@ # Kubo environment variables +- [Variables](#variables) + - [`IPFS_PATH`](#ipfs_path) + - [`IPFS_LOGGING`](#ipfs_logging) + - [`IPFS_LOGGING_FMT`](#ipfs_logging_fmt) + - [`GOLOG_LOG_LEVEL`](#golog_log_level) + - [`GOLOG_LOG_FMT`](#golog_log_fmt) + - [`GOLOG_FILE`](#golog_file) + - [`GOLOG_OUTPUT`](#golog_output) + - [`GOLOG_TRACING_FILE`](#golog_tracing_file) + - [`IPFS_FUSE_DEBUG`](#ipfs_fuse_debug) + - [`YAMUX_DEBUG`](#yamux_debug) + - [`IPFS_FD_MAX`](#ipfs_fd_max) + - [`IPFS_DIST_PATH`](#ipfs_dist_path) + - [`IPFS_NS_MAP`](#ipfs_ns_map) + - [`IPFS_HTTP_ROUTERS`](#ipfs_http_routers) + - [`IPFS_HTTP_ROUTERS_FILTER_PROTOCOLS`](#ipfs_http_routers_filter_protocols) + - [`IPFS_CONTENT_BLOCKING_DISABLE`](#ipfs_content_blocking_disable) + - [`IPFS_WAIT_REPO_LOCK`](#ipfs_wait_repo_lock) + - [`LIBP2P_TCP_REUSEPORT`](#libp2p_tcp_reuseport) + - [`LIBP2P_TCP_MUX`](#libp2p_tcp_mux) + - [`LIBP2P_MUX_PREFS`](#libp2p_mux_prefs) + - [`LIBP2P_RCMGR`](#libp2p_rcmgr) + - [`LIBP2P_DEBUG_RCMGR`](#libp2p_debug_rcmgr) +- [Tracing](#tracing) + +# Variables + ## `IPFS_PATH` Sets the location of the IPFS repo (where the config, blocks, etc. @@ -63,6 +90,14 @@ The logging format defaults to `color` when the output is a terminal, and `nocol Sets the file to which Kubo logs. By default, Kubo logs to standard error. +## `GOLOG_OUTPUT` + +When stderr and/or stdout options are configured or specified by the `GOLOG_OUTPUT` environ variable, log only to the output(s) specified. For example: + +- `GOLOG_OUTPUT="stderr"` logs only to stderr +- `GOLOG_OUTPUT="stdout"` logs only to stdout +- `GOLOG_OUTPUT="stderr+stdout"` logs to both stderr and stdout + ## `GOLOG_TRACING_FILE` Sets the file to which Kubo sends tracing events. By default, tracing is @@ -149,6 +184,15 @@ Default: `config.DefaultHTTPRoutersFilterProtocols` Disables the content-blocking subsystem. No denylists will be watched and no content will be blocked. +## `IPFS_WAIT_REPO_LOCK` + +Specifies the amount of time to wait for the repo lock. Set the value of this variable to a string that can be [parsed](https://pkg.go.dev/time@go1.24.3#ParseDuration) as a golang `time.Duration`. For example: +``` +IPFS_WAIT_REPO_LOCK="15s" +``` + +If the lock cannot be acquired because someone else has the lock, and `IPFS_WAIT_REPO_LOCK` is set to a valid value, then acquiring the lock is retried every second until the lock is acquired or the specified wait time has elapsed. + ## `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 84b77f97be1..c4b5597441e 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -78,7 +78,7 @@ require ( github.com/ipfs-shipyard/nopfs/ipfs v0.25.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.2.0 // indirect + github.com/ipfs/go-block-format v0.2.1 // indirect github.com/ipfs/go-blockservice v0.5.2 // indirect github.com/ipfs/go-cid v0.5.0 // indirect github.com/ipfs/go-cidutil v0.1.0 // indirect @@ -88,7 +88,7 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.2 // indirect github.com/ipfs/go-ds-measure v0.2.2 // indirect github.com/ipfs/go-ds-pebble v0.5.0 // indirect - github.com/ipfs/go-fs-lock v0.0.7 // indirect + github.com/ipfs/go-fs-lock v0.1.1 // 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.1 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index ddd8f8329f0..29c11e00886 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -315,8 +315,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-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-block-format v0.2.1 h1:96kW71XGNNa+mZw/MTzJrCpMhBWCrd9kBLoKm9Iip/Q= +github.com/ipfs/go-block-format v0.2.1/go.mod h1:frtvXHMQhM6zn7HvEQu+Qz5wSTj+04oEH/I+NjDgEjk= 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= @@ -344,8 +344,8 @@ github.com/ipfs/go-ds-measure v0.2.2 h1:4kwvBGbbSXNYe4ANlg7qTIYoZU6mNlqzQHdVqICk github.com/ipfs/go-ds-measure v0.2.2/go.mod h1:b/87ak0jMgH9Ylt7oH0+XGy4P8jHx9KG09Qz+pOeTIs= github.com/ipfs/go-ds-pebble v0.5.0 h1:lXffYCAKVD7nLLPqwJ9D8IxgO7Kz8woiX021tezdsIM= github.com/ipfs/go-ds-pebble v0.5.0/go.mod h1:aiCRVcj3K60sxc6k5C+HO9C6rouqiSkjR/WKnbTcMfQ= -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-fs-lock v0.1.1 h1:TecsP/Uc7WqYYatasreZQiP9EGRy4ZnKoG4yXxR33nw= +github.com/ipfs/go-fs-lock v0.1.1/go.mod h1:2goSXMCw7QfscHmSe09oXiR34DQeUdm+ei+dhonqly0= 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= @@ -381,7 +381,6 @@ github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9 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.3.0/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g= github.com/ipfs/go-log/v2 v2.6.0 h1:2Nu1KKQQ2ayonKp4MPo6pXCjqw1ULc9iohRqWV5EYqg= github.com/ipfs/go-log/v2 v2.6.0/go.mod h1:p+Efr3qaY5YXpx9TX7MoLCSEZX5boSWj9wh86P5HJa8= github.com/ipfs/go-merkledag v0.11.0 h1:DgzwK5hprESOzS4O1t/wi6JDpyVQdvm9Bs59N/jqfBY= @@ -512,7 +511,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.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 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= @@ -872,7 +870,6 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.uber.org/zap/exp v0.3.0 h1:6JYzdifzYkGmTdRR59oYH+Ng7k49H9qVpWwNSsGJj3U= go.uber.org/zap/exp v0.3.0/go.mod h1:5I384qq7XGxYyByIhHm6jg5CHkGY0nsTfbDLgDDlgJQ= 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= 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= @@ -949,7 +946,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL 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-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-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -1014,10 +1010,8 @@ 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-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/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-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= diff --git a/go.mod b/go.mod index 61f1a204560..00121bc001f 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/ipfs-shipyard/nopfs v0.0.14 github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 github.com/ipfs/boxo v0.30.0 - github.com/ipfs/go-block-format v0.2.0 + github.com/ipfs/go-block-format v0.2.1 github.com/ipfs/go-cid v0.5.0 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.8.2 @@ -32,7 +32,7 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.2 github.com/ipfs/go-ds-measure v0.2.2 github.com/ipfs/go-ds-pebble v0.5.0 - github.com/ipfs/go-fs-lock v0.0.7 + github.com/ipfs/go-fs-lock v0.1.1 github.com/ipfs/go-ipfs-cmds v0.14.1 github.com/ipfs/go-ipld-cbor v0.2.0 github.com/ipfs/go-ipld-format v0.6.0 diff --git a/go.sum b/go.sum index 585763c5fce..4db34250781 100644 --- a/go.sum +++ b/go.sum @@ -379,8 +379,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-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-block-format v0.2.1 h1:96kW71XGNNa+mZw/MTzJrCpMhBWCrd9kBLoKm9Iip/Q= +github.com/ipfs/go-block-format v0.2.1/go.mod h1:frtvXHMQhM6zn7HvEQu+Qz5wSTj+04oEH/I+NjDgEjk= 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= @@ -408,8 +408,8 @@ github.com/ipfs/go-ds-measure v0.2.2 h1:4kwvBGbbSXNYe4ANlg7qTIYoZU6mNlqzQHdVqICk github.com/ipfs/go-ds-measure v0.2.2/go.mod h1:b/87ak0jMgH9Ylt7oH0+XGy4P8jHx9KG09Qz+pOeTIs= github.com/ipfs/go-ds-pebble v0.5.0 h1:lXffYCAKVD7nLLPqwJ9D8IxgO7Kz8woiX021tezdsIM= github.com/ipfs/go-ds-pebble v0.5.0/go.mod h1:aiCRVcj3K60sxc6k5C+HO9C6rouqiSkjR/WKnbTcMfQ= -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-fs-lock v0.1.1 h1:TecsP/Uc7WqYYatasreZQiP9EGRy4ZnKoG4yXxR33nw= +github.com/ipfs/go-fs-lock v0.1.1/go.mod h1:2goSXMCw7QfscHmSe09oXiR34DQeUdm+ei+dhonqly0= 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= @@ -449,7 +449,6 @@ 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.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.6.0 h1:2Nu1KKQQ2ayonKp4MPo6pXCjqw1ULc9iohRqWV5EYqg= github.com/ipfs/go-log/v2 v2.6.0/go.mod h1:p+Efr3qaY5YXpx9TX7MoLCSEZX5boSWj9wh86P5HJa8= github.com/ipfs/go-merkledag v0.11.0 h1:DgzwK5hprESOzS4O1t/wi6JDpyVQdvm9Bs59N/jqfBY= @@ -605,7 +604,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.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 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= @@ -1042,7 +1040,6 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.uber.org/zap/exp v0.3.0 h1:6JYzdifzYkGmTdRR59oYH+Ng7k49H9qVpWwNSsGJj3U= go.uber.org/zap/exp v0.3.0/go.mod h1:5I384qq7XGxYyByIhHm6jg5CHkGY0nsTfbDLgDDlgJQ= 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= 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= @@ -1215,7 +1212,6 @@ golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/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= diff --git a/repo/fsrepo/fsrepo.go b/repo/fsrepo/fsrepo.go index e7577f9dc19..609b988a627 100644 --- a/repo/fsrepo/fsrepo.go +++ b/repo/fsrepo/fsrepo.go @@ -10,6 +10,7 @@ import ( "path/filepath" "strings" "sync" + "time" filestore "github.com/ipfs/boxo/filestore" keystore "github.com/ipfs/boxo/keystore" @@ -146,7 +147,23 @@ func open(repoPath string, userConfigFilePath string) (repo.Repo, error) { return nil, err } - r.lockfile, err = lockfile.Lock(r.path, LockFile) + text := os.Getenv("IPFS_WAIT_REPO_LOCK") + if text != "" { + var lockWaitTime time.Duration + lockWaitTime, err = time.ParseDuration(text) + if err != nil { + log.Errorw("Cannot parse value of IPFS_WAIT_REPO_LOCK as duration, not waiting for repo lock", "err", err, "value", text) + r.lockfile, err = lockfile.Lock(r.path, LockFile) + } else if lockWaitTime <= 0 { + r.lockfile, err = lockfile.WaitLock(context.Background(), r.path, LockFile) + } else { + ctx, cancel := context.WithTimeout(context.Background(), lockWaitTime) + r.lockfile, err = lockfile.WaitLock(ctx, r.path, LockFile) + cancel() + } + } else { + r.lockfile, err = lockfile.Lock(r.path, LockFile) + } if err != nil { return nil, err } diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index dc66b2708be..530e7c421cb 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -131,10 +131,9 @@ require ( github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/boxo v0.30.0 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect - github.com/ipfs/go-block-format v0.2.0 // indirect + github.com/ipfs/go-block-format v0.2.1 // indirect github.com/ipfs/go-cid v0.5.0 // indirect github.com/ipfs/go-datastore v0.8.2 // 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-metrics-interface v0.3.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index adc5ae5d604..790426ebf46 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -334,8 +334,8 @@ github.com/ipfs/boxo v0.30.0 h1:7afsoxPGGqfoH7Dum/wOTGUB9M5fb8HyKPMlLfBvIEQ= github.com/ipfs/boxo v0.30.0/go.mod h1:BPqgGGyHB9rZZcPSzah2Dc9C+5Or3U1aQe7EH1H7370= 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-block-format v0.2.1 h1:96kW71XGNNa+mZw/MTzJrCpMhBWCrd9kBLoKm9Iip/Q= +github.com/ipfs/go-block-format v0.2.1/go.mod h1:frtvXHMQhM6zn7HvEQu+Qz5wSTj+04oEH/I+NjDgEjk= github.com/ipfs/go-cid v0.5.0 h1:goEKKhaGm0ul11IHA7I6p1GmKz8kEYniqFopaB5Otwg= github.com/ipfs/go-cid v0.5.0/go.mod h1:0L7vmeNXpQpUS9vt+yEARkJ8rOg43DF3iPgn4GIN0mk= github.com/ipfs/go-cidutil v0.1.0 h1:RW5hO7Vcf16dplUU60Hs0AKDkQAVPVplr7lk97CFL+Q= @@ -348,8 +348,6 @@ github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1I 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= 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= From 79ccbb06fe217cb29884231956c4e706775acf9f Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 7 May 2025 16:40:48 +0200 Subject: [PATCH 35/42] chore(version): 0.35.0-rc1 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index bca3b4238fa..df548748db3 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.35.0-dev" +const CurrentVersionNumber = "0.35.0-rc1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 6e89271d4249fcf49cb07a8355053d82cfbf06de Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 7 May 2025 16:49:02 +0200 Subject: [PATCH 36/42] docs(changelog): go-libp2p-kad-dht --- docs/changelogs/v0.35.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index 9314390ad88..c8fd97014b6 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -261,6 +261,7 @@ If the lock cannot be acquired because someone else has the lock, and `IPFS_WAIT - update `go-ds-pebble` to [v0.5.0](https://github.com/ipfs/go-ds-pebble/releases/tag/v0.5.0) - update `pebble` to [v2.0.3](https://github.com/cockroachdb/pebble/releases/tag/v2.0.3) - update `go-libp2p-pubsub` to [v0.13.1](https://github.com:/libp2p/go-libp2p-pubsub/releases/tag/v0.13.1) +- update `go-libp2p-kad-dht` to [v0.32.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.32.0) (incl. [v0.31.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.31.0)) - update `go-log` to [v2.6.0](https://github.com/ipfs/go-log/releases/tag/v2.6.0) ### πŸ“ Changelog From 36b28a0af240c5da982f9527670b1fe343ca7be4 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 15 May 2025 19:19:18 +0200 Subject: [PATCH 37/42] fix(config): wire up `Provider.Enabled` flag (#10804) * fix(config): explicit Provider.Enabled flag Adds missing config option described in https://github.com/ipfs/kubo/issues/10803 * refactor: remove Experimental.StrategicProviding removing experiment, replaced with Provider.Enabled * test(cli): routing [re]provide updated and added tests for manually triggering provide and reprovide and making them respect global configuration flag to avoid inconsistent behaviors * docs: improve DelegatedRouters * refactor: default DefaultProviderWorkerCount=16 - simplified default for both - 16 is safer for non-accelerated DHT client - acceletated DHT performs better without limit anyway - updated docs (cherry picked from commit 2ab3f58c992104bac45fbc204d5475300d250355) --- cmd/ipfs/kubo/daemon.go | 17 +++++-- config/experiments.go | 2 +- config/profile.go | 8 +-- config/provider.go | 4 +- config/routing.go | 3 +- core/commands/routing.go | 21 ++++++++ core/node/bitswap.go | 7 +-- core/node/groups.go | 12 +++-- core/node/provider.go | 4 +- docs/changelogs/v0.35.md | 12 +++-- docs/config.md | 71 +++++++++++++++++++------- docs/experimental-features.md | 22 +------- test/cli/provider_test.go | 94 +++++++++++++++++++++++++++-------- 13 files changed, 193 insertions(+), 84 deletions(-) diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index ea6ccfc1dbe..5cdf3fa1dca 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -491,6 +491,11 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment if cfg.Provider.Strategy.WithDefault("") != "" && cfg.Reprovider.Strategy.IsDefault() { log.Fatal("Invalid config. Remove unused Provider.Strategy and set Reprovider.Strategy instead. Documentation: https://github.com/ipfs/kubo/blob/master/docs/config.md#reproviderstrategy") } + if cfg.Experimental.StrategicProviding { + log.Error("Experimental.StrategicProviding was removed. Remove it from your config and set Provider.Enabled=false to remove this message. Documentation: https://github.com/ipfs/kubo/blob/master/docs/experimental-features.md#strategic-providing") + cfg.Experimental.StrategicProviding = false + cfg.Provider.Enabled = config.False + } printLibp2pPorts(node) @@ -625,17 +630,19 @@ take effect. }() if !offline { - // Warn users who were victims of 'lowprofile' footgun (https://github.com/ipfs/kubo/pull/10524) - if cfg.Experimental.StrategicProviding { + // Warn users when provide systems are disabled + if !cfg.Provider.Enabled.WithDefault(config.DefaultProviderEnabled) { fmt.Print(` -⚠️ Reprovide system is disabled due to 'Experimental.StrategicProviding=true' + +⚠️ Provide and Reprovide systems are disabled due to 'Provide.Enabled=false' ⚠️ 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' +⚠️ If this is not intentional, call 'ipfs config profile apply announce-on' or set Provide.Enabled=true' `) } else if cfg.Reprovider.Interval.WithDefault(config.DefaultReproviderInterval) == 0 { fmt.Print(` -⚠️ Reprovider system is disabled due to 'Reprovider.Interval=0' + +⚠️ Provide and Reprovide systems are 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' diff --git a/config/experiments.go b/config/experiments.go index fab1f953c2e..6c43ac04f07 100644 --- a/config/experiments.go +++ b/config/experiments.go @@ -6,7 +6,7 @@ type Experiments struct { ShardingEnabled bool `json:",omitempty"` // deprecated by autosharding: https://github.com/ipfs/kubo/pull/8527 Libp2pStreamMounting bool P2pHttpProxy bool //nolint - StrategicProviding bool + StrategicProviding bool `json:",omitempty"` // removed, use Provider.Enabled instead OptimisticProvide bool OptimisticProvideJobsPoolSize int GatewayOverLibp2p bool `json:",omitempty"` diff --git a/config/profile.go b/config/profile.go index 605af355529..ec2e5a0b7ae 100644 --- a/config/profile.go +++ b/config/profile.go @@ -270,7 +270,7 @@ fetching may be degraded. }, }, "announce-off": { - Description: `Disables Reprovide system (and announcing to Amino DHT). + Description: `Disables Provide and Reprovide systems (announcing to Amino DHT). USE WITH CAUTION: The main use case for this is setups with manual Peering.Peers config. @@ -279,16 +279,16 @@ fetching may be degraded. one hosting it, and other peers are not already connected to it. `, Transform: func(c *Config) error { + c.Provider.Enabled = False 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).`, + Description: `Re-enables Provide and Reprovide systems (reverts announce-off profile).`, Transform: func(c *Config) error { + c.Provider.Enabled = True 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 }, }, diff --git a/config/provider.go b/config/provider.go index a1c44859889..4a2243acb07 100644 --- a/config/provider.go +++ b/config/provider.go @@ -1,12 +1,14 @@ package config const ( - DefaultProviderWorkerCount = 64 + DefaultProviderEnabled = true + DefaultProviderWorkerCount = 16 ) // Provider configuration describes how NEW CIDs are announced the moment they are created. // For periodical reprovide configuration, see Reprovider.* type Provider struct { + Enabled Flag `json:",omitempty"` Strategy *OptionalString `json:",omitempty"` // Unused, you are likely looking for Reprovider.Strategy instead WorkerCount *OptionalInteger `json:",omitempty"` // Number of concurrent provides allowed, 0 means unlimited } diff --git a/config/routing.go b/config/routing.go index 3fe501ee410..aea60c3bd24 100644 --- a/config/routing.go +++ b/config/routing.go @@ -48,10 +48,11 @@ type Routing struct { IgnoreProviders []string `json:",omitempty"` + // Simplified configuration used by default when Routing.Type=auto|autoclient DelegatedRouters []string `json:",omitempty"` + // Advanced configuration used when Routing.Type=custom Routers Routers `json:",omitempty"` - Methods Methods `json:",omitempty"` } diff --git a/core/commands/routing.go b/core/commands/routing.go index 3528a94f5ea..0804b1f44c3 100644 --- a/core/commands/routing.go +++ b/core/commands/routing.go @@ -9,6 +9,7 @@ import ( "strings" "time" + "github.com/ipfs/kubo/config" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" dag "github.com/ipfs/boxo/ipld/merkledag" @@ -158,6 +159,14 @@ var provideRefRoutingCmd = &cmds.Command{ if !nd.IsOnline { return ErrNotOnline } + // respect global config + cfg, err := nd.Repo.Config() + if err != nil { + return err + } + if !cfg.Provider.Enabled.WithDefault(config.DefaultProviderEnabled) { + return errors.New("invalid configuration: Provider.Enabled is set to 'false'") + } if len(nd.PeerHost.Network().Conns()) == 0 { return errors.New("cannot provide, no connected peers") @@ -254,6 +263,18 @@ Trigger reprovider to announce our data to network. return ErrNotOnline } + // respect global config + cfg, err := nd.Repo.Config() + if err != nil { + return err + } + if !cfg.Provider.Enabled.WithDefault(config.DefaultProviderEnabled) { + return errors.New("invalid configuration: Provider.Enabled is set to 'false'") + } + if cfg.Reprovider.Interval.WithDefault(config.DefaultReproviderInterval) == 0 { + return errors.New("invalid configuration: Reprovider.Interval is set to '0'") + } + err = nd.Provider.Reprovide(req.Context) if err != nil { return err diff --git a/core/node/bitswap.go b/core/node/bitswap.go index a52b3e75d34..e87464b8a67 100644 --- a/core/node/bitswap.go +++ b/core/node/bitswap.go @@ -83,7 +83,7 @@ type bitswapIn struct { // Bitswap creates the BitSwap server/client instance. // If Bitswap.ServerEnabled is false, the node will act only as a client // using an empty blockstore to prevent serving blocks to other peers. -func Bitswap(serverEnabled bool) interface{} { +func Bitswap(serverEnabled, libp2pEnabled, httpEnabled bool) interface{} { return func(in bitswapIn, lc fx.Lifecycle) (*bitswap.Bitswap, error) { var bitswapNetworks, bitswapLibp2p network.BitSwapNetwork var bitswapBlockstore blockstore.Blockstore = in.Bs @@ -93,7 +93,8 @@ func Bitswap(serverEnabled bool) interface{} { bitswapLibp2p = bsnet.NewFromIpfsHost(in.Host) } - if httpCfg := in.Cfg.HTTPRetrieval; httpCfg.Enabled.WithDefault(config.DefaultHTTPRetrievalEnabled) { + if httpEnabled { + httpCfg := in.Cfg.HTTPRetrieval maxBlockSize, err := humanize.ParseBytes(httpCfg.MaxBlockSize.WithDefault(config.DefaultHTTPRetrievalMaxBlockSize)) if err != nil { return nil, err @@ -136,7 +137,7 @@ func Bitswap(serverEnabled bool) interface{} { return nil, err } - // Explicitly enable/disable server to ensure desired provide mode + // Explicitly enable/disable server in.BitswapOpts = append(in.BitswapOpts, bitswap.WithServerEnabled(serverEnabled)) bs := bitswap.New(helpers.LifecycleCtx(in.Mctx, lc), bitswapNetworks, providerQueryMgr, bitswapBlockstore, in.BitswapOpts...) diff --git a/core/node/groups.go b/core/node/groups.go index e4682f6a6bc..3a952ccfe10 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -337,16 +337,18 @@ func Online(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part isBitswapLibp2pEnabled := cfg.Bitswap.Libp2pEnabled.WithDefault(config.DefaultBitswapLibp2pEnabled) isBitswapServerEnabled := cfg.Bitswap.ServerEnabled.WithDefault(config.DefaultBitswapServerEnabled) + isHTTPRetrievalEnabled := cfg.HTTPRetrieval.Enabled.WithDefault(config.DefaultHTTPRetrievalEnabled) - // Don't provide from bitswap when the legacy noop experiment "strategic provider service" is active - isBitswapServerEnabled = isBitswapServerEnabled && !cfg.Experimental.StrategicProviding + // Right now Provider and Reprovider systems are tied together - disabling Reprovider by setting interval to 0 disables Provider + // and vice versa: Provider.Enabled=false will disable both Provider of new CIDs and the Reprovider of old ones. + isProviderEnabled := cfg.Provider.Enabled.WithDefault(config.DefaultProviderEnabled) && cfg.Reprovider.Interval.WithDefault(config.DefaultReproviderInterval) != 0 return fx.Options( fx.Provide(BitswapOptions(cfg)), - fx.Provide(Bitswap(isBitswapServerEnabled)), + fx.Provide(Bitswap(isBitswapServerEnabled, isBitswapLibp2pEnabled, isHTTPRetrievalEnabled)), fx.Provide(OnlineExchange(isBitswapLibp2pEnabled)), // Replace our Exchange with a Providing exchange! - fx.Decorate(ProvidingExchange(isBitswapServerEnabled)), + fx.Decorate(ProvidingExchange(isProviderEnabled && isBitswapServerEnabled)), fx.Provide(DNSResolver), fx.Provide(Namesys(ipnsCacheSize, cfg.Ipns.MaxCacheTTL.WithDefault(config.DefaultIpnsMaxCacheTTL))), fx.Provide(Peering), @@ -358,7 +360,7 @@ func Online(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part LibP2P(bcfg, cfg, userResourceOverrides), OnlineProviders( - cfg.Experimental.StrategicProviding, + isProviderEnabled, cfg.Reprovider.Strategy.WithDefault(config.DefaultReproviderStrategy), cfg.Reprovider.Interval.WithDefault(config.DefaultReproviderInterval), cfg.Routing.AcceleratedDHTClient.WithDefault(config.DefaultAcceleratedDHTClient), diff --git a/core/node/provider.go b/core/node/provider.go index d0081eb0aec..79fed2a4f99 100644 --- a/core/node/provider.go +++ b/core/node/provider.go @@ -132,8 +132,8 @@ https://github.com/ipfs/kubo/blob/master/docs/config.md#routingaccelerateddhtcli // ONLINE/OFFLINE // OnlineProviders groups units managing provider routing records online -func OnlineProviders(useStrategicProviding bool, reprovideStrategy string, reprovideInterval time.Duration, acceleratedDHTClient bool, provideWorkerCount int) fx.Option { - if useStrategicProviding { +func OnlineProviders(provide bool, reprovideStrategy string, reprovideInterval time.Duration, acceleratedDHTClient bool, provideWorkerCount int) fx.Option { + if !provide { return OfflineProviders() } diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index c8fd97014b6..023dcfd5425 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -181,12 +181,16 @@ to delays in initial advertisements (provides). Provides and Reprovides now have separate queues, allowing for immediate provide of new CIDs and optimised batching of reprovides. -This change introduces a new configuration option for limiting the number of -concurrent provide operations: -[`Provider.WorkerCount`](https://github.com/ipfs/kubo/blob/master/docs/config.md#providerworkercount). +###### New `Provider` configuration options + +This change introduces a new configuration options: + +- [`Provider.Enabled`](https://github.com/ipfs/kubo/blob/master/docs/config.md#providerenabled) is a global flag for disabling both [Provider](https://github.com/ipfs/kubo/blob/master/docs/config.md#provider) and [Reprovider](https://github.com/ipfs/kubo/blob/master/docs/config.md#reprovider) systems (announcing new/old CIDs to amino DHT). +- [`Provider.WorkerCount`](https://github.com/ipfs/kubo/blob/master/docs/config.md#providerworkercount) for limiting the number of concurrent provide operations, allows for fine-tuning the trade-off between announcement speed and system load when announcing new CIDs. +- Removed `Experimental.StrategicProviding`. Superseded by `Provider.Enabled`, `Reprovider.Interval` and [`Reprovider.Strategy`](https://github.com/ipfs/kubo/blob/master/docs/config.md#reproviderstrategy). > [!TIP] -> Users who need to provide large volumes of content immediately should consider removing the cap on concurrent provide operations and also set `Routing.AcceleratedDHTClient` to `true`. +> Users who need to provide large volumes of content immediately should consider setting `Routing.AcceleratedDHTClient` to `true`. If that is not enough, consider adjusting `Provider.WorkerCount` to a higher value. ###### Deprecated `ipfs stats provider` diff --git a/docs/config.md b/docs/config.md index 3da157d19ac..4b8d66ac02c 100644 --- a/docs/config.md +++ b/docs/config.md @@ -110,6 +110,7 @@ config file at runtime. - [`Pinning.RemoteServices: Policies.MFS.PinName`](#pinningremoteservices-policiesmfspinname) - [`Pinning.RemoteServices: Policies.MFS.RepinInterval`](#pinningremoteservices-policiesmfsrepininterval) - [`Provider`](#provider) + - [`Provider.Enabled`](#providerenabled) - [`Provider.Strategy`](#providerstrategy) - [`Provider.WorkerCount`](#providerworkercount) - [`Pubsub`](#pubsub) @@ -962,7 +963,7 @@ We are working on developing a modern replacement. To support our efforts, pleas 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`, +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] @@ -1000,7 +1001,7 @@ Type: `array[string]` #### `Gateway.PublicGateways: UseSubdomains` A boolean to configure whether the gateway at the hostname should be -a [Subdomain Gateway](https://specs.ipfs.tech/http-gateways/subdomain-gateway/) +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. @@ -1110,7 +1111,7 @@ $ ipfs config --json Gateway.PublicGateways '{"localhost": null }' ### `Gateway` recipes -Below is a list of the most common public gateway setups. +Below is a list of the most common gateway setups. * Public [subdomain gateway](https://docs.ipfs.tech/how-to/address-ipfs-on-web/#subdomain-gateway) at `http://{cid}.ipfs.dweb.link` (each content root gets its own Origin) ```console @@ -1121,6 +1122,7 @@ Below is a list of the most common public gateway setups. } }' ``` + - **Performance:** consider running with `Routing.AcceleratedDHTClient=true` and either `Provider.Enabled=false` (avoid providing newly retrieved blocks) or `Provider.WorkerCount=0` (provide as fast as possible, at the cost of increased load) - **Backward-compatible:** this feature enables automatic redirects from content paths to subdomains: `http://dweb.link/ipfs/{cid}` β†’ `http://{cid}.ipfs.dweb.link` @@ -1145,6 +1147,7 @@ Below is a list of the most common public gateway setups. } }' ``` + - **Performance:** when running an open, recursive gateway consider running with `Routing.AcceleratedDHTClient=true` and either `Provider.Enabled=false` (avoid providing newly retrieved blocks) or `Provider.WorkerCount=0` (provide as fast as possible, at the cost of increased load) * Public [DNSLink](https://dnslink.io/) gateway resolving every hostname passed in `Host` header. ```console @@ -1503,15 +1506,28 @@ commands. For periodical DHT reprovide settings, see [`Reprovide.*`](#reprovider). +### `Provider.Enabled` + +Controls whether Kubo provider and reprovide systems are enabled. + +> [!CAUTION] +> Disabling this, will disable BOTH `Provider` system for new CIDs +> and the periodical reprovide ([`Reprovider.Interval`](#reprovider)) of old CIDs. + +Default: `true` + +Type: `flag` + ### `Provider.Strategy` Legacy, not used at the moment, see [`Reprovider.Strategy`](#reproviderstrategy) instead. ### `Provider.WorkerCount` -Sets the maximum number of _concurrent_ DHT provide operations. DHT reprovides -operations do **not** count against that limit. A value of `0` allows an -unlimited number of provide workers. +Sets the maximum number of _concurrent_ DHT provide operations (announcement of new CIDs). + +[`Reprovider`](#reprovider) operations do **not** count against this limit. +A value of `0` allows an unlimited number of provide workers. If the [accelerated DHT client](#routingaccelerateddhtclient) is enabled, each provide operation opens ~20 connections in parallel. With the standard DHT @@ -1520,13 +1536,17 @@ connections, with at most 10 active at once. Provides complete more quickly when using the accelerated client. Be mindful of how many simultaneous connections this setting can generate. -For nodes without strict connection limits that need to provide large volumes -of content immediately, we recommend enabling the `Routing.AcceleratedDHTClient` and -setting `Provider.WorkerCount` to `0` (unlimited). +> [!CAUTION] +> For nodes without strict connection limits that need to provide large volumes +> of content immediately, we recommend enabling the `Routing.AcceleratedDHTClient` and +> setting `Provider.WorkerCount` to `0` (unlimited). +> +> At the same time, mind that raising this value too high may lead to increased load. +> Proceed with caution, ensure proper hardware and networking are in place. -Default: `64` +Default: `16` -Type: `integer` (non-negative; `0` means unlimited number of workers) +Type: `optionalInteger` (non-negative; `0` means unlimited number of workers) ## `Pubsub` @@ -1704,7 +1724,11 @@ system. 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. +manually announce your content periodically or run your own routing system +and convince users to add it to [`Routing.DelegatedRouters`](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingdelegatedrouters). + +> [!CAUTION] +> To maintain backward-compatibility, setting `Reprovider.Interval=0` will also disable Provider system (equivalent of `Provider.Enabled=false`) Default: `22h` (`DefaultReproviderInterval`) @@ -1868,12 +1892,13 @@ Type: `array[string]` ### `Routing.DelegatedRouters` -This is an array of URL hostnames that support the [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) which are used alongside the DHT when [`Routing.Type`](#routingtype) is set to `auto` or `autoclient`. +An array of URL hostnames for delegated routers to be queried in addition to the Amino DHT when `Routing.Type` is set to `auto` (default) or `autoclient`. +These endpoints must support the [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/). > [!TIP] > Delegated routing allows IPFS implementations to offload tasks like content routing, peer routing, and naming to a separate process or server while also benefiting from HTTP caching. > -> One can run their own delegated router either by implementing the [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) themselves, or by using [Someguy](https://github.com/ipfs/someguy), a turn-key implementation that proxies requests to the Amino DHT and other delegated routing servers, such as the Network Indexer at `cid.contact`. Public utility instance of Someguy is hosted at [`https://delegated-ipfs.dev`](https://docs.ipfs.tech/concepts/public-utilities/#delegated-routing). +> One can run their own delegated router either by implementing the [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) themselves, or by using [Someguy](https://github.com/ipfs/someguy), a turn-key implementation that proxies requests to other routing systems. A public utility instance of Someguy is hosted at [`https://delegated-ipfs.dev`](https://docs.ipfs.tech/concepts/public-utilities/#delegated-routing). Default: `["https://cid.contact"]` (empty or `nil` will also use this default; to disable delegated routing, set `Routing.Type` to `dht` or `dhtclient`) @@ -1881,11 +1906,14 @@ Type: `array[string]` ### `Routing.Routers` -**EXPERIMENTAL: `Routing.Routers` configuration may change in future release** +Alternative configuration used when `Routing.Type=custom`. -Map of additional Routers. +> [!WARNING] +> **EXPERIMENTAL: `Routing.Routers` configuration may change in future release** +> +> Consider this advanced low-level config: Most users can simply use `Routing.Type=auto` or `autoclient` and set up basic config in user-friendly [`Routing.DelegatedRouters`](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingdelegatedrouters). -Allows for extending the default routing (Amino DHT) with alternative Router +Allows for replacing the default routing (Amino DHT) with alternative Router implementations. The map key is a name of a Router, and the value is its configuration. @@ -1945,7 +1973,14 @@ Type: `object[string->string]` ### `Routing: Methods` -`Methods:map` will define which routers will be executed per method. The key will be the name of the method: `"provide"`, `"find-providers"`, `"find-peers"`, `"put-ipns"`, `"get-ipns"`. All methods must be added to the list. +`Methods:map` will define which routers will be executed per method used when `Routing.Type=custom`. + +> [!WARNING] +> **EXPERIMENTAL: `Routing.Routers` configuration may change in future release** +> +> Consider this advanced low-level config: Most users can simply use `Routing.Type=auto` or `autoclient` and set up basic config in user-friendly [`Routing.DelegatedRouters`](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingdelegatedrouters). + +The key will be the name of the method: `"provide"`, `"find-providers"`, `"find-peers"`, `"put-ipns"`, `"get-ipns"`. All methods must be added to the list. The value will contain: - `RouterName:string`: Name of the router. It should be one of the previously added to `Routing.Routers` list. diff --git a/docs/experimental-features.md b/docs/experimental-features.md index 7d0069fc6f7..fbee3d480b1 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -537,27 +537,9 @@ ipfs config --json Swarm.RelayClient.Enabled true ### State -Experimental, disabled by default. - -Replaces the existing provide mechanism with a robust, strategic provider system. Currently enabling this option will provide nothing. - -### How to enable - -Modify your ipfs config: - -``` -ipfs config --json Experimental.StrategicProviding true -``` - -### Road to being a real feature +`Experimental.StrategicProviding` was removed in Kubo v0.35. -- [ ] needs real-world testing -- [ ] needs adoption -- [ ] needs to support all provider subsystem features - - [X] provide nothing - - [ ] provide roots - - [ ] provide all - - [ ] provide strategic +Replaced by [`Provide.Enabled`](https://github.com/ipfs/kubo/blob/master/docs/config.md#providerenabled) and [`Reprovider.Strategy`](https://github.com/ipfs/kubo/blob/master/docs/config.md#reproviderstrategy). ## GraphSync diff --git a/test/cli/provider_test.go b/test/cli/provider_test.go index 81af7814954..7e2bee411c0 100644 --- a/test/cli/provider_test.go +++ b/test/cli/provider_test.go @@ -7,6 +7,7 @@ import ( "github.com/ipfs/kubo/test/cli/harness" "github.com/ipfs/kubo/test/cli/testutils" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -33,11 +34,11 @@ func TestProvider(t *testing.T) { } } - t.Run("Basic Providing", func(t *testing.T) { + t.Run("Provider.Enabled=true announces new CIDs created by ipfs add", func(t *testing.T) { t.Parallel() nodes := initNodes(t, 2, func(n *harness.Node) { - n.SetIPFSConfig("Experimental.StrategicProviding", false) + n.SetIPFSConfig("Provider.Enabled", true) }) defer nodes.StopDaemons() @@ -48,11 +49,11 @@ func TestProvider(t *testing.T) { expectProviders(t, cid, nodes[0].PeerID().String(), nodes[1:]...) }) - t.Run("Basic Strategic Providing", func(t *testing.T) { + t.Run("Provider.Enabled=false disables announcement of new CID from ipfs add", func(t *testing.T) { t.Parallel() nodes := initNodes(t, 2, func(n *harness.Node) { - n.SetIPFSConfig("Experimental.StrategicProviding", true) + n.SetIPFSConfig("Provider.Enabled", false) }) defer nodes.StopDaemons() @@ -60,6 +61,75 @@ func TestProvider(t *testing.T) { expectNoProviders(t, cid, nodes[1:]...) }) + t.Run("Provider.Enabled=false disables manual announcement via RPC command", func(t *testing.T) { + t.Parallel() + + nodes := initNodes(t, 2, func(n *harness.Node) { + n.SetIPFSConfig("Provider.Enabled", false) + }) + defer nodes.StopDaemons() + + cid := nodes[0].IPFSAddStr(time.Now().String()) + res := nodes[0].RunIPFS("routing", "provide", cid) + assert.Contains(t, res.Stderr.Trimmed(), "invalid configuration: Provider.Enabled is set to 'false'") + assert.Equal(t, 1, res.ExitCode()) + + expectNoProviders(t, cid, nodes[1:]...) + }) + + // Right now Provide and Reprovide are tied together + t.Run("Reprovide.Interval=0 disables announcement of new CID too", 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()) + expectNoProviders(t, cid, nodes[1:]...) + }) + + // It is a lesser evil - forces users to fix their config and have some sort of interval + t.Run("Manual Reprovider trigger does not work when periodic Reprovider is disabled", 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:]...) + + res := nodes[0].RunIPFS("routing", "reprovide") + assert.Contains(t, res.Stderr.Trimmed(), "invalid configuration: Reprovider.Interval is set to '0'") + assert.Equal(t, 1, res.ExitCode()) + + expectNoProviders(t, cid, nodes[1:]...) + }) + + // It is a lesser evil - forces users to fix their config and have some sort of interval + t.Run("Manual Reprovider trigger does not work when Provider system is disabled", func(t *testing.T) { + t.Parallel() + + nodes := initNodes(t, 2, func(n *harness.Node) { + n.SetIPFSConfig("Provider.Enabled", false) + }) + defer nodes.StopDaemons() + + cid := nodes[0].IPFSAddStr(time.Now().String(), "--offline") + + expectNoProviders(t, cid, nodes[1:]...) + + res := nodes[0].RunIPFS("routing", "reprovide") + assert.Contains(t, res.Stderr.Trimmed(), "invalid configuration: Provider.Enabled is set to 'false'") + assert.Equal(t, 1, res.ExitCode()) + + expectNoProviders(t, cid, nodes[1:]...) + }) + t.Run("Reprovides with 'all' strategy", func(t *testing.T) { t.Parallel() @@ -149,20 +219,4 @@ func TestProvider(t *testing.T) { 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("routing", "reprovide") - - expectProviders(t, cid, nodes[0].PeerID().String(), nodes[1:]...) - }) } From 8bdbcbf9c2af56862218c4e58eb78507eca32dcf Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 15 May 2025 23:43:43 +0200 Subject: [PATCH 38/42] fix(fuse): ipns error handling and friendly errors (#10807) * fix(fusei/ux): check if paths exist, print err * fix(fuse): ipns 'could not resolve' error type changed when code got extracted to boxo, but it was not caught because of FUSE tests do not cover IPNS in online mode Closes #8095 Closes #2167 Closes #3013 * docs: clarify opt-in (cherry picked from commit f84fb2849bb64df667dd65c1912a0e691001ea06) --- cmd/ipfs/kubo/daemon.go | 29 +++++++++++++++++++++++++++++ docs/config.md | 5 ++++- fuse/ipns/ipns_unix.go | 3 ++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index 5cdf3fa1dca..94b633f7941 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -1065,16 +1065,25 @@ func mountFuse(req *cmds.Request, cctx *oldcmds.Context) error { if !found { fsdir = cfg.Mounts.IPFS } + if err := checkFusePath("Mounts.IPFS", fsdir); err != nil { + return err + } nsdir, found := req.Options[ipnsMountKwd].(string) if !found { nsdir = cfg.Mounts.IPNS } + if err := checkFusePath("Mounts.IPNS", nsdir); err != nil { + return err + } mfsdir, found := req.Options[mfsMountKwd].(string) if !found { mfsdir = cfg.Mounts.MFS } + if err := checkFusePath("Mounts.MFS", mfsdir); err != nil { + return err + } node, err := cctx.ConstructNode() if err != nil { @@ -1091,6 +1100,26 @@ func mountFuse(req *cmds.Request, cctx *oldcmds.Context) error { return nil } +func checkFusePath(name, path string) error { + if path == "" { + return fmt.Errorf("%s path cannot be empty", name) + } + + fileInfo, err := os.Stat(path) + if err != nil { + if os.IsNotExist(err) { + return fmt.Errorf("%s path (%q) does not exist: %w", name, path, err) + } + return fmt.Errorf("error while inspecting %s path (%q): %w", name, path, err) + } + + if !fileInfo.IsDir() { + return fmt.Errorf("%s path (%q) is not a directory", name, path) + } + + return nil +} + func maybeRunGC(req *cmds.Request, node *core.IpfsNode) (<-chan error, error) { enableGC, _ := req.Options[enableGCKwd].(bool) if !enableGC { diff --git a/docs/config.md b/docs/config.md index 4b8d66ac02c..e40ac5887e4 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1373,7 +1373,10 @@ Default: `cache` ## `Mounts` > [!CAUTION] -> **EXPERIMENTAL:** read about current limitations at [fuse.md](./fuse.md). +> **EXPERIMENTAL:** +> This feature is disabled by default, requires an explicit opt-in with `ipfs mount` or `ipfs daemon --mount`. +> +> Read about current limitations at [fuse.md](./fuse.md). FUSE mount point configuration options. diff --git a/fuse/ipns/ipns_unix.go b/fuse/ipns/ipns_unix.go index 23704cabd52..ea2e753017e 100644 --- a/fuse/ipns/ipns_unix.go +++ b/fuse/ipns/ipns_unix.go @@ -16,6 +16,7 @@ import ( dag "github.com/ipfs/boxo/ipld/merkledag" ft "github.com/ipfs/boxo/ipld/unixfs" + "github.com/ipfs/boxo/namesys" "github.com/ipfs/boxo/path" fuse "bazil.org/fuse" @@ -95,7 +96,7 @@ func loadRoot(ctx context.Context, ipfs iface.CoreAPI, key iface.Key) (*mfs.Root node, err := ipfs.ResolveNode(ctx, key.Path()) switch err { case nil: - case iface.ErrResolveFailed: + case namesys.ErrResolveFailed: node = ft.EmptyDirNode() default: log.Errorf("looking up %s: %s", key.Path(), err) From 623902ebf27a63e493b93877b9ade50c660f939d Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 15 May 2025 23:47:38 +0200 Subject: [PATCH 39/42] chore(version): 0.35.0-rc2 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index df548748db3..1b9b7e05617 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.35.0-rc1" +const CurrentVersionNumber = "0.35.0-rc2" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 91a146d5fb86b2fa19b69dccb6644ce3cb26d47c Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 21 May 2025 00:29:57 +0200 Subject: [PATCH 40/42] fix: p2p-forge v0.5.1 ignoring /p2p-circuit (#10813) https://github.com/ipshipyard/p2p-forge/pull/68 (cherry picked from commit 3290afcef8dba34296f26dfdc77554fd62dd3e8c) --- docs/changelogs/v0.35.md | 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 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 7 files changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index 023dcfd5425..759f1ae9ec4 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -267,6 +267,7 @@ If the lock cannot be acquired because someone else has the lock, and `IPFS_WAIT - update `go-libp2p-pubsub` to [v0.13.1](https://github.com:/libp2p/go-libp2p-pubsub/releases/tag/v0.13.1) - update `go-libp2p-kad-dht` to [v0.32.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.32.0) (incl. [v0.31.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.31.0)) - update `go-log` to [v2.6.0](https://github.com/ipfs/go-log/releases/tag/v2.6.0) +- update `p2p-forge/client` to [v0.5.1](https://github.com/ipshipyard/p2p-forge/releases/tag/v0.5.1) ### πŸ“ Changelog ### πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index c4b5597441e..8524c138599 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -111,7 +111,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.4.0 // indirect + github.com/ipshipyard/p2p-forge v0.5.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/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 29c11e00886..02ba33ac470 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -406,8 +406,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.4.0 h1:A40PW027nCZn0d/pw5ufMoxnAo9wZwrG+iuz18A8P5I= -github.com/ipshipyard/p2p-forge v0.4.0/go.mod h1:hVGPP24xrRezP2+z6q8udEW36w89M+jWuWBz9meLggY= +github.com/ipshipyard/p2p-forge v0.5.1 h1:9MCpAlk+wNhy7W/yOYKgi9KlXPnyb0abmDpsRPHUDxQ= +github.com/ipshipyard/p2p-forge v0.5.1/go.mod h1:GNDXM2CR8KRS8mJGw7ARIRVlrG9NH8MdewgNVfIIByA= 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= diff --git a/go.mod b/go.mod index 00121bc001f..7b70363f9be 100644 --- a/go.mod +++ b/go.mod @@ -48,7 +48,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.4.0 + github.com/ipshipyard/p2p-forge v0.5.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 diff --git a/go.sum b/go.sum index 4db34250781..bd0e4327430 100644 --- a/go.sum +++ b/go.sum @@ -476,8 +476,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.4.0 h1:A40PW027nCZn0d/pw5ufMoxnAo9wZwrG+iuz18A8P5I= -github.com/ipshipyard/p2p-forge v0.4.0/go.mod h1:hVGPP24xrRezP2+z6q8udEW36w89M+jWuWBz9meLggY= +github.com/ipshipyard/p2p-forge v0.5.1 h1:9MCpAlk+wNhy7W/yOYKgi9KlXPnyb0abmDpsRPHUDxQ= +github.com/ipshipyard/p2p-forge v0.5.1/go.mod h1:GNDXM2CR8KRS8mJGw7ARIRVlrG9NH8MdewgNVfIIByA= 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= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 530e7c421cb..dde8ee6af2c 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -140,7 +140,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.4.0 // indirect + github.com/ipshipyard/p2p-forge v0.5.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/jgautheron/goconst v1.7.1 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 790426ebf46..8c9bbdd340a 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -370,8 +370,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.4.0 h1:A40PW027nCZn0d/pw5ufMoxnAo9wZwrG+iuz18A8P5I= -github.com/ipshipyard/p2p-forge v0.4.0/go.mod h1:hVGPP24xrRezP2+z6q8udEW36w89M+jWuWBz9meLggY= +github.com/ipshipyard/p2p-forge v0.5.1 h1:9MCpAlk+wNhy7W/yOYKgi9KlXPnyb0abmDpsRPHUDxQ= +github.com/ipshipyard/p2p-forge v0.5.1/go.mod h1:GNDXM2CR8KRS8mJGw7ARIRVlrG9NH8MdewgNVfIIByA= 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-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= From b47f0b30a8a32d6f623ef7a875f76a052eda8d6b Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 21 May 2025 17:26:25 +0200 Subject: [PATCH 41/42] fix: go-libp2p-kad-dht v0.33.1 (#10814) https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.33.1 (cherry picked from commit 46b2e60c9f542a94b9922a90b9a329d19c39509a) --- docs/changelogs/v0.35.md | 2 +- docs/examples/kubo-as-a-library/go.mod | 18 ++++++------ docs/examples/kubo-as-a-library/go.sum | 36 +++++++++++------------ go.mod | 20 ++++++------- go.sum | 40 +++++++++++++------------- test/dependencies/go.mod | 20 ++++++------- test/dependencies/go.sum | 40 +++++++++++++------------- 7 files changed, 88 insertions(+), 88 deletions(-) diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index 759f1ae9ec4..9186b26085c 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -265,7 +265,7 @@ If the lock cannot be acquired because someone else has the lock, and `IPFS_WAIT - update `go-ds-pebble` to [v0.5.0](https://github.com/ipfs/go-ds-pebble/releases/tag/v0.5.0) - update `pebble` to [v2.0.3](https://github.com/cockroachdb/pebble/releases/tag/v2.0.3) - update `go-libp2p-pubsub` to [v0.13.1](https://github.com:/libp2p/go-libp2p-pubsub/releases/tag/v0.13.1) -- update `go-libp2p-kad-dht` to [v0.32.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.32.0) (incl. [v0.31.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.31.0)) +- update `go-libp2p-kad-dht` to [v0.33.1](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.33.1) (incl. [v0.33.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.33.0), [v0.32.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.32.0), [v0.31.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.31.0)) - update `go-log` to [v2.6.0](https://github.com/ipfs/go-log/releases/tag/v2.6.0) - update `p2p-forge/client` to [v0.5.1](https://github.com/ipshipyard/p2p-forge/releases/tag/v0.5.1) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 8524c138599..c5334ab2a78 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -126,7 +126,7 @@ require ( github.com/libp2p/go-doh-resolver v0.5.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.32.0 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.33.1 // indirect github.com/libp2p/go-libp2p-kbucket v0.7.0 // indirect github.com/libp2p/go-libp2p-pubsub v0.13.1 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect @@ -141,7 +141,7 @@ require ( github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mholt/acmez/v3 v3.0.0 // indirect - github.com/miekg/dns v1.1.65 // indirect + github.com/miekg/dns v1.1.66 // 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 @@ -225,14 +225,14 @@ require ( go.uber.org/zap v1.27.0 // indirect go.uber.org/zap/exp v0.3.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.37.0 // indirect - golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect + golang.org/x/crypto v0.38.0 // indirect + golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect golang.org/x/mod v0.24.0 // indirect - golang.org/x/net v0.39.0 // indirect - golang.org/x/sync v0.13.0 // indirect + golang.org/x/net v0.40.0 // indirect + golang.org/x/sync v0.14.0 // indirect golang.org/x/sys v0.33.0 // indirect - golang.org/x/text v0.24.0 // indirect - golang.org/x/tools v0.32.0 // indirect + golang.org/x/text v0.25.0 // indirect + golang.org/x/tools v0.33.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gonum.org/v1/gonum v0.16.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect @@ -240,5 +240,5 @@ require ( google.golang.org/grpc v1.67.1 // indirect google.golang.org/protobuf v1.36.6 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - lukechampine.com/blake3 v1.4.0 // indirect + lukechampine.com/blake3 v1.4.1 // indirect ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 02ba33ac470..0a3f3a32900 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -470,8 +470,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.32.0 h1:dpyq7o00od98vPQG0IZvNHpeLnKyuICN1nVzGnVMC9k= -github.com/libp2p/go-libp2p-kad-dht v0.32.0/go.mod h1:vQU5oE9hMHXJhSQawbZapC9u0U9dc+tWC0DYasGmIAA= +github.com/libp2p/go-libp2p-kad-dht v0.33.1 h1:hKFhHMf7WH69LDjaxsJUWOU6qZm71uO47M/a5ijkiP0= +github.com/libp2p/go-libp2p-kad-dht v0.33.1/go.mod h1:CdmNk4VeGJa9EXM9SLNyNVySEvduKvb+5rSC/H4pLAo= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.7.0 h1:vYDvRjkyJPeWunQXqcW2Z6E93Ywx7fX0jgzb/dGOKCs= github.com/libp2p/go-libp2p-kbucket v0.7.0/go.mod h1:blOINGIj1yiPYlVEX0Rj9QwEkmVnz3EP8LK1dRKBC6g= @@ -519,8 +519,8 @@ github.com/mholt/acmez/v3 v3.0.0 h1:r1NcjuWR0VaKP2BTjDK9LRFBw/WvURx3jlaEUl9Ht8E= github.com/mholt/acmez/v3 v3.0.0/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.65 h1:0+tIPHzUW0GCge7IiK3guGP57VAw7hoPDfApjkMD1Fc= -github.com/miekg/dns v1.1.65/go.mod h1:Dzw9769uoKVaLuODMDZz9M6ynFU6Em65csPuoi8G0ck= +github.com/miekg/dns v1.1.66 h1:FeZXOS3VCVsKnEAd+wBkjMC3D2K+ww66Cq3VnCINuJE= +github.com/miekg/dns v1.1.66/go.mod h1:jGFzBsSNbJw6z1HYut1RKBKHA9PBdxeHrZG8J+gC2WE= 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= @@ -892,8 +892,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.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= -golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= +golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= +golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= 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-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-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM= -golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8= +golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI= +golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ= 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= @@ -963,8 +963,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.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= -golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= +golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= +golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= 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= @@ -983,8 +983,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.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= -golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= +golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 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= @@ -1054,8 +1054,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.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= -golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= 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= @@ -1098,8 +1098,8 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 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.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU= -golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s= +golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= +golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= 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= @@ -1204,8 +1204,8 @@ 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.4.0 h1:xDbKOZCVbnZsfzM6mHSYcGRHZ3YrLDzqz8XnV4uaD5w= -lukechampine.com/blake3 v1.4.0/go.mod h1:MQJNQCTnR+kwOP/JEZSxj3MaQjp80FOFSNMMHXcSeX0= +lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg= +lukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo= 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= diff --git a/go.mod b/go.mod index 7b70363f9be..74ecb4bf78e 100644 --- a/go.mod +++ b/go.mod @@ -55,7 +55,7 @@ require ( github.com/libp2p/go-doh-resolver v0.5.0 github.com/libp2p/go-libp2p v0.41.1 github.com/libp2p/go-libp2p-http v0.5.0 - github.com/libp2p/go-libp2p-kad-dht v0.32.0 + github.com/libp2p/go-libp2p-kad-dht v0.33.1 github.com/libp2p/go-libp2p-kbucket v0.7.0 github.com/libp2p/go-libp2p-pubsub v0.13.1 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 @@ -87,10 +87,10 @@ require ( 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.37.0 - golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 + golang.org/x/crypto v0.38.0 + golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 golang.org/x/mod v0.24.0 - golang.org/x/sync v0.13.0 + golang.org/x/sync v0.14.0 golang.org/x/sys v0.33.0 google.golang.org/protobuf v1.36.6 ) @@ -187,7 +187,7 @@ require ( github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect github.com/mholt/acmez/v3 v3.0.0 // indirect - github.com/miekg/dns v1.1.65 // indirect + github.com/miekg/dns v1.1.66 // 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 @@ -265,11 +265,11 @@ require ( go.uber.org/mock v0.5.0 // indirect go.uber.org/zap/exp v0.3.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/net v0.39.0 // indirect + golang.org/x/net v0.40.0 // indirect golang.org/x/oauth2 v0.25.0 // indirect - golang.org/x/term v0.31.0 // indirect - golang.org/x/text v0.24.0 // indirect - golang.org/x/tools v0.32.0 // indirect + golang.org/x/term v0.32.0 // indirect + golang.org/x/text v0.25.0 // indirect + golang.org/x/tools v0.33.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gonum.org/v1/gonum v0.16.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect @@ -277,5 +277,5 @@ require ( 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.4.0 // indirect + lukechampine.com/blake3 v1.4.1 // indirect ) diff --git a/go.sum b/go.sum index bd0e4327430..6eafdb1ddec 100644 --- a/go.sum +++ b/go.sum @@ -556,8 +556,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.32.0 h1:dpyq7o00od98vPQG0IZvNHpeLnKyuICN1nVzGnVMC9k= -github.com/libp2p/go-libp2p-kad-dht v0.32.0/go.mod h1:vQU5oE9hMHXJhSQawbZapC9u0U9dc+tWC0DYasGmIAA= +github.com/libp2p/go-libp2p-kad-dht v0.33.1 h1:hKFhHMf7WH69LDjaxsJUWOU6qZm71uO47M/a5ijkiP0= +github.com/libp2p/go-libp2p-kad-dht v0.33.1/go.mod h1:CdmNk4VeGJa9EXM9SLNyNVySEvduKvb+5rSC/H4pLAo= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.7.0 h1:vYDvRjkyJPeWunQXqcW2Z6E93Ywx7fX0jgzb/dGOKCs= github.com/libp2p/go-libp2p-kbucket v0.7.0/go.mod h1:blOINGIj1yiPYlVEX0Rj9QwEkmVnz3EP8LK1dRKBC6g= @@ -617,8 +617,8 @@ github.com/mholt/acmez/v3 v3.0.0 h1:r1NcjuWR0VaKP2BTjDK9LRFBw/WvURx3jlaEUl9Ht8E= github.com/mholt/acmez/v3 v3.0.0/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.65 h1:0+tIPHzUW0GCge7IiK3guGP57VAw7hoPDfApjkMD1Fc= -github.com/miekg/dns v1.1.65/go.mod h1:Dzw9769uoKVaLuODMDZz9M6ynFU6Em65csPuoi8G0ck= +github.com/miekg/dns v1.1.66 h1:FeZXOS3VCVsKnEAd+wBkjMC3D2K+ww66Cq3VnCINuJE= +github.com/miekg/dns v1.1.66/go.mod h1:jGFzBsSNbJw6z1HYut1RKBKHA9PBdxeHrZG8J+gC2WE= 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= @@ -1062,8 +1062,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.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= -golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= +golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= +golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= 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= @@ -1074,8 +1074,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-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM= -golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8= +golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI= +golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ= 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= @@ -1152,8 +1152,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.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= -golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= +golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= +golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= 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= @@ -1180,8 +1180,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.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= -golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= +golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 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= @@ -1262,8 +1262,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.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o= -golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= +golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= +golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= 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= @@ -1275,8 +1275,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.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= -golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= 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= @@ -1336,8 +1336,8 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 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.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU= -golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s= +golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= +golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= 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= @@ -1477,8 +1477,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= -lukechampine.com/blake3 v1.4.0 h1:xDbKOZCVbnZsfzM6mHSYcGRHZ3YrLDzqz8XnV4uaD5w= -lukechampine.com/blake3 v1.4.0/go.mod h1:MQJNQCTnR+kwOP/JEZSxj3MaQjp80FOFSNMMHXcSeX0= +lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg= +lukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo= 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= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index dde8ee6af2c..a73c6d6605f 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -169,7 +169,7 @@ require ( github.com/libp2p/go-flow-metrics v0.2.0 // indirect github.com/libp2p/go-libp2p v0.41.1 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.32.0 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.33.1 // indirect github.com/libp2p/go-libp2p-kbucket v0.7.0 // indirect github.com/libp2p/go-libp2p-record v0.3.1 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.7.5 // indirect @@ -188,7 +188,7 @@ require ( github.com/mattn/go-shellwords v1.0.12 // indirect github.com/mgechev/revive v1.3.9 // indirect github.com/mholt/acmez/v3 v3.0.0 // indirect - github.com/miekg/dns v1.1.65 // indirect + github.com/miekg/dns v1.1.66 // 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 @@ -310,23 +310,23 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go.uber.org/zap/exp v0.3.0 // indirect - golang.org/x/crypto v0.37.0 // indirect - golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect + golang.org/x/crypto v0.38.0 // indirect + golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f // indirect golang.org/x/mod v0.24.0 // indirect - golang.org/x/net v0.39.0 // indirect - golang.org/x/sync v0.13.0 // indirect + golang.org/x/net v0.40.0 // indirect + golang.org/x/sync v0.14.0 // indirect golang.org/x/sys v0.33.0 // indirect - golang.org/x/term v0.31.0 // indirect - golang.org/x/text v0.24.0 // indirect - golang.org/x/tools v0.32.0 // indirect + golang.org/x/term v0.32.0 // indirect + golang.org/x/text v0.25.0 // indirect + golang.org/x/tools v0.33.0 // indirect gonum.org/v1/gonum v0.16.0 // indirect google.golang.org/protobuf v1.36.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.5.1 // indirect - lukechampine.com/blake3 v1.4.0 // indirect + lukechampine.com/blake3 v1.4.1 // 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 8c9bbdd340a..c1d2937e0aa 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -440,8 +440,8 @@ github.com/libp2p/go-libp2p v0.41.1 h1:8ecNQVT5ev/jqALTvisSJeVNvXYJyK4NhQx1nNRXQ github.com/libp2p/go-libp2p v0.41.1/go.mod h1:DcGTovJzQl/I7HMrby5ZRjeD0kQkGiy+9w6aEkSZpRI= 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.32.0 h1:dpyq7o00od98vPQG0IZvNHpeLnKyuICN1nVzGnVMC9k= -github.com/libp2p/go-libp2p-kad-dht v0.32.0/go.mod h1:vQU5oE9hMHXJhSQawbZapC9u0U9dc+tWC0DYasGmIAA= +github.com/libp2p/go-libp2p-kad-dht v0.33.1 h1:hKFhHMf7WH69LDjaxsJUWOU6qZm71uO47M/a5ijkiP0= +github.com/libp2p/go-libp2p-kad-dht v0.33.1/go.mod h1:CdmNk4VeGJa9EXM9SLNyNVySEvduKvb+5rSC/H4pLAo= github.com/libp2p/go-libp2p-kbucket v0.7.0 h1:vYDvRjkyJPeWunQXqcW2Z6E93Ywx7fX0jgzb/dGOKCs= github.com/libp2p/go-libp2p-kbucket v0.7.0/go.mod h1:blOINGIj1yiPYlVEX0Rj9QwEkmVnz3EP8LK1dRKBC6g= github.com/libp2p/go-libp2p-record v0.3.1 h1:cly48Xi5GjNw5Wq+7gmjfBiG9HCzQVkiZOUZ8kUl+Fg= @@ -494,8 +494,8 @@ github.com/mgechev/revive v1.3.9/go.mod h1:+uxEIr5UH0TjXWHTno3xh4u7eg6jDpXKzQccA github.com/mholt/acmez/v3 v3.0.0 h1:r1NcjuWR0VaKP2BTjDK9LRFBw/WvURx3jlaEUl9Ht8E= github.com/mholt/acmez/v3 v3.0.0/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/miekg/dns v1.1.65 h1:0+tIPHzUW0GCge7IiK3guGP57VAw7hoPDfApjkMD1Fc= -github.com/miekg/dns v1.1.65/go.mod h1:Dzw9769uoKVaLuODMDZz9M6ynFU6Em65csPuoi8G0ck= +github.com/miekg/dns v1.1.66 h1:FeZXOS3VCVsKnEAd+wBkjMC3D2K+ww66Cq3VnCINuJE= +github.com/miekg/dns v1.1.66/go.mod h1:jGFzBsSNbJw6z1HYut1RKBKHA9PBdxeHrZG8J+gC2WE= 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= @@ -881,11 +881,11 @@ golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf 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.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= -golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= +golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= +golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM= -golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8= +golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI= +golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ= 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-20240314144324-c7f7c6466f7f h1:phY1HzDcf18Aq9A8KkmRtY9WvOFIxN8wgfvy6Zm1DV8= @@ -943,8 +943,8 @@ 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.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= -golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= +golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= +golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= 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= @@ -964,8 +964,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.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= -golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= +golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 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= @@ -1021,8 +1021,8 @@ 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.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o= -golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= +golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= +golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= 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= @@ -1037,8 +1037,8 @@ 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.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= -golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= 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= @@ -1076,8 +1076,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.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU= -golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s= +golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= +golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= 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= @@ -1125,8 +1125,8 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/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= -lukechampine.com/blake3 v1.4.0 h1:xDbKOZCVbnZsfzM6mHSYcGRHZ3YrLDzqz8XnV4uaD5w= -lukechampine.com/blake3 v1.4.0/go.mod h1:MQJNQCTnR+kwOP/JEZSxj3MaQjp80FOFSNMMHXcSeX0= +lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg= +lukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo= 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= From 49e2690001a5b9320267015936cf15a708fd1c13 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 21 May 2025 17:57:27 +0200 Subject: [PATCH 42/42] chore(version): 0.35.0 --- docs/changelogs/v0.35.md | 140 +++++++++++++++++++++++++++++++++++++++ version.go | 2 +- 2 files changed, 141 insertions(+), 1 deletion(-) diff --git a/docs/changelogs/v0.35.md b/docs/changelogs/v0.35.md index 9186b26085c..d94063e0cf4 100644 --- a/docs/changelogs/v0.35.md +++ b/docs/changelogs/v0.35.md @@ -270,4 +270,144 @@ If the lock cannot be acquired because someone else has the lock, and `IPFS_WAIT - update `p2p-forge/client` to [v0.5.1](https://github.com/ipshipyard/p2p-forge/releases/tag/v0.5.1) ### πŸ“ Changelog + +
Full Changelog + +- github.com/ipfs/kubo: + - chore(version): 0.35.0 + - fix: go-libp2p-kad-dht v0.33.1 (#10814) ([ipfs/kubo#10814](https://github.com/ipfs/kubo/pull/10814)) + - fix: p2p-forge v0.5.1 ignoring /p2p-circuit (#10813) ([ipfs/kubo#10813](https://github.com/ipfs/kubo/pull/10813)) + - chore(version): 0.35.0-rc2 + - fix(fuse): ipns error handling and friendly errors (#10807) ([ipfs/kubo#10807](https://github.com/ipfs/kubo/pull/10807)) + - fix(config): wire up `Provider.Enabled` flag (#10804) ([ipfs/kubo#10804](https://github.com/ipfs/kubo/pull/10804)) + - docs(changelog): go-libp2p-kad-dht + - chore(version): 0.35.0-rc1 + - feat: IPFS_WAIT_REPO_LOCK (#10797) ([ipfs/kubo#10797](https://github.com/ipfs/kubo/pull/10797)) + - logging: upgrade to go-log/v2 v2.6.0 (#10798) ([ipfs/kubo#10798](https://github.com/ipfs/kubo/pull/10798)) + - chore: ensure /mfs is present in docker + - feat(fuse): Expose MFS as FUSE mount point (#10781) ([ipfs/kubo#10781](https://github.com/ipfs/kubo/pull/10781)) + - feat: opt-in http retrieval client (#10772) ([ipfs/kubo#10772](https://github.com/ipfs/kubo/pull/10772)) + - Update go-libp2p-pubsub to v0.13.1 (#10795) ([ipfs/kubo#10795](https://github.com/ipfs/kubo/pull/10795)) + - feat(config): ability to disable Bitswap fully or just server (#10782) ([ipfs/kubo#10782](https://github.com/ipfs/kubo/pull/10782)) + - refactor: make datastore metrics opt-in (#10788) ([ipfs/kubo#10788](https://github.com/ipfs/kubo/pull/10788)) + - feat(pebble): support pinning `FormatMajorVersion` (#10789) ([ipfs/kubo#10789](https://github.com/ipfs/kubo/pull/10789)) + - feat: `Provider.WorkerCount` and `stats reprovide` (#10779) ([ipfs/kubo#10779](https://github.com/ipfs/kubo/pull/10779)) + - Upgrade to Boxo v0.30.0 (#10794) ([ipfs/kubo#10794](https://github.com/ipfs/kubo/pull/10794)) + - docs: use latest fuse package (#10791) ([ipfs/kubo#10791](https://github.com/ipfs/kubo/pull/10791)) + - remove duplicate workds (#10790) ([ipfs/kubo#10790](https://github.com/ipfs/kubo/pull/10790)) + - feat(config): `ipfs add` and `Import` options for controling UnixFS DAG Width (#10774) ([ipfs/kubo#10774](https://github.com/ipfs/kubo/pull/10774)) + - feat(config): expose ProviderSearchMaxResults (#10773) ([ipfs/kubo#10773](https://github.com/ipfs/kubo/pull/10773)) + - feat: ipfs-webui v4.7.0 (#10780) ([ipfs/kubo#10780](https://github.com/ipfs/kubo/pull/10780)) + - feat: partial DAG provides with Reprovider.Strategy=mfs|pinned+mfs (#10754) ([ipfs/kubo#10754](https://github.com/ipfs/kubo/pull/10754)) + - chore: update url + - docs: known issues with file/urlstores (#10768) ([ipfs/kubo#10768](https://github.com/ipfs/kubo/pull/10768)) + - fix: Add IPFS & IPNS path details to error (re. #10762) (#10770) ([ipfs/kubo#10770](https://github.com/ipfs/kubo/pull/10770)) + - docs: Fix typo in v0.34 changelog (#10771) ([ipfs/kubo#10771](https://github.com/ipfs/kubo/pull/10771)) + - Support WithIgnoreProviders() in provider query manager ([ipfs/kubo#10765](https://github.com/ipfs/kubo/pull/10765)) + - Merge release v0.34.1 ([ipfs/kubo#10766](https://github.com/ipfs/kubo/pull/10766)) + - fix: reprovides warning (#10761) ([ipfs/kubo#10761](https://github.com/ipfs/kubo/pull/10761)) + - Merge release v0.34.0 ([ipfs/kubo#10759](https://github.com/ipfs/kubo/pull/10759)) + - feat: ipfs-webui v4.6 (#10756) ([ipfs/kubo#10756](https://github.com/ipfs/kubo/pull/10756)) + - docs(readme): update min. requirements + cleanup (#10750) ([ipfs/kubo#10750](https://github.com/ipfs/kubo/pull/10750)) + - Upgrade to Boxo v0.29.1 (#10755) ([ipfs/kubo#10755](https://github.com/ipfs/kubo/pull/10755)) + - Nonfunctional (#10753) ([ipfs/kubo#10753](https://github.com/ipfs/kubo/pull/10753)) + - provider: buffer pin providers ([ipfs/kubo#10746](https://github.com/ipfs/kubo/pull/10746)) + - chore: 0.35.0-dev +- github.com/ipfs/boxo (v0.29.1 -> v0.30.0): + - Release v0.30.0 ([ipfs/boxo#915](https://github.com/ipfs/boxo/pull/915)) + - feat(bitswap): add option to disable Bitswap server (#911) ([ipfs/boxo#911](https://github.com/ipfs/boxo/pull/911)) + - provider: dedicated provide queue (#907) ([ipfs/boxo#907](https://github.com/ipfs/boxo/pull/907)) + - provider: deduplicate cids in queue (#910) ([ipfs/boxo#910](https://github.com/ipfs/boxo/pull/910)) + - feat(unixfs/mfs): support MaxLinks and MaxHAMTFanout (#906) ([ipfs/boxo#906](https://github.com/ipfs/boxo/pull/906)) + - feat(ipld/unixfs): DagModifier: allow specifying MaxLinks per file (#898) ([ipfs/boxo#898](https://github.com/ipfs/boxo/pull/898)) + - feat: NewDAGProvider to walk partial DAGs in offline mode (#905) ([ipfs/boxo#905](https://github.com/ipfs/boxo/pull/905)) + - gateway: check for UseSubdomains with IP addresses (#903) ([ipfs/boxo#903](https://github.com/ipfs/boxo/pull/903)) + - feat(gateway): add cid copy button to directory listings (#899) ([ipfs/boxo#899](https://github.com/ipfs/boxo/pull/899)) + - Improve performance of data onboarding (#888) ([ipfs/boxo#888](https://github.com/ipfs/boxo/pull/888)) + - bitswap: add requestsInFlight metric ([ipfs/boxo#904](https://github.com/ipfs/boxo/pull/904)) + - provider: simplify reprovide (#890) ([ipfs/boxo#890](https://github.com/ipfs/boxo/pull/890)) + - Upgrade to go-libp2p v0.41.1 ([ipfs/boxo#896](https://github.com/ipfs/boxo/pull/896)) + - Update RELEASE.md ([ipfs/boxo#892](https://github.com/ipfs/boxo/pull/892)) + - changelog: document bsnet import path change ([ipfs/boxo#891](https://github.com/ipfs/boxo/pull/891)) + - fix(gateway): preserve query parameters on _redirects ([ipfs/boxo#886](https://github.com/ipfs/boxo/pull/886)) + - bitswap/httpnet: Add WithDenylist option ([ipfs/boxo#877](https://github.com/ipfs/boxo/pull/877)) +- github.com/ipfs/go-block-format (v0.2.0 -> v0.2.1): + - Update version (#60) ([ipfs/go-block-format#60](https://github.com/ipfs/go-block-format/pull/60)) + - Update go-ipfs-util to use boxo (#52) ([ipfs/go-block-format#52](https://github.com/ipfs/go-block-format/pull/52)) +- github.com/ipfs/go-ds-pebble (v0.4.4 -> v0.5.0): + - new version (#53) ([ipfs/go-ds-pebble#53](https://github.com/ipfs/go-ds-pebble/pull/53)) + - Upgrade to pebble v2.0.3 (#45) ([ipfs/go-ds-pebble#45](https://github.com/ipfs/go-ds-pebble/pull/45)) +- github.com/ipfs/go-fs-lock (v0.0.7 -> v0.1.1): + - new version (#48) ([ipfs/go-fs-lock#48](https://github.com/ipfs/go-fs-lock/pull/48)) + - Return original error when WaitLock times out (#47) ([ipfs/go-fs-lock#47](https://github.com/ipfs/go-fs-lock/pull/47)) + - new version (#45) ([ipfs/go-fs-lock#45](https://github.com/ipfs/go-fs-lock/pull/45)) + - Add WaitLock function (#44) ([ipfs/go-fs-lock#44](https://github.com/ipfs/go-fs-lock/pull/44)) + - sync: update CI config files ([ipfs/go-fs-lock#30](https://github.com/ipfs/go-fs-lock/pull/30)) + - sync: update CI config files (#27) ([ipfs/go-fs-lock#27](https://github.com/ipfs/go-fs-lock/pull/27)) + - sync: update CI config files ([ipfs/go-fs-lock#25](https://github.com/ipfs/go-fs-lock/pull/25)) +- github.com/ipfs/go-log/v2 (v2.5.1 -> v2.6.0): + - new version (#155) ([ipfs/go-log#155](https://github.com/ipfs/go-log/pull/155)) + - feat: only log to stderr or to stdout or both if configured (#154) ([ipfs/go-log#154](https://github.com/ipfs/go-log/pull/154)) + - ci: uci/copy-templates ([ipfs/go-log#145](https://github.com/ipfs/go-log/pull/145)) + - sync: update CI config files (#137) ([ipfs/go-log#137](https://github.com/ipfs/go-log/pull/137)) +- github.com/libp2p/go-libp2p-kad-dht (v0.30.2 -> v0.33.1): + - chore: release v0.33.1 (#1088) ([libp2p/go-libp2p-kad-dht#1088](https://github.com/libp2p/go-libp2p-kad-dht/pull/1088)) + - fix(fullrt): mutex cleanup (#1087) ([libp2p/go-libp2p-kad-dht#1087](https://github.com/libp2p/go-libp2p-kad-dht/pull/1087)) + - fix: use correct mutex for reading keyToPeerMap (#1086) ([libp2p/go-libp2p-kad-dht#1086](https://github.com/libp2p/go-libp2p-kad-dht/pull/1086)) + - fix: fullrt kMapLk unlock (#1085) ([libp2p/go-libp2p-kad-dht#1085](https://github.com/libp2p/go-libp2p-kad-dht/pull/1085)) + - chore: release v0.33.0 (#1083) ([libp2p/go-libp2p-kad-dht#1083](https://github.com/libp2p/go-libp2p-kad-dht/pull/1083)) + - fix/updates to use context passed in New function for context cancellation (#1081) ([libp2p/go-libp2p-kad-dht#1081](https://github.com/libp2p/go-libp2p-kad-dht/pull/1081)) + - chore: release v0.31.1 (#1079) ([libp2p/go-libp2p-kad-dht#1079](https://github.com/libp2p/go-libp2p-kad-dht/pull/1079)) + - fix: netsize warning (#1077) ([libp2p/go-libp2p-kad-dht#1077](https://github.com/libp2p/go-libp2p-kad-dht/pull/1077)) + - fix: use correct message type attribute in metrics (#1076) ([libp2p/go-libp2p-kad-dht#1076](https://github.com/libp2p/go-libp2p-kad-dht/pull/1076)) + - chore: bump go-log to v2 (#1074) ([libp2p/go-libp2p-kad-dht#1074](https://github.com/libp2p/go-libp2p-kad-dht/pull/1074)) + - release v0.31.0 (#1072) ([libp2p/go-libp2p-kad-dht#1072](https://github.com/libp2p/go-libp2p-kad-dht/pull/1072)) + - query: ip diversity filter (#1070) ([libp2p/go-libp2p-kad-dht#1070](https://github.com/libp2p/go-libp2p-kad-dht/pull/1070)) + - tests: fix flaky TestProvidesExpire (#1069) ([libp2p/go-libp2p-kad-dht#1069](https://github.com/libp2p/go-libp2p-kad-dht/pull/1069)) + - refactor: replace fmt.Errorf with errors.New when not formatting is required (#1067) ([libp2p/go-libp2p-kad-dht#1067](https://github.com/libp2p/go-libp2p-kad-dht/pull/1067)) + - fix: error on no valid provs (#1065) ([libp2p/go-libp2p-kad-dht#1065](https://github.com/libp2p/go-libp2p-kad-dht/pull/1065)) + - cleanup: remove deprecated opt package (#1064) ([libp2p/go-libp2p-kad-dht#1064](https://github.com/libp2p/go-libp2p-kad-dht/pull/1064)) + - cleanup: fullrt ([libp2p/go-libp2p-kad-dht#1062](https://github.com/libp2p/go-libp2p-kad-dht/pull/1062)) + - fix: remove peerstore no-op (#1063) ([libp2p/go-libp2p-kad-dht#1063](https://github.com/libp2p/go-libp2p-kad-dht/pull/1063)) + - tests: flaky TestSearchValue (dual) (#1060) ([libp2p/go-libp2p-kad-dht#1060](https://github.com/libp2p/go-libp2p-kad-dht/pull/1060)) +- github.com/libp2p/go-libp2p-kbucket (v0.6.5 -> v0.7.0): + - chore: release v0.7.0 (#143) ([libp2p/go-libp2p-kbucket#143](https://github.com/libp2p/go-libp2p-kbucket/pull/143)) + - peerdiversity: export IPGroupKey (#141) ([libp2p/go-libp2p-kbucket#141](https://github.com/libp2p/go-libp2p-kbucket/pull/141)) + - fix: flaky TestUsefulNewPeer (#140) ([libp2p/go-libp2p-kbucket#140](https://github.com/libp2p/go-libp2p-kbucket/pull/140)) + - fix: flaky TestTableFindMultipleBuckets (#139) ([libp2p/go-libp2p-kbucket#139](https://github.com/libp2p/go-libp2p-kbucket/pull/139)) +- github.com/libp2p/go-libp2p-pubsub (v0.13.0 -> v0.13.1): + - feat: WithValidatorData publishing option (#603) ([libp2p/go-libp2p-pubsub#603](https://github.com/libp2p/go-libp2p-pubsub/pull/603)) + - feat: avoid repeated checksum calculations (#599) ([libp2p/go-libp2p-pubsub#599](https://github.com/libp2p/go-libp2p-pubsub/pull/599)) +- github.com/libp2p/go-yamux/v4 (v4.0.1 -> v4.0.2): + - Release v4.0.2 (#124) ([libp2p/go-yamux#124](https://github.com/libp2p/go-yamux/pull/124)) + - fix: remove noisy logs (#116) ([libp2p/go-yamux#116](https://github.com/libp2p/go-yamux/pull/116)) + - check deadline before sending a message (#114) ([libp2p/go-yamux#114](https://github.com/libp2p/go-yamux/pull/114)) + - only check KeepAliveInterval if keep-alives are enabled (#113) ([libp2p/go-yamux#113](https://github.com/libp2p/go-yamux/pull/113)) + - ci: uci/copy-templates ([libp2p/go-yamux#109](https://github.com/libp2p/go-yamux/pull/109)) + +
+ ### πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors + +| Contributor | Commits | Lines Β± | Files Changed | +|-------------|---------|---------|---------------| +| Hector Sanjuan | 16 | +2662/-590 | 71 | +| Guillaume Michel | 27 | +1339/-714 | 69 | +| Andrew Gillis | 22 | +1056/-377 | 54 | +| Sergey Gorbunov | 1 | +962/-42 | 26 | +| Marcin Rataj | 19 | +714/-133 | 47 | +| IGP | 2 | +419/-35 | 11 | +| GITSRC | 1 | +90/-1 | 3 | +| guillaumemichel | 1 | +21/-43 | 1 | +| blockchainluffy | 1 | +27/-26 | 8 | +| web3-bot | 9 | +21/-22 | 13 | +| VersaliX | 1 | +31/-2 | 4 | +| gammazero | 5 | +18/-5 | 5 | +| Hlib Kanunnikov | 1 | +14/-4 | 1 | +| diogo464 | 1 | +6/-7 | 1 | +| Asutorufa | 2 | +7/-1 | 2 | +| Russell Dempsey | 1 | +6/-1 | 1 | +| Steven Allen | 1 | +1/-5 | 1 | +| Michael Vorburger | 2 | +3/-3 | 2 | +| Aayush Rajasekaran | 1 | +2/-2 | 1 | +| sukun | 1 | +1/-1 | 1 | diff --git a/version.go b/version.go index 1b9b7e05617..26cb836b976 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.35.0-rc2" +const CurrentVersionNumber = "0.35.0" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint