From 4b29eb020c6860da7b60b501003a68334aa6961f Mon Sep 17 00:00:00 2001 From: Jorropo Date: Mon, 24 Jul 2023 10:29:07 +0200 Subject: [PATCH 001/312] docs: fix changelog entries (#414) --- CHANGELOG.md | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2926a0a56..231c110b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,24 +35,6 @@ The following emojis are used to highlight certain changes: ### Security -## [0.10.1] - 2023-06-19 - -### Added - -None. - -### Changed - -None. - -### Removed - -None. - -### Fixed - -### Security - ## [0.10.2] - 2023-06-29 ### Fixed @@ -134,8 +116,9 @@ None. - `RecursiveKeys` - `InternalKeys` - 🛠 `provider/batched.New` has been moved to `provider.New` and arguments has been changed. (https://github.com/ipfs/boxo/pulls/273) - - a routing system is now passed with the `provider.Online` option, by default the system run in offline mode (push stuff onto the queue); and - - you do not have to pass a queue anymore, you pass a `datastore.Datastore` exclusively. + - A routing system is now passed with the `provider.Online` option, by default the system run in offline mode (push stuff onto the queue). + - When using `provider.Online` calling the `.Run` method is not required anymore, the background worker is implicitely started in the background by `provider.New`. + - You do not have to pass a queue anymore, you pass a `datastore.Datastore` exclusively. - 🛠 `provider.NewOfflineProvider` has been renamed to `provider.NewNoopProvider` to show more clearly that is does nothing. (https://github.com/ipfs/boxo/pulls/273) - 🛠 `provider.Provider` and `provider.Reprovider` has been merged under one `provider.System`. (https://github.com/ipfs/boxo/pulls/273) - 🛠 `routing/http` responses now return a streaming `iter.ResultIter` generic interface. (https://github.com/ipfs/boxo/pulls/18) From f6b448b4263acc7e7a39942fa24e5ada1b09a408 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 24 Jul 2023 10:47:31 +0200 Subject: [PATCH 002/312] feat(gateway): support for order=, dups= parameters from IPIP-412 (#370) Co-authored-by: Marcin Rataj --- CHANGELOG.md | 27 +++++++-- gateway/blocks_backend.go | 9 ++- gateway/gateway.go | 50 ++++++++++++++++- gateway/handler.go | 47 ++++++++-------- gateway/handler_car.go | 106 ++++++++++++++++++++++++++++++------ gateway/handler_car_test.go | 66 +++++++++++++++++++++- 6 files changed, 255 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 231c110b7..d2d4b2536 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,13 +16,30 @@ The following emojis are used to highlight certain changes: ### Added +* ✨ The gateway now supports the optional `order` and `dups` CAR parameters + from [IPIP-412](https://github.com/ipfs/specs/pull/412). + * The `BlocksBackend` only implements `order=dfs` (Depth-First Search) + ordering, which was already the default behavior. + * If a request specifies no `dups`, response with `dups=n` is returned, which + was already the default behavior. + * If a request explicitly specifies a CAR `order` other than `dfs`, it will + result in an error. + * The only change to the default behavior on CAR responses is that we follow + IPIP-412 and make `order=dfs;dups=n` explicit in the returned + `Content-Type` HTTP header. + ### Changed -* 🛠 The `ipns` package has been refactored. You should no longer use the direct Protobuf - version of the IPNS Record. Instead, we have a shiny new `ipns.Record` type that wraps - all the required functionality to work the best as possible with IPNS v2 Records. Please - check the [documentation](https://pkg.go.dev/github.com/ipfs/boxo/ipns) for more information, - and follow [ipfs/specs#376](https://github.com/ipfs/specs/issues/376) for related IPIP. +* 🛠 The `ipns` package has been refactored. + * You should no longer use the direct Protobuf version of the IPNS Record. + Instead, we have a shiny new `ipns.Record` type that wraps all the required + functionality to work the best as possible with IPNS v2 Records. Please + check the [documentation](https://pkg.go.dev/github.com/ipfs/boxo/ipns) for + more information, and follow + [ipfs/specs#376](https://github.com/ipfs/specs/issues/376) for related + IPIP. + * There is no change to IPNS Records produced by `boxo/ipns`, it still + produces both V1 and V2 signatures by default, it is still backward-compatible. ### Removed diff --git a/gateway/blocks_backend.go b/gateway/blocks_backend.go index 6d76bb013..01ca49fec 100644 --- a/gateway/blocks_backend.go +++ b/gateway/blocks_backend.go @@ -245,7 +245,12 @@ func (bb *BlocksBackend) GetCAR(ctx context.Context, p ImmutablePath, params Car r, w := io.Pipe() go func() { - cw, err := storage.NewWritable(w, []cid.Cid{pathMetadata.LastSegment.Cid()}, car.WriteAsCarV1(true)) + cw, err := storage.NewWritable( + w, + []cid.Cid{pathMetadata.LastSegment.Cid()}, + car.WriteAsCarV1(true), + car.AllowDuplicatePuts(params.Duplicates.Bool()), + ) if err != nil { // io.PipeWriter.CloseWithError always returns nil. _ = w.CloseWithError(err) @@ -312,7 +317,7 @@ func walkGatewaySimpleSelector(ctx context.Context, p ipfspath.Path, params CarP Ctx: ctx, LinkSystem: *lsys, LinkTargetNodePrototypeChooser: bsfetcher.DefaultPrototypeChooser, - LinkVisitOnlyOnce: true, // This is safe for the "all" selector + LinkVisitOnlyOnce: !params.Duplicates.Bool(), }, } diff --git a/gateway/gateway.go b/gateway/gateway.go index cf2ca9104..780691a45 100644 --- a/gateway/gateway.go +++ b/gateway/gateway.go @@ -121,8 +121,10 @@ func (i ImmutablePath) IsValid() error { var _ path.Path = (*ImmutablePath)(nil) type CarParams struct { - Range *DagByteRange - Scope DagScope + Range *DagByteRange + Scope DagScope + Order DagOrder + Duplicates DuplicateBlocksPolicy } // DagByteRange describes a range request within a UnixFS file. "From" and @@ -189,6 +191,50 @@ const ( DagScopeBlock DagScope = "block" ) +type DagOrder string + +const ( + DagOrderUnspecified DagOrder = "" + DagOrderUnknown DagOrder = "unk" + DagOrderDFS DagOrder = "dfs" +) + +// DuplicateBlocksPolicy represents the content type parameter 'dups' (IPIP-412) +type DuplicateBlocksPolicy int + +const ( + DuplicateBlocksUnspecified DuplicateBlocksPolicy = iota // 0 - implicit default + DuplicateBlocksIncluded // 1 - explicitly include duplicates + DuplicateBlocksExcluded // 2 - explicitly NOT include duplicates +) + +// NewDuplicateBlocksPolicy returns DuplicateBlocksPolicy based on the content type parameter 'dups' (IPIP-412) +func NewDuplicateBlocksPolicy(dupsValue string) DuplicateBlocksPolicy { + switch dupsValue { + case "y": + return DuplicateBlocksIncluded + case "n": + return DuplicateBlocksExcluded + } + return DuplicateBlocksUnspecified +} + +func (d DuplicateBlocksPolicy) Bool() bool { + // duplicates should be returned only when explicitly requested, + // so any other state than DuplicateBlocksIncluded should return false + return d == DuplicateBlocksIncluded +} + +func (d DuplicateBlocksPolicy) String() string { + switch d { + case DuplicateBlocksIncluded: + return "y" + case DuplicateBlocksExcluded: + return "n" + } + return "" +} + type ContentPathMetadata struct { PathSegmentRoots []cid.Cid LastSegment path.Resolved diff --git a/gateway/handler.go b/gateway/handler.go index 102593449..8c1358553 100644 --- a/gateway/handler.go +++ b/gateway/handler.go @@ -637,28 +637,9 @@ const ( // return explicit response format if specified in request as query parameter or via Accept HTTP header func customResponseFormat(r *http.Request) (mediaType string, params map[string]string, err error) { - // Translate query param to a content type, if present. - if formatParam := r.URL.Query().Get("format"); formatParam != "" { - switch formatParam { - case "raw": - return rawResponseFormat, nil, nil - case "car": - return carResponseFormat, nil, nil - case "tar": - return tarResponseFormat, nil, nil - case "json": - return jsonResponseFormat, nil, nil - case "cbor": - return cborResponseFormat, nil, nil - case "dag-json": - return dagJsonResponseFormat, nil, nil - case "dag-cbor": - return dagCborResponseFormat, nil, nil - case "ipns-record": - return ipnsRecordResponseFormat, nil, nil - } - } - + // First, inspect Accept header, as it may not only include content type, but also optional parameters. + // such as CAR version or additional ones from IPIP-412. + // // Browsers and other user agents will send Accept header with generic types like: // Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 // We only care about explicit, vendor-specific content-types and respond to the first match (in order). @@ -681,6 +662,28 @@ func customResponseFormat(r *http.Request) (mediaType string, params map[string] } } + // If no Accept header, translate query param to a content type, if present. + if formatParam := r.URL.Query().Get("format"); formatParam != "" { + switch formatParam { + case "raw": + return rawResponseFormat, nil, nil + case "car": + return carResponseFormat, nil, nil + case "tar": + return tarResponseFormat, nil, nil + case "json": + return jsonResponseFormat, nil, nil + case "cbor": + return cborResponseFormat, nil, nil + case "dag-json": + return dagJsonResponseFormat, nil, nil + case "dag-cbor": + return dagCborResponseFormat, nil, nil + case "ipns-record": + return ipnsRecordResponseFormat, nil, nil + } + } + // If none of special-cased content types is found, return empty string // to indicate default, implicit UnixFS response should be prepared return "", nil, nil diff --git a/gateway/handler_car.go b/gateway/handler_car.go index e773c920e..553519988 100644 --- a/gateway/handler_car.go +++ b/gateway/handler_car.go @@ -30,16 +30,7 @@ func (i *handler) serveCAR(ctx context.Context, w http.ResponseWriter, r *http.R ctx, cancel := context.WithCancel(ctx) defer cancel() - switch rq.responseParams["version"] { - case "": // noop, client does not care about version - case "1": // noop, we support this - default: - err := fmt.Errorf("unsupported CAR version: only version=1 is supported") - i.webError(w, r, err, http.StatusBadRequest) - return false - } - - params, err := getCarParams(r) + params, err := buildCarParams(r, rq.responseParams) if err != nil { i.webError(w, r, err, http.StatusBadRequest) return false @@ -90,7 +81,7 @@ func (i *handler) serveCAR(ctx context.Context, w http.ResponseWriter, r *http.R // sub-DAGs and IPLD selectors: https://github.com/ipfs/go-ipfs/issues/8769 w.Header().Set("Accept-Ranges", "none") - w.Header().Set("Content-Type", carResponseFormat+"; version=1") + w.Header().Set("Content-Type", buildContentTypeFromCarParams(params)) w.Header().Set("X-Content-Type-Options", "nosniff") // no funny business in the browsers :^) _, copyErr := io.Copy(w, carFile) @@ -113,7 +104,15 @@ func (i *handler) serveCAR(ctx context.Context, w http.ResponseWriter, r *http.R return true } -func getCarParams(r *http.Request) (CarParams, error) { +// buildCarParams returns CarParams based on the request, any optional parameters +// passed in URL, Accept header and the implicit defaults specific to boxo +// implementation, such as block order and duplicates status. +// +// If any of the optional content type parameters (e.g., CAR order or +// duplicates) are unspecified or empty, the function will automatically infer +// default values. +func buildCarParams(r *http.Request, contentTypeParams map[string]string) (CarParams, error) { + // URL query parameters queryParams := r.URL.Query() rangeStr, hasRange := queryParams.Get(carRangeBytesKey), queryParams.Has(carRangeBytesKey) scopeStr, hasScope := queryParams.Get(carTerminalElementTypeKey), queryParams.Has(carTerminalElementTypeKey) @@ -122,7 +121,7 @@ func getCarParams(r *http.Request) (CarParams, error) { if hasRange { rng, err := NewDagByteRange(rangeStr) if err != nil { - err = fmt.Errorf("invalid entity-bytes: %w", err) + err = fmt.Errorf("invalid application/vnd.ipld.car entity-bytes URL parameter: %w", err) return CarParams{}, err } params.Range = &rng @@ -133,16 +132,78 @@ func getCarParams(r *http.Request) (CarParams, error) { case DagScopeEntity, DagScopeAll, DagScopeBlock: params.Scope = s default: - err := fmt.Errorf("unsupported dag-scope %s", scopeStr) + err := fmt.Errorf("unsupported application/vnd.ipld.car dag-scope URL parameter: %q", scopeStr) return CarParams{}, err } } else { params.Scope = DagScopeAll } + // application/vnd.ipld.car content type parameters from Accept header + + // version of CAR format + switch contentTypeParams["version"] { + case "": // noop, client does not care about version + case "1": // noop, we support this + default: + return CarParams{}, fmt.Errorf("unsupported application/vnd.ipld.car version: only version=1 is supported") + } + + // optional order from IPIP-412 + if order := DagOrder(contentTypeParams["order"]); order != DagOrderUnspecified { + switch order { + case DagOrderUnknown, DagOrderDFS: + params.Order = order + default: + return CarParams{}, fmt.Errorf("unsupported application/vnd.ipld.car content type order parameter: %q", order) + } + } else { + // when order is not specified, we use DFS as the implicit default + // as this has always been the default behavior and we should not break + // legacy clients + params.Order = DagOrderDFS + } + + // optional dups from IPIP-412 + if dups := NewDuplicateBlocksPolicy(contentTypeParams["dups"]); dups != DuplicateBlocksUnspecified { + switch dups { + case DuplicateBlocksExcluded, DuplicateBlocksIncluded: + params.Duplicates = dups + default: + return CarParams{}, fmt.Errorf("unsupported application/vnd.ipld.car content type dups parameter: %q", dups) + } + } else { + // when duplicate block preference is not specified, we set it to + // false, as this has always been the default behavior, we should + // not break legacy clients, and responses to requests made via ?format=car + // should benefit from block deduplication + params.Duplicates = DuplicateBlocksExcluded + + } + return params, nil } +// buildContentTypeFromCarParams returns a string for Content-Type header. +// It does not change any values, CarParams are respected as-is. +func buildContentTypeFromCarParams(params CarParams) string { + h := strings.Builder{} + h.WriteString(carResponseFormat) + h.WriteString("; version=1") + + if params.Order != DagOrderUnspecified { + h.WriteString("; order=") + h.WriteString(string(params.Order)) + } + + if params.Duplicates != DuplicateBlocksUnspecified { + h.WriteString("; dups=") + h.WriteString(params.Duplicates.String()) + } + + return h.String() +} + func getCarRootCidAndLastSegment(imPath ImmutablePath) (cid.Cid, string, error) { imPathStr := imPath.String() if !strings.HasPrefix(imPathStr, "/ipfs/") { @@ -167,14 +228,25 @@ func getCarRootCidAndLastSegment(imPath ImmutablePath) (cid.Cid, string, error) func getCarEtag(imPath ImmutablePath, params CarParams, rootCid cid.Cid) string { data := imPath.String() if params.Scope != DagScopeAll { - data += "." + string(params.Scope) + data += string(params.Scope) + } + + // 'order' from IPIP-412 impact Etag only if set to something else + // than DFS (which is the implicit default) + if params.Order != DagOrderDFS { + data += string(params.Order) + } + + // 'dups' from IPIP-412 impact Etag only if 'y' + if dups := params.Duplicates.String(); dups == "y" { + data += dups } if params.Range != nil { if params.Range.From != 0 || params.Range.To != nil { - data += "." + strconv.FormatInt(params.Range.From, 10) + data += strconv.FormatInt(params.Range.From, 10) if params.Range.To != nil { - data += "." + strconv.FormatInt(*params.Range.To, 10) + data += strconv.FormatInt(*params.Range.To, 10) } } } diff --git a/gateway/handler_car_test.go b/gateway/handler_car_test.go index 858ccb85d..65777453d 100644 --- a/gateway/handler_car_test.go +++ b/gateway/handler_car_test.go @@ -28,7 +28,7 @@ func TestCarParams(t *testing.T) { } for _, test := range tests { r := mustNewRequest(t, http.MethodGet, "http://example.com/?"+test.query, nil) - params, err := getCarParams(r) + params, err := buildCarParams(r, map[string]string{}) if test.expectedError { assert.Error(t, err) } else { @@ -60,7 +60,7 @@ func TestCarParams(t *testing.T) { } for _, test := range tests { r := mustNewRequest(t, http.MethodGet, "http://example.com/?"+test.query, nil) - params, err := getCarParams(r) + params, err := buildCarParams(r, map[string]string{}) if test.hasError { assert.Error(t, err) } else { @@ -73,6 +73,68 @@ func TestCarParams(t *testing.T) { } } }) + + t.Run("buildCarParams from Accept header: order and dups parsing", func(t *testing.T) { + t.Parallel() + + // below ensure the implicit default (DFS and no duplicates) is correctly inferred + // from the value read from Accept header + tests := []struct { + acceptHeader string + expectedOrder DagOrder + expectedDuplicates DuplicateBlocksPolicy + }{ + {"application/vnd.ipld.car; order=dfs; dups=y", DagOrderDFS, DuplicateBlocksIncluded}, + {"application/vnd.ipld.car; order=unk; dups=n", DagOrderUnknown, DuplicateBlocksExcluded}, + {"application/vnd.ipld.car; order=unk", DagOrderUnknown, DuplicateBlocksExcluded}, + {"application/vnd.ipld.car; dups=y", DagOrderDFS, DuplicateBlocksIncluded}, + {"application/vnd.ipld.car; dups=n", DagOrderDFS, DuplicateBlocksExcluded}, + {"application/vnd.ipld.car", DagOrderDFS, DuplicateBlocksExcluded}, + {"application/vnd.ipld.car;version=1;order=dfs;dups=y", DagOrderDFS, DuplicateBlocksIncluded}, + } + for _, test := range tests { + r := mustNewRequest(t, http.MethodGet, "http://example.com/", nil) + r.Header.Set("Accept", test.acceptHeader) + + mediaType, formatParams, err := customResponseFormat(r) + assert.NoError(t, err) + assert.Equal(t, carResponseFormat, mediaType) + + params, err := buildCarParams(r, formatParams) + assert.NoError(t, err) + + // order from IPIP-412 + require.Equal(t, test.expectedOrder, params.Order) + + // dups from IPIP-412 + require.Equal(t, test.expectedDuplicates.String(), params.Duplicates.String()) + } + }) +} + +func TestContentTypeFromCarParams(t *testing.T) { + t.Parallel() + + // below ensures buildContentTypeFromCarParams produces correct Content-Type + // at this point we do not do any inferring, it happens in buildCarParams instead + // and tests of *Unspecified here are just present for completenes and to guard + // against regressions between refactors + tests := []struct { + params CarParams + header string + }{ + {CarParams{}, "application/vnd.ipld.car; version=1"}, + {CarParams{Order: DagOrderUnspecified, Duplicates: DuplicateBlocksUnspecified}, "application/vnd.ipld.car; version=1"}, + {CarParams{Order: DagOrderDFS, Duplicates: DuplicateBlocksIncluded}, "application/vnd.ipld.car; version=1; order=dfs; dups=y"}, + {CarParams{Order: DagOrderUnknown, Duplicates: DuplicateBlocksIncluded}, "application/vnd.ipld.car; version=1; order=unk; dups=y"}, + {CarParams{Order: DagOrderUnknown}, "application/vnd.ipld.car; version=1; order=unk"}, + {CarParams{Duplicates: DuplicateBlocksIncluded}, "application/vnd.ipld.car; version=1; dups=y"}, + {CarParams{Duplicates: DuplicateBlocksExcluded}, "application/vnd.ipld.car; version=1; dups=n"}, + } + for _, test := range tests { + header := buildContentTypeFromCarParams(test.params) + assert.Equal(t, test.header, header) + } } func TestGetCarEtag(t *testing.T) { From 1f5df74ba66a6f42bce56c6b7b9b8bf322c1a4ba Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Tue, 25 Jul 2023 09:54:47 -0400 Subject: [PATCH 003/312] fix: handle _redirects for If-None-Match headers (#412) * fix: handle _redirects for If-None-Match headers * fix: handle _redirects for If-None-Match headers * fix(gateway): HEAD requests now respect _redirects * feat: add _redirects regression test * docs: add changelog entry --------- Co-authored-by: Henrique Dias --- CHANGELOG.md | 1 + gateway/gateway_test.go | 55 +++++++++++++++++++++++++++++ gateway/handler.go | 16 +++++++-- gateway/handler_defaults.go | 19 ++++++++-- gateway/testdata/redirects-spa.car | Bin 0 -> 360 bytes 5 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 gateway/testdata/redirects-spa.car diff --git a/CHANGELOG.md b/CHANGELOG.md index d2d4b2536..8388c06f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ The following emojis are used to highlight certain changes: ### Fixed - Removed mentions of unused ARC algorithm ([#336](https://github.com/ipfs/boxo/issues/366#issuecomment-1597253540)) +- Handle `_redirects` file when `If-None-Match` header is present ([#412](https://github.com/ipfs/boxo/pull/412)) ### Security diff --git a/gateway/gateway_test.go b/gateway/gateway_test.go index cc36da68f..7fae55f3e 100644 --- a/gateway/gateway_test.go +++ b/gateway/gateway_test.go @@ -523,6 +523,61 @@ func TestRedirects(t *testing.T) { res = mustDoWithoutRedirect(t, req) require.Equal(t, http.StatusNotFound, res.StatusCode) }) + + t.Run("_redirects file with If-None-Match header", func(t *testing.T) { + t.Parallel() + + backend, root := newMockBackend(t, "redirects-spa.car") + backend.namesys["/ipns/example.com"] = path.FromCid(root) + + ts := newTestServerWithConfig(t, backend, Config{ + Headers: map[string][]string{}, + NoDNSLink: false, + PublicGateways: map[string]*PublicGateway{ + "example.com": { + UseSubdomains: true, + DeserializedResponses: true, + }, + }, + DeserializedResponses: true, + }) + + missingPageURL := ts.URL + "/missing-page" + + do := func(method string) { + // Make initial request to non-existing page that should return the contents + // of index.html as per the _redirects file. + req := mustNewRequest(t, method, missingPageURL, nil) + req.Header.Add("Accept", "text/html") + req.Host = "example.com" + + res := mustDoWithoutRedirect(t, req) + defer res.Body.Close() + + // Check statuses and body. + require.Equal(t, http.StatusOK, res.StatusCode) + body, err := io.ReadAll(res.Body) + require.NoError(t, err) + require.Equal(t, "hello world\n", string(body)) + + // Check Etag. + etag := res.Header.Get("Etag") + require.NotEmpty(t, etag) + + // Repeat request with Etag as If-None-Match value. Expect 304 Not Modified. + req = mustNewRequest(t, method, missingPageURL, nil) + req.Header.Add("Accept", "text/html") + req.Host = "example.com" + req.Header.Add("If-None-Match", etag) + + res = mustDoWithoutRedirect(t, req) + defer res.Body.Close() + require.Equal(t, http.StatusNotModified, res.StatusCode) + } + + do(http.MethodGet) + do(http.MethodHead) + }) } func TestDeserializedResponses(t *testing.T) { diff --git a/gateway/handler.go b/gateway/handler.go index 8c1358553..ecf505617 100644 --- a/gateway/handler.go +++ b/gateway/handler.go @@ -703,9 +703,19 @@ func (i *handler) handleIfNoneMatch(w http.ResponseWriter, r *http.Request, rq * if ifNoneMatch := r.Header.Get("If-None-Match"); ifNoneMatch != "" { pathMetadata, err := i.backend.ResolvePath(r.Context(), rq.immutablePath) if err != nil { - err = fmt.Errorf("failed to resolve %s: %w", debugStr(rq.contentPath.String()), err) - i.webError(w, r, err, http.StatusInternalServerError) - return true + var forwardedPath ImmutablePath + var continueProcessing bool + if isWebRequest(rq.responseFormat) { + forwardedPath, continueProcessing = i.handleWebRequestErrors(w, r, rq.mostlyResolvedPath(), rq.immutablePath, rq.contentPath, err, rq.logger) + if continueProcessing { + pathMetadata, err = i.backend.ResolvePath(r.Context(), forwardedPath) + } + } + if !continueProcessing || err != nil { + err = fmt.Errorf("failed to resolve %s: %w", debugStr(rq.contentPath.String()), err) + i.webError(w, r, err, http.StatusInternalServerError) + return true + } } pathCid := pathMetadata.LastSegment.Cid() diff --git a/gateway/handler_defaults.go b/gateway/handler_defaults.go index 8e96d8b15..de31c1fc1 100644 --- a/gateway/handler_defaults.go +++ b/gateway/handler_defaults.go @@ -33,8 +33,23 @@ func (i *handler) serveDefaults(ctx context.Context, w http.ResponseWriter, r *h case http.MethodHead: var data files.Node pathMetadata, data, err = i.backend.Head(ctx, rq.mostlyResolvedPath()) - if !i.handleRequestErrors(w, r, rq.contentPath, err) { - return false + if err != nil { + if isWebRequest(rq.responseFormat) { + forwardedPath, continueProcessing := i.handleWebRequestErrors(w, r, rq.mostlyResolvedPath(), rq.immutablePath, rq.contentPath, err, rq.logger) + if !continueProcessing { + return false + } + pathMetadata, data, err = i.backend.Head(ctx, forwardedPath) + if err != nil { + err = fmt.Errorf("failed to resolve %s: %w", debugStr(rq.contentPath.String()), err) + i.webError(w, r, err, http.StatusInternalServerError) + return false + } + } else { + if !i.handleRequestErrors(w, r, rq.contentPath, err) { + return false + } + } } defer data.Close() if _, ok := data.(files.Directory); ok { diff --git a/gateway/testdata/redirects-spa.car b/gateway/testdata/redirects-spa.car new file mode 100644 index 0000000000000000000000000000000000000000..b92b253991c300332a456410a770b9355972bca9 GIT binary patch literal 360 zcmcColv%#k2 zU*Dvcr4|)u=I1d^VI)SmkO`LxW2lgV)iJIn3I2n>3cqYs`NaH8<#v`+tM856a*vLM z&cZ^S)$V=6J0DJ%FU7AOP@CfnsQAo?oN!8=h*HX|&SfgNMV8CSnvW1Z2GE#GL@)gSSi*i!90HeZ;ssI20 literal 0 HcmV?d00001 From 5ba947bb2bc2db41808a5ffbbcb63822c573691d Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 26 Jul 2023 11:57:17 +0200 Subject: [PATCH 004/312] bitswap/client: add basic traceable blocks (#308) Co-authored-by: hannahhoward --- CHANGELOG.md | 1 + bitswap/client/bitswap_with_sessions_test.go | 30 +++++++++++++++---- bitswap/client/client.go | 15 +++++----- .../internal/notifications/notifications.go | 16 +++++++--- .../notifications/notifications_test.go | 22 +++++++++----- bitswap/client/traceability/block.go | 21 +++++++++++++ 6 files changed, 80 insertions(+), 25 deletions(-) create mode 100644 bitswap/client/traceability/block.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 8388c06f9..da229502a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ The following emojis are used to highlight certain changes: * The only change to the default behavior on CAR responses is that we follow IPIP-412 and make `order=dfs;dups=n` explicit in the returned `Content-Type` HTTP header. +* ✨ While the call signature remains the same, the blocks that Bitswap returns can now be cast to [traceability.Block](./bitswap/client/traceability/block.go), which will additionally tell you where the Block came from and how long it took to fetch. This helps consumers of Bitswap collect better metrics on Bitswap behavior. ### Changed diff --git a/bitswap/client/bitswap_with_sessions_test.go b/bitswap/client/bitswap_with_sessions_test.go index e28379113..2191a5a90 100644 --- a/bitswap/client/bitswap_with_sessions_test.go +++ b/bitswap/client/bitswap_with_sessions_test.go @@ -8,6 +8,7 @@ import ( "github.com/ipfs/boxo/bitswap" "github.com/ipfs/boxo/bitswap/client/internal/session" + "github.com/ipfs/boxo/bitswap/client/traceability" testinstance "github.com/ipfs/boxo/bitswap/testinstance" tn "github.com/ipfs/boxo/bitswap/testnet" "github.com/ipfs/boxo/internal/test" @@ -17,6 +18,7 @@ import ( blocksutil "github.com/ipfs/go-ipfs-blocksutil" delay "github.com/ipfs/go-ipfs-delay" tu "github.com/libp2p/go-libp2p-testing/etc" + "github.com/libp2p/go-libp2p/core/peer" ) func getVirtualNetwork() tn.Network { @@ -71,9 +73,18 @@ func TestBasicSessions(t *testing.T) { if !blkout.Cid().Equals(block.Cid()) { t.Fatal("got wrong block") } + + traceBlock, ok := blkout.(traceability.Block) + if !ok { + t.Fatal("did not get tracable block") + } + + if traceBlock.From != b.Peer { + t.Fatal("should have received block from peer B, did not") + } } -func assertBlockLists(got, exp []blocks.Block) error { +func assertBlockListsFrom(from peer.ID, got, exp []blocks.Block) error { if len(got) != len(exp) { return fmt.Errorf("got wrong number of blocks, %d != %d", len(got), len(exp)) } @@ -81,6 +92,13 @@ func assertBlockLists(got, exp []blocks.Block) error { h := cid.NewSet() for _, b := range got { h.Add(b.Cid()) + traceableBlock, ok := b.(traceability.Block) + if !ok { + return fmt.Errorf("not a traceable block: %s", b.Cid()) + } + if traceableBlock.From != from { + return fmt.Errorf("incorrect peer sent block, expect %s, got %s", from, traceableBlock.From) + } } for _, b := range exp { if !h.Has(b.Cid()) { @@ -133,7 +151,7 @@ func TestSessionBetweenPeers(t *testing.T) { for b := range ch { got = append(got, b) } - if err := assertBlockLists(got, blks[i*10:(i+1)*10]); err != nil { + if err := assertBlockListsFrom(inst[0].Peer, got, blks[i*10:(i+1)*10]); err != nil { t.Fatal(err) } } @@ -192,7 +210,7 @@ func TestSessionSplitFetch(t *testing.T) { for b := range ch { got = append(got, b) } - if err := assertBlockLists(got, blks[i*10:(i+1)*10]); err != nil { + if err := assertBlockListsFrom(inst[i].Peer, got, blks[i*10:(i+1)*10]); err != nil { t.Fatal(err) } } @@ -238,7 +256,7 @@ func TestFetchNotConnected(t *testing.T) { for b := range ch { got = append(got, b) } - if err := assertBlockLists(got, blks); err != nil { + if err := assertBlockListsFrom(other.Peer, got, blks); err != nil { t.Fatal(err) } } @@ -289,7 +307,7 @@ func TestFetchAfterDisconnect(t *testing.T) { got = append(got, b) } - if err := assertBlockLists(got, blks[:5]); err != nil { + if err := assertBlockListsFrom(peerA.Peer, got, blks[:5]); err != nil { t.Fatal(err) } @@ -318,7 +336,7 @@ func TestFetchAfterDisconnect(t *testing.T) { } } - if err := assertBlockLists(got, blks); err != nil { + if err := assertBlockListsFrom(peerA.Peer, got, blks); err != nil { t.Fatal(err) } } diff --git a/bitswap/client/client.go b/bitswap/client/client.go index 4e5c57b82..d29eb6faf 100644 --- a/bitswap/client/client.go +++ b/bitswap/client/client.go @@ -5,14 +5,9 @@ package client import ( "context" "errors" - "sync" "time" - delay "github.com/ipfs/go-ipfs-delay" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" - bsbpm "github.com/ipfs/boxo/bitswap/client/internal/blockpresencemanager" bsgetter "github.com/ipfs/boxo/bitswap/client/internal/getter" bsmq "github.com/ipfs/boxo/bitswap/client/internal/messagequeue" @@ -33,11 +28,14 @@ import ( exchange "github.com/ipfs/boxo/exchange" blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" + delay "github.com/ipfs/go-ipfs-delay" logging "github.com/ipfs/go-log/v2" "github.com/ipfs/go-metrics-interface" process "github.com/jbenet/goprocess" procctx "github.com/jbenet/goprocess/context" "github.com/libp2p/go-libp2p/core/peer" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) var log = logging.Logger("bitswap-client") @@ -239,6 +237,7 @@ type counters struct { // GetBlock attempts to retrieve a particular block from peers within the // deadline enforced by the context. +// It returns a [github.com/ipfs/boxo/bitswap/client/traceability.Block] assertable [blocks.Block]. func (bs *Client) GetBlock(ctx context.Context, k cid.Cid) (blocks.Block, error) { ctx, span := internal.StartSpan(ctx, "GetBlock", trace.WithAttributes(attribute.String("Key", k.String()))) defer span.End() @@ -248,6 +247,7 @@ func (bs *Client) GetBlock(ctx context.Context, k cid.Cid) (blocks.Block, error) // GetBlocks returns a channel where the caller may receive blocks that // correspond to the provided |keys|. Returns an error if BitSwap is unable to // begin this request within the deadline enforced by the context. +// It returns a [github.com/ipfs/boxo/bitswap/client/traceability.Block] assertable [blocks.Block]. // // NB: Your request remains open until the context expires. To conserve // resources, provide a context with a reasonably short deadline (ie. not one @@ -284,7 +284,8 @@ func (bs *Client) NotifyNewBlocks(ctx context.Context, blks ...blocks.Block) err // Publish the block to any Bitswap clients that had requested blocks. // (the sessions use this pubsub mechanism to inform clients of incoming // blocks) - bs.notif.Publish(blks...) + var zero peer.ID + bs.notif.Publish(zero, blks...) return nil } @@ -325,7 +326,7 @@ func (bs *Client) receiveBlocksFrom(ctx context.Context, from peer.ID, blks []bl // (the sessions use this pubsub mechanism to inform clients of incoming // blocks) for _, b := range wanted { - bs.notif.Publish(b) + bs.notif.Publish(from, b) } for _, b := range wanted { diff --git a/bitswap/client/internal/notifications/notifications.go b/bitswap/client/internal/notifications/notifications.go index ed4b79f57..dc6dda899 100644 --- a/bitswap/client/internal/notifications/notifications.go +++ b/bitswap/client/internal/notifications/notifications.go @@ -3,10 +3,13 @@ package notifications import ( "context" "sync" + "time" pubsub "github.com/cskr/pubsub" + "github.com/ipfs/boxo/bitswap/client/traceability" blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" + "github.com/libp2p/go-libp2p/core/peer" ) const bufferSize = 16 @@ -15,7 +18,7 @@ const bufferSize = 16 // for cids. It's used internally by bitswap to decouple receiving blocks // and actually providing them back to the GetBlocks caller. type PubSub interface { - Publish(blocks ...blocks.Block) + Publish(from peer.ID, blocks ...blocks.Block) Subscribe(ctx context.Context, keys ...cid.Cid) <-chan blocks.Block Shutdown() } @@ -35,7 +38,7 @@ type impl struct { closed chan struct{} } -func (ps *impl) Publish(blocks ...blocks.Block) { +func (ps *impl) Publish(from peer.ID, blocks ...blocks.Block) { ps.lk.RLock() defer ps.lk.RUnlock() select { @@ -45,7 +48,7 @@ func (ps *impl) Publish(blocks ...blocks.Block) { } for _, block := range blocks { - ps.wrapped.Pub(block, block.Cid().KeyString()) + ps.wrapped.Pub(traceability.Block{Block: block, From: from}, block.Cid().KeyString()) } } @@ -84,6 +87,8 @@ func (ps *impl) Subscribe(ctx context.Context, keys ...cid.Cid) <-chan blocks.Bl default: } + subscribe := time.Now() + // AddSubOnceEach listens for each key in the list, and closes the channel // once all keys have been received ps.wrapped.AddSubOnceEach(valuesCh, toStrings(keys)...) @@ -113,10 +118,13 @@ func (ps *impl) Subscribe(ctx context.Context, keys ...cid.Cid) <-chan blocks.Bl if !ok { return } - block, ok := val.(blocks.Block) + block, ok := val.(traceability.Block) if !ok { + // FIXME: silently dropping errors wtf ? return } + block.Delay = time.Since(subscribe) + select { case <-ctx.Done(): return diff --git a/bitswap/client/internal/notifications/notifications_test.go b/bitswap/client/internal/notifications/notifications_test.go index 09c8eb806..25b580f6a 100644 --- a/bitswap/client/internal/notifications/notifications_test.go +++ b/bitswap/client/internal/notifications/notifications_test.go @@ -10,10 +10,12 @@ import ( blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" blocksutil "github.com/ipfs/go-ipfs-blocksutil" + "github.com/libp2p/go-libp2p/core/peer" ) func TestDuplicates(t *testing.T) { test.Flaky(t) + var zero peer.ID // this test doesn't check the peer id b1 := blocks.NewBlock([]byte("1")) b2 := blocks.NewBlock([]byte("2")) @@ -22,16 +24,16 @@ func TestDuplicates(t *testing.T) { defer n.Shutdown() ch := n.Subscribe(context.Background(), b1.Cid(), b2.Cid()) - n.Publish(b1) + n.Publish(zero, b1) blockRecvd, ok := <-ch if !ok { t.Fail() } assertBlocksEqual(t, b1, blockRecvd) - n.Publish(b1) // ignored duplicate + n.Publish(zero, b1) // ignored duplicate - n.Publish(b2) + n.Publish(zero, b2) blockRecvd, ok = <-ch if !ok { t.Fail() @@ -41,6 +43,7 @@ func TestDuplicates(t *testing.T) { func TestPublishSubscribe(t *testing.T) { test.Flaky(t) + var zero peer.ID // this test doesn't check the peer id blockSent := blocks.NewBlock([]byte("Greetings from The Interval")) @@ -48,7 +51,7 @@ func TestPublishSubscribe(t *testing.T) { defer n.Shutdown() ch := n.Subscribe(context.Background(), blockSent.Cid()) - n.Publish(blockSent) + n.Publish(zero, blockSent) blockRecvd, ok := <-ch if !ok { t.Fail() @@ -60,6 +63,7 @@ func TestPublishSubscribe(t *testing.T) { func TestSubscribeMany(t *testing.T) { test.Flaky(t) + var zero peer.ID // this test doesn't check the peer id e1 := blocks.NewBlock([]byte("1")) e2 := blocks.NewBlock([]byte("2")) @@ -68,14 +72,14 @@ func TestSubscribeMany(t *testing.T) { defer n.Shutdown() ch := n.Subscribe(context.Background(), e1.Cid(), e2.Cid()) - n.Publish(e1) + n.Publish(zero, e1) r1, ok := <-ch if !ok { t.Fatal("didn't receive first expected block") } assertBlocksEqual(t, e1, r1) - n.Publish(e2) + n.Publish(zero, e2) r2, ok := <-ch if !ok { t.Fatal("didn't receive second expected block") @@ -87,6 +91,7 @@ func TestSubscribeMany(t *testing.T) { // would be requested twice at the same time. func TestDuplicateSubscribe(t *testing.T) { test.Flaky(t) + var zero peer.ID // this test doesn't check the peer id e1 := blocks.NewBlock([]byte("1")) @@ -95,7 +100,7 @@ func TestDuplicateSubscribe(t *testing.T) { ch1 := n.Subscribe(context.Background(), e1.Cid()) ch2 := n.Subscribe(context.Background(), e1.Cid()) - n.Publish(e1) + n.Publish(zero, e1) r1, ok := <-ch1 if !ok { t.Fatal("didn't receive first expected block") @@ -158,6 +163,7 @@ func TestCarryOnWhenDeadlineExpires(t *testing.T) { func TestDoesNotDeadLockIfContextCancelledBeforePublish(t *testing.T) { test.Flaky(t) + var zero peer.ID // this test doesn't check the peer id g := blocksutil.NewBlockGenerator() ctx, cancel := context.WithCancel(context.Background()) @@ -179,7 +185,7 @@ func TestDoesNotDeadLockIfContextCancelledBeforePublish(t *testing.T) { t.Log("cancel context before any blocks published") cancel() for _, b := range bs { - n.Publish(b) + n.Publish(zero, b) } t.Log("publishing the large number of blocks to the ignored channel must not deadlock") diff --git a/bitswap/client/traceability/block.go b/bitswap/client/traceability/block.go new file mode 100644 index 000000000..28b52118d --- /dev/null +++ b/bitswap/client/traceability/block.go @@ -0,0 +1,21 @@ +package traceability + +import ( + "time" + + blocks "github.com/ipfs/go-block-format" + "github.com/libp2p/go-libp2p/core/peer" +) + +// Block is a block whose provenance has been tracked. +type Block struct { + blocks.Block + + // From contains the peer id of the node who sent us the block. + // It will be the zero value if we did not downloaded this block from the + // network. (such as by getting the block from NotifyNewBlocks). + From peer.ID + // Delay contains how long did we had to wait between when we started being + // intrested and when we actually got the block. + Delay time.Duration +} From fe8f90ed6a69c0b0656f122a503e9f01e0e0cf3c Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 26 Jul 2023 16:22:54 +0200 Subject: [PATCH 005/312] changelog: create v0.11.0 section --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index da229502a..b3a41d83f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,18 @@ The following emojis are used to highlight certain changes: ### Added +### Changed + +### Removed + +### Fixed + +### Security + +## [v0.11.0] + +### Added + * ✨ The gateway now supports the optional `order` and `dups` CAR parameters from [IPIP-412](https://github.com/ipfs/specs/pull/412). * The `BlocksBackend` only implements `order=dfs` (Depth-First Search) From 7c4111d4c2984b8a17ae4b025c0072f31797eaf0 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 26 Jul 2023 16:31:47 +0200 Subject: [PATCH 006/312] chore: release v0.11.0 --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index 9186b8eee..ea22ea591 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "v0.10.2" + "version": "v0.11.0" } From 221dbc488fd559b60739d7cb386deae976cd7cee Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Mon, 31 Jul 2023 12:04:56 +0200 Subject: [PATCH 007/312] chore: gateway conformance v0.3 --- .github/workflows/gateway-conformance.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index c6c12ed05..281cfe951 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -16,7 +16,7 @@ jobs: steps: # 1. Download the gateway-conformance fixtures - name: Download gateway-conformance fixtures - uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.2 + uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.3 with: output: fixtures merged: true @@ -40,7 +40,7 @@ jobs: # 4. Run the gateway-conformance tests - name: Run gateway-conformance tests - uses: ipfs/gateway-conformance/.github/actions/test@v0.2 + uses: ipfs/gateway-conformance/.github/actions/test@v0.3 with: gateway-url: http://127.0.0.1:8040 json: output.json From 582e297b584af31709c39caea74f066a833a7478 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Tue, 25 Jul 2023 09:54:47 -0400 Subject: [PATCH 008/312] fix: handle _redirects for If-None-Match headers (#412) * fix: handle _redirects for If-None-Match headers * fix: handle _redirects for If-None-Match headers * fix(gateway): HEAD requests now respect _redirects * feat: add _redirects regression test * docs: add changelog entry (cherry picked from commit 1f5df74ba66a6f42bce56c6b7b9b8bf322c1a4ba) --- CHANGELOG.md | 2 ++ gateway/gateway_test.go | 55 +++++++++++++++++++++++++++++ gateway/handler.go | 16 +++++++-- gateway/handler_defaults.go | 19 ++++++++-- gateway/testdata/redirects-spa.car | Bin 0 -> 360 bytes 5 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 gateway/testdata/redirects-spa.car diff --git a/CHANGELOG.md b/CHANGELOG.md index 934fc75ce..62ca5313f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,8 @@ The following emojis are used to highlight certain changes: ### Fixed +- Handle `_redirects` file when `If-None-Match` header is present ([#412](https://github.com/ipfs/boxo/pull/412)) + ### Security ## [0.10.2] - 2023-06-29 diff --git a/gateway/gateway_test.go b/gateway/gateway_test.go index cc36da68f..7fae55f3e 100644 --- a/gateway/gateway_test.go +++ b/gateway/gateway_test.go @@ -523,6 +523,61 @@ func TestRedirects(t *testing.T) { res = mustDoWithoutRedirect(t, req) require.Equal(t, http.StatusNotFound, res.StatusCode) }) + + t.Run("_redirects file with If-None-Match header", func(t *testing.T) { + t.Parallel() + + backend, root := newMockBackend(t, "redirects-spa.car") + backend.namesys["/ipns/example.com"] = path.FromCid(root) + + ts := newTestServerWithConfig(t, backend, Config{ + Headers: map[string][]string{}, + NoDNSLink: false, + PublicGateways: map[string]*PublicGateway{ + "example.com": { + UseSubdomains: true, + DeserializedResponses: true, + }, + }, + DeserializedResponses: true, + }) + + missingPageURL := ts.URL + "/missing-page" + + do := func(method string) { + // Make initial request to non-existing page that should return the contents + // of index.html as per the _redirects file. + req := mustNewRequest(t, method, missingPageURL, nil) + req.Header.Add("Accept", "text/html") + req.Host = "example.com" + + res := mustDoWithoutRedirect(t, req) + defer res.Body.Close() + + // Check statuses and body. + require.Equal(t, http.StatusOK, res.StatusCode) + body, err := io.ReadAll(res.Body) + require.NoError(t, err) + require.Equal(t, "hello world\n", string(body)) + + // Check Etag. + etag := res.Header.Get("Etag") + require.NotEmpty(t, etag) + + // Repeat request with Etag as If-None-Match value. Expect 304 Not Modified. + req = mustNewRequest(t, method, missingPageURL, nil) + req.Header.Add("Accept", "text/html") + req.Host = "example.com" + req.Header.Add("If-None-Match", etag) + + res = mustDoWithoutRedirect(t, req) + defer res.Body.Close() + require.Equal(t, http.StatusNotModified, res.StatusCode) + } + + do(http.MethodGet) + do(http.MethodHead) + }) } func TestDeserializedResponses(t *testing.T) { diff --git a/gateway/handler.go b/gateway/handler.go index cf553320a..3849bfec2 100644 --- a/gateway/handler.go +++ b/gateway/handler.go @@ -700,9 +700,19 @@ func (i *handler) handleIfNoneMatch(w http.ResponseWriter, r *http.Request, rq * if ifNoneMatch := r.Header.Get("If-None-Match"); ifNoneMatch != "" { pathMetadata, err := i.backend.ResolvePath(r.Context(), rq.immutablePath) if err != nil { - err = fmt.Errorf("failed to resolve %s: %w", debugStr(rq.contentPath.String()), err) - i.webError(w, r, err, http.StatusInternalServerError) - return true + var forwardedPath ImmutablePath + var continueProcessing bool + if isWebRequest(rq.responseFormat) { + forwardedPath, continueProcessing = i.handleWebRequestErrors(w, r, rq.mostlyResolvedPath(), rq.immutablePath, rq.contentPath, err, rq.logger) + if continueProcessing { + pathMetadata, err = i.backend.ResolvePath(r.Context(), forwardedPath) + } + } + if !continueProcessing || err != nil { + err = fmt.Errorf("failed to resolve %s: %w", debugStr(rq.contentPath.String()), err) + i.webError(w, r, err, http.StatusInternalServerError) + return true + } } pathCid := pathMetadata.LastSegment.Cid() diff --git a/gateway/handler_defaults.go b/gateway/handler_defaults.go index 8e96d8b15..de31c1fc1 100644 --- a/gateway/handler_defaults.go +++ b/gateway/handler_defaults.go @@ -33,8 +33,23 @@ func (i *handler) serveDefaults(ctx context.Context, w http.ResponseWriter, r *h case http.MethodHead: var data files.Node pathMetadata, data, err = i.backend.Head(ctx, rq.mostlyResolvedPath()) - if !i.handleRequestErrors(w, r, rq.contentPath, err) { - return false + if err != nil { + if isWebRequest(rq.responseFormat) { + forwardedPath, continueProcessing := i.handleWebRequestErrors(w, r, rq.mostlyResolvedPath(), rq.immutablePath, rq.contentPath, err, rq.logger) + if !continueProcessing { + return false + } + pathMetadata, data, err = i.backend.Head(ctx, forwardedPath) + if err != nil { + err = fmt.Errorf("failed to resolve %s: %w", debugStr(rq.contentPath.String()), err) + i.webError(w, r, err, http.StatusInternalServerError) + return false + } + } else { + if !i.handleRequestErrors(w, r, rq.contentPath, err) { + return false + } + } } defer data.Close() if _, ok := data.(files.Directory); ok { diff --git a/gateway/testdata/redirects-spa.car b/gateway/testdata/redirects-spa.car new file mode 100644 index 0000000000000000000000000000000000000000..b92b253991c300332a456410a770b9355972bca9 GIT binary patch literal 360 zcmcColv%#k2 zU*Dvcr4|)u=I1d^VI)SmkO`LxW2lgV)iJIn3I2n>3cqYs`NaH8<#v`+tM856a*vLM z&cZ^S)$V=6J0DJ%FU7AOP@CfnsQAo?oN!8=h*HX|&SfgNMV8CSnvW1Z2GE#GL@)gSSi*i!90HeZ;ssI20 literal 0 HcmV?d00001 From 315c8a8e3b8edaaa2be7abaa06927f676a3091b1 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 8 Aug 2023 12:07:34 +0200 Subject: [PATCH 009/312] changelog: wrapup for 0.10.3 --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62ca5313f..3faa649dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,18 @@ The following emojis are used to highlight certain changes: ### Fixed +### Security + +## [0.10.3] - 2023-08-08 + +### Added + +### Changed + +### Removed + +### Fixed + - Handle `_redirects` file when `If-None-Match` header is present ([#412](https://github.com/ipfs/boxo/pull/412)) ### Security From b0cb35aabb992b6193acaf58e77f30a344a4950a Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 8 Aug 2023 13:30:15 +0200 Subject: [PATCH 010/312] chore: release v0.10.3 --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index 9186b8eee..9e6dd4ba8 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "v0.10.2" + "version": "v0.10.3" } From d4e6cd9eff8fb617d5dc52ef2a48fe10a3647b01 Mon Sep 17 00:00:00 2001 From: Joao Andrade Date: Mon, 7 Aug 2023 14:07:56 +0100 Subject: [PATCH 011/312] docs(readme): fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 767e34637..45edb5953 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ No. This repo houses some IPFS functionality written in Go that has been useful ### Is everything related to IPFS in the Go ecosystem in this repo? -No. Not everything related to IPFS is intended to be in Boxo. View it as a starter toolbox (potentially among multiple). If you’d like to build an IPFS implementation with Go, here are some tools you might want that are maintained by a group that has long term commitments to the IPFS project. There are certainly repos that others maintainer that aren't included here (e.g., ipfs/go-car) which are still useful to IPFS implementations. It's expected and fine for new IPFS functionality to be developed that won't be part of Boxo. +No. Not everything related to IPFS is intended to be in Boxo. View it as a starter toolbox (potentially among multiple). If you’d like to build an IPFS implementation with Go, here are some tools you might want that are maintained by a group that has long term commitments to the IPFS project. There are certainly repos that others maintain that aren't included here (e.g., ipfs/go-car) which are still useful to IPFS implementations. It's expected and fine for new IPFS functionality to be developed that won't be part of Boxo. ## Consuming From 5116b44dc1c580810a05a57c514d6a2fdeb3b58d Mon Sep 17 00:00:00 2001 From: web3-bot Date: Sun, 13 Aug 2023 18:49:37 +0200 Subject: [PATCH 012/312] ci: uci/delete-templates (#428) chore: delete templates [skip ci] --- .github/workflows/automerge.yml | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 .github/workflows/automerge.yml diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml deleted file mode 100644 index 0b1e9d055..000000000 --- a/.github/workflows/automerge.yml +++ /dev/null @@ -1,15 +0,0 @@ -# File managed by web3-bot. DO NOT EDIT. -# See https://github.com/protocol/.github/ for details. - -name: Automerge -on: [ pull_request ] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - automerge: - uses: protocol/.github/.github/workflows/automerge.yml@master - with: - job: 'automerge' From b96767cc0971ca279feb36e7844e527a774309ab Mon Sep 17 00:00:00 2001 From: web3-bot Date: Mon, 14 Aug 2023 10:06:52 +0200 Subject: [PATCH 013/312] ci: uci/copy-templates (#429) * chore: add or force update .github/workflows/go-test.yml * chore: add or force update .github/workflows/go-check.yml * chore: add or force update .github/workflows/releaser.yml * chore: add or force update .github/workflows/release-check.yml * chore: add or force update .github/workflows/tagpush.yml * chore: update .github/workflows/go-test.yml --- .github/workflows/go-check.yml | 70 +++------------------ .github/workflows/go-test.yml | 94 +++-------------------------- .github/workflows/release-check.yml | 14 +++-- .github/workflows/releaser.yml | 10 +-- .github/workflows/tagpush.yml | 10 +-- 5 files changed, 34 insertions(+), 164 deletions(-) diff --git a/.github/workflows/go-check.yml b/.github/workflows/go-check.yml index d0729ee4d..9c0589c07 100644 --- a/.github/workflows/go-check.yml +++ b/.github/workflows/go-check.yml @@ -1,74 +1,18 @@ -# File managed by web3-bot. DO NOT EDIT. -# See https://github.com/protocol/.github/ for details. +name: Go Checks on: pull_request: push: branches: ["main","release"] -name: Go Checks + workflow_dispatch: + +permissions: + contents: read concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} cancel-in-progress: true jobs: - unit: - runs-on: ubuntu-latest - name: All - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - id: config - uses: protocol/.github/.github/actions/read-config@master - - uses: actions/setup-go@v3 - with: - go-version: 1.20.x - - name: Run repo-specific setup - uses: ./.github/actions/go-check-setup - if: hashFiles('./.github/actions/go-check-setup') != '' - - name: Install staticcheck - run: go install honnef.co/go/tools/cmd/staticcheck@4970552d932f48b71485287748246cf3237cebdf # 2023.1 (v0.4.0) - - name: Check that go.mod is tidy - uses: protocol/multiple-go-modules@v1.2 - with: - run: | - go mod tidy - if [[ -n $(git ls-files --other --exclude-standard --directory -- go.sum) ]]; then - echo "go.sum was added by go mod tidy" - exit 1 - fi - git diff --exit-code -- go.sum go.mod - - name: gofmt - if: success() || failure() # run this step even if the previous one failed - run: | - out=$(gofmt -s -l .) - if [[ -n "$out" ]]; then - echo $out | awk '{print "::error file=" $0 ",line=0,col=0::File is not gofmt-ed."}' - exit 1 - fi - - name: go vet - if: success() || failure() # run this step even if the previous one failed - uses: protocol/multiple-go-modules@v1.2 - with: - run: go vet ./... - - name: staticcheck - if: success() || failure() # run this step even if the previous one failed - uses: protocol/multiple-go-modules@v1.2 - with: - run: | - set -o pipefail - staticcheck ./... | sed -e 's@\(.*\)\.go@./\1.go@g' - - name: go generate - uses: protocol/multiple-go-modules@v1.2 - if: (success() || failure()) && fromJSON(steps.config.outputs.json).gogenerate == true - with: - run: | - git clean -fd # make sure there aren't untracked files / directories - go generate -x ./... - # check if go generate modified or added any files - if ! $(git add . && git diff-index HEAD --exit-code --quiet); then - echo "go generated caused changes to the repository:" - git status --short - exit 1 - fi + go-check: + uses: pl-strflt/uci/.github/workflows/go-check.yml@v0.0 diff --git a/.github/workflows/go-test.yml b/.github/workflows/go-test.yml index 744100912..f9d7cb34d 100644 --- a/.github/workflows/go-test.yml +++ b/.github/workflows/go-test.yml @@ -1,98 +1,18 @@ -# File managed by web3-bot. DO NOT EDIT. -# See https://github.com/protocol/.github/ for details. +name: Go Test on: pull_request: push: branches: ["main","release"] -name: Go Test + workflow_dispatch: + +permissions: + contents: read concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} cancel-in-progress: true jobs: - unit: - strategy: - fail-fast: false - matrix: - os: [ "ubuntu", "windows", "macos" ] - go: ["1.19.x","1.20.x"] - env: - GOTESTFLAGS: -cover -coverprofile=module-coverage.txt -coverpkg=./... - GO386FLAGS: '' - GORACEFLAGS: '' - runs-on: ${{ fromJSON(vars[format('UCI_GO_TEST_RUNNER_{0}', matrix.os)] || format('"{0}-latest"', matrix.os)) }} - name: ${{ matrix.os }} (go ${{ matrix.go }}) - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - id: config - uses: protocol/.github/.github/actions/read-config@master - - if: toJSON(fromJSON(steps.config.outputs.json).shuffle) != 'false' - run: | - echo "GOTESTFLAGS=-shuffle=on $GOTESTFLAGS" >> $GITHUB_ENV - echo "GO386FLAGS=-shuffle=on $GO386FLAGS" >> $GITHUB_ENV - echo "GORACEFLAGS=-shuffle=on $GORACEFLAGS" >> $GITHUB_ENV - - if: toJSON(fromJSON(steps.config.outputs.json).verbose) != 'false' - run: | - echo "GOTESTFLAGS=-v $GOTESTFLAGS" >> $GITHUB_ENV - echo "GO386FLAGS=-v $GO386FLAGS" >> $GITHUB_ENV - echo "GORACEFLAGS=-v $GORACEFLAGS" >> $GITHUB_ENV - - uses: actions/setup-go@v3 - with: - go-version: ${{ matrix.go }} - - name: Go information - run: | - go version - go env - - name: Use msys2 on windows - if: matrix.os == 'windows' - shell: bash - # The executable for msys2 is also called bash.cmd - # https://github.com/actions/virtual-environments/blob/main/images/win/Windows2019-Readme.md#shells - # If we prepend its location to the PATH - # subsequent 'shell: bash' steps will use msys2 instead of gitbash - run: echo "C:/msys64/usr/bin" >> $GITHUB_PATH - - name: Run repo-specific setup - uses: ./.github/actions/go-test-setup - if: hashFiles('./.github/actions/go-test-setup') != '' - - name: Run tests - if: contains(fromJSON(steps.config.outputs.json).skipOSes, matrix.os) == false - uses: protocol/multiple-go-modules@v1.2 - env: - GOFLAGS: ${{ format('{0} {1}', env.GOTESTFLAGS, env.GOFLAGS) }} - with: - run: go test ./... - - name: Run tests (32 bit) - # can't run 32 bit tests on OSX. - if: matrix.os != 'macos' && - fromJSON(steps.config.outputs.json).skip32bit != true && - contains(fromJSON(steps.config.outputs.json).skipOSes, matrix.os) == false - uses: protocol/multiple-go-modules@v1.2 - env: - GOARCH: 386 - GOFLAGS: ${{ format('{0} {1}', env.GO386FLAGS, env.GOFLAGS) }} - with: - run: | - export "PATH=$PATH_386:$PATH" - go test ./... - - name: Run tests with race detector - # speed things up. Windows and OSX VMs are slow - if: matrix.os == 'ubuntu' && - contains(fromJSON(steps.config.outputs.json).skipOSes, matrix.os) == false - uses: protocol/multiple-go-modules@v1.2 - env: - GOFLAGS: ${{ format('{0} {1}', env.GORACEFLAGS, env.GOFLAGS) }} - with: - run: go test -race ./... - - name: Collect coverage files - id: coverages - shell: bash - run: echo "files=$(find . -type f -name 'module-coverage.txt' | tr -s '\n' ',' | sed 's/,$//')" >> $GITHUB_OUTPUT - - name: Upload coverage to Codecov - uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # v3.1.1 - with: - files: ${{ steps.coverages.outputs.files }} - env_vars: OS=${{ matrix.os }}, GO=${{ matrix.go }} + go-test: + uses: ipfs/uci/.github/workflows/go-test.yml@v0.0 diff --git a/.github/workflows/release-check.yml b/.github/workflows/release-check.yml index c8c455f0d..bda616005 100644 --- a/.github/workflows/release-check.yml +++ b/.github/workflows/release-check.yml @@ -1,10 +1,14 @@ -# File managed by web3-bot. DO NOT EDIT. -# See https://github.com/protocol/.github/ for details. - name: Release Checker + on: pull_request_target: paths: [ 'version.json' ] + types: [ opened, synchronize, reopened, labeled, unlabeled ] + workflow_dispatch: + +permissions: + contents: write + pull-requests: write concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -12,6 +16,4 @@ concurrency: jobs: release-check: - uses: protocol/.github/.github/workflows/release-check.yml@master - with: - go-version: 1.20.x + uses: pl-strflt/uci/.github/workflows/release-check.yml@v0.0 diff --git a/.github/workflows/releaser.yml b/.github/workflows/releaser.yml index 201338e86..dd8081b91 100644 --- a/.github/workflows/releaser.yml +++ b/.github/workflows/releaser.yml @@ -1,10 +1,12 @@ -# File managed by web3-bot. DO NOT EDIT. -# See https://github.com/protocol/.github/ for details. - name: Releaser + on: push: paths: [ 'version.json' ] + workflow_dispatch: + +permissions: + contents: write concurrency: group: ${{ github.workflow }}-${{ github.sha }} @@ -12,4 +14,4 @@ concurrency: jobs: releaser: - uses: protocol/.github/.github/workflows/releaser.yml@master + uses: pl-strflt/uci/.github/workflows/releaser.yml@v0.0 diff --git a/.github/workflows/tagpush.yml b/.github/workflows/tagpush.yml index 3894127b1..59de8cb91 100644 --- a/.github/workflows/tagpush.yml +++ b/.github/workflows/tagpush.yml @@ -1,16 +1,18 @@ -# File managed by web3-bot. DO NOT EDIT. -# See https://github.com/protocol/.github/ for details. - name: Tag Push Checker + on: push: tags: - v* +permissions: + contents: read + issues: write + concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: releaser: - uses: protocol/.github/.github/workflows/tagpush.yml@master + uses: pl-strflt/uci/.github/workflows/tagpush.yml@v0.0 From 6b07cb0d8bea293f4b1be2885905e9ff5fe227aa Mon Sep 17 00:00:00 2001 From: Wondertan Date: Sun, 9 Jul 2023 18:56:11 +0200 Subject: [PATCH 014/312] verifcid: introduce Allowlist interface --- CHANGELOG.md | 6 + blockservice/blockservice.go | 106 +++++++++++------- provider/reprovider.go | 13 ++- verifcid/allowlist.go | 69 ++++++++++++ .../{validate_test.go => allowlist_test.go} | 30 +++-- verifcid/cid.go | 33 ++++++ verifcid/validate.go | 69 ------------ 7 files changed, 201 insertions(+), 125 deletions(-) create mode 100644 verifcid/allowlist.go rename verifcid/{validate_test.go => allowlist_test.go} (69%) create mode 100644 verifcid/cid.go delete mode 100644 verifcid/validate.go diff --git a/CHANGELOG.md b/CHANGELOG.md index b3a41d83f..04021016c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,12 @@ The following emojis are used to highlight certain changes: ### Added +* The `verifycid` package has been updated with the new Allowlist interface as part of + reducing globals efforts. Still, existing global accessor funcs are kept for + backwards-compatibility. +* The `blockservice` and `provider` packages has been updated to accommodate for + changes in `verifycid`. + ### Changed ### Removed diff --git a/blockservice/blockservice.go b/blockservice/blockservice.go index 773fb5303..cdcac33cc 100644 --- a/blockservice/blockservice.go +++ b/blockservice/blockservice.go @@ -1,4 +1,4 @@ -// package blockservice implements a BlockService interface that provides +// Package blockservice implements a BlockService interface that provides // a single GetBlock/AddBlock interface that seamlessly retrieves data either // locally or from a remote peer through the exchange. package blockservice @@ -11,11 +11,11 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" - blockstore "github.com/ipfs/boxo/blockstore" - exchange "github.com/ipfs/boxo/exchange" + "github.com/ipfs/boxo/blockstore" + "github.com/ipfs/boxo/exchange" "github.com/ipfs/boxo/verifcid" blocks "github.com/ipfs/go-block-format" - cid "github.com/ipfs/go-cid" + "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" logging "github.com/ipfs/go-log/v2" @@ -64,7 +64,15 @@ type BlockService interface { DeleteBlock(ctx context.Context, o cid.Cid) error } +// BoundedBlockService is a Blockservice bounded via strict multihash Allowlist. +type BoundedBlockService interface { + BlockService + + Allowlist() verifcid.Allowlist +} + type blockService struct { + allowlist verifcid.Allowlist blockstore blockstore.Blockstore exchange exchange.Interface // If checkFirst is true then first check that a block doesn't @@ -72,33 +80,45 @@ type blockService struct { checkFirst bool } -// NewBlockService creates a BlockService with given datastore instance. -func New(bs blockstore.Blockstore, rem exchange.Interface) BlockService { - if rem == nil { +// New creates a BlockService with given datastore instance. +func New(bs blockstore.Blockstore, exchange exchange.Interface) BlockService { + if exchange == nil { logger.Debug("blockservice running in local (offline) mode.") } return &blockService{ + allowlist: verifcid.DefaultAllowlist, blockstore: bs, - exchange: rem, + exchange: exchange, checkFirst: true, } } // NewWriteThrough creates a BlockService that guarantees writes will go // through to the blockstore and are not skipped by cache checks. -func NewWriteThrough(bs blockstore.Blockstore, rem exchange.Interface) BlockService { - if rem == nil { +func NewWriteThrough(bs blockstore.Blockstore, exchange exchange.Interface) BlockService { + if exchange == nil { logger.Debug("blockservice running in local (offline) mode.") } return &blockService{ + allowlist: verifcid.DefaultAllowlist, blockstore: bs, - exchange: rem, + exchange: exchange, checkFirst: false, } } +// NewWithAllowList creates a BlockService with customized multihash Allowlist. +func NewWithAllowList(bs blockstore.Blockstore, exchange exchange.Interface, allowlist verifcid.Allowlist) BlockService { + return &blockService{ + allowlist: allowlist, + blockstore: bs, + exchange: exchange, + checkFirst: true, + } +} + // Blockstore returns the blockstore behind this blockservice. func (s *blockService) Blockstore() blockstore.Blockstore { return s.blockstore @@ -109,27 +129,37 @@ func (s *blockService) Exchange() exchange.Interface { return s.exchange } +func (s *blockService) Allowlist() verifcid.Allowlist { + return s.allowlist +} + // NewSession creates a new session that allows for // controlled exchange of wantlists to decrease the bandwidth overhead. // If the current exchange is a SessionExchange, a new exchange // session will be created. Otherwise, the current exchange will be used // directly. func NewSession(ctx context.Context, bs BlockService) *Session { + allowlist := verifcid.Allowlist(verifcid.DefaultAllowlist) + if bbs, ok := bs.(BoundedBlockService); ok { + allowlist = bbs.Allowlist() + } exch := bs.Exchange() if sessEx, ok := exch.(exchange.SessionExchange); ok { return &Session{ - sessCtx: ctx, - ses: nil, - sessEx: sessEx, - bs: bs.Blockstore(), - notifier: exch, + allowlist: allowlist, + sessCtx: ctx, + ses: nil, + sessEx: sessEx, + bs: bs.Blockstore(), + notifier: exch, } } return &Session{ - ses: exch, - sessCtx: ctx, - bs: bs.Blockstore(), - notifier: exch, + allowlist: allowlist, + ses: exch, + sessCtx: ctx, + bs: bs.Blockstore(), + notifier: exch, } } @@ -139,8 +169,7 @@ func (s *blockService) AddBlock(ctx context.Context, o blocks.Block) error { defer span.End() c := o.Cid() - // hash security - err := verifcid.ValidateCid(c) + err := verifcid.ValidateCid(s.allowlist, c) // hash security if err != nil { return err } @@ -171,7 +200,7 @@ func (s *blockService) AddBlocks(ctx context.Context, bs []blocks.Block) error { // hash security for _, b := range bs { - err := verifcid.ValidateCid(b.Cid()) + err := verifcid.ValidateCid(s.allowlist, b.Cid()) if err != nil { return err } @@ -221,15 +250,15 @@ func (s *blockService) GetBlock(ctx context.Context, c cid.Cid) (blocks.Block, e f = s.getExchange } - return getBlock(ctx, c, s.blockstore, f) // hash security + return getBlock(ctx, c, s.blockstore, s.allowlist, f) } func (s *blockService) getExchange() notifiableFetcher { return s.exchange } -func getBlock(ctx context.Context, c cid.Cid, bs blockstore.Blockstore, fget func() notifiableFetcher) (blocks.Block, error) { - err := verifcid.ValidateCid(c) // hash security +func getBlock(ctx context.Context, c cid.Cid, bs blockstore.Blockstore, allowlist verifcid.Allowlist, fget func() notifiableFetcher) (blocks.Block, error) { + err := verifcid.ValidateCid(allowlist, c) // hash security if err != nil { return nil, err } @@ -278,10 +307,10 @@ func (s *blockService) GetBlocks(ctx context.Context, ks []cid.Cid) <-chan block f = s.getExchange } - return getBlocks(ctx, ks, s.blockstore, f) // hash security + return getBlocks(ctx, ks, s.blockstore, s.allowlist, f) } -func getBlocks(ctx context.Context, ks []cid.Cid, bs blockstore.Blockstore, fget func() notifiableFetcher) <-chan blocks.Block { +func getBlocks(ctx context.Context, ks []cid.Cid, bs blockstore.Blockstore, allowlist verifcid.Allowlist, fget func() notifiableFetcher) <-chan blocks.Block { out := make(chan blocks.Block) go func() { @@ -289,7 +318,7 @@ func getBlocks(ctx context.Context, ks []cid.Cid, bs blockstore.Blockstore, fget allValid := true for _, c := range ks { - if err := verifcid.ValidateCid(c); err != nil { + if err := verifcid.ValidateCid(allowlist, c); err != nil { allValid = false break } @@ -300,7 +329,7 @@ func getBlocks(ctx context.Context, ks []cid.Cid, bs blockstore.Blockstore, fget ks2 := make([]cid.Cid, 0, len(ks)) for _, c := range ks { // hash security - if err := verifcid.ValidateCid(c); err == nil { + if err := verifcid.ValidateCid(allowlist, c); err == nil { ks2 = append(ks2, c) } else { logger.Errorf("unsafe CID (%s) passed to blockService.GetBlocks: %s", c, err) @@ -396,12 +425,13 @@ type notifier interface { // Session is a helper type to provide higher level access to bitswap sessions type Session struct { - bs blockstore.Blockstore - ses exchange.Fetcher - sessEx exchange.SessionExchange - sessCtx context.Context - notifier notifier - lk sync.Mutex + allowlist verifcid.Allowlist + bs blockstore.Blockstore + ses exchange.Fetcher + sessEx exchange.SessionExchange + sessCtx context.Context + notifier notifier + lk sync.Mutex } type notifiableFetcher interface { @@ -444,7 +474,7 @@ func (s *Session) GetBlock(ctx context.Context, c cid.Cid) (blocks.Block, error) ctx, span := internal.StartSpan(ctx, "Session.GetBlock", trace.WithAttributes(attribute.Stringer("CID", c))) defer span.End() - return getBlock(ctx, c, s.bs, s.getFetcherFactory()) // hash security + return getBlock(ctx, c, s.bs, s.allowlist, s.getFetcherFactory()) } // GetBlocks gets blocks in the context of a request session @@ -452,7 +482,7 @@ func (s *Session) GetBlocks(ctx context.Context, ks []cid.Cid) <-chan blocks.Blo ctx, span := internal.StartSpan(ctx, "Session.GetBlocks") defer span.End() - return getBlocks(ctx, ks, s.bs, s.getFetcherFactory()) // hash security + return getBlocks(ctx, ks, s.bs, s.allowlist, s.getFetcherFactory()) } var _ BlockGetter = (*Session)(nil) diff --git a/provider/reprovider.go b/provider/reprovider.go index 619bf8196..e95227ee0 100644 --- a/provider/reprovider.go +++ b/provider/reprovider.go @@ -13,7 +13,7 @@ import ( "github.com/ipfs/boxo/verifcid" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" - namespace "github.com/ipfs/go-datastore/namespace" + "github.com/ipfs/go-datastore/namespace" logging "github.com/ipfs/go-log/v2" "github.com/multiformats/go-multihash" ) @@ -47,6 +47,7 @@ type reprovider struct { initalReprovideDelay time.Duration initialReprovideDelaySet bool + allowlist verifcid.Allowlist rsys Provide keyProvider KeyChanFunc @@ -102,6 +103,7 @@ var DefaultKeyPrefix = datastore.NewKey("/provider") // If provider casts to [Ready], it will wait until [Ready.Ready] is true. func New(ds datastore.Batching, opts ...Option) (System, error) { s := &reprovider{ + allowlist: verifcid.DefaultAllowlist, reprovideInterval: DefaultReproviderInterval, maxReprovideBatchSize: math.MaxUint, keyPrefix: DefaultKeyPrefix, @@ -149,6 +151,13 @@ func New(ds datastore.Batching, opts ...Option) (System, error) { return s, nil } +func Allowlist(allowlist verifcid.Allowlist) Option { + return func(system *reprovider) error { + system.allowlist = allowlist + return nil + } +} + func ReproviderInterval(duration time.Duration) Option { return func(system *reprovider) error { system.reprovideInterval = duration @@ -294,7 +303,7 @@ func (s *reprovider) run() { delete(m, c) // hash security - if err := verifcid.ValidateCid(c); err != nil { + if err := verifcid.ValidateCid(s.allowlist, c); err != nil { log.Errorf("insecure hash in reprovider, %s (%s)", c, err) continue } diff --git a/verifcid/allowlist.go b/verifcid/allowlist.go new file mode 100644 index 000000000..b572de3a6 --- /dev/null +++ b/verifcid/allowlist.go @@ -0,0 +1,69 @@ +package verifcid + +import ( + mh "github.com/multiformats/go-multihash" +) + +// DefaultAllowlist is the default list of hashes allowed in IPFS. +var DefaultAllowlist defaultAllowlist + +// Allowlist defines an interface containing list of allowed multihashes. +type Allowlist interface { + // IsAllowed checks for multihash allowance by the code. + IsAllowed(code uint64) bool +} + +// NewAllowlist constructs new [Allowlist] from the given map set. +func NewAllowlist(allowset map[uint64]bool) Allowlist { + return allowlist{allowset: allowset} +} + +// NewOverridingAllowlist is like [NewAllowlist] but it will fallback to an other [AllowList] if keys are missing. +// If override is nil it will return unsecure for unknown things. +func NewOverridingAllowlist(override Allowlist, allowset map[uint64]bool) Allowlist { + return allowlist{override, allowset} +} + +type allowlist struct { + override Allowlist + allowset map[uint64]bool +} + +func (al allowlist) IsAllowed(code uint64) bool { + if good, found := al.allowset[code]; found { + return good + } + + if al.override != nil { + return al.override.IsAllowed(code) + } + + return false +} + +type defaultAllowlist struct{} + +func (defaultAllowlist) IsAllowed(code uint64) bool { + switch code { + case mh.SHA2_256, mh.SHA2_512, + mh.SHAKE_256, + mh.DBL_SHA2_256, + mh.BLAKE3, + mh.IDENTITY, + + mh.SHA3_224, mh.SHA3_256, mh.SHA3_384, mh.SHA3_512, + mh.KECCAK_224, mh.KECCAK_256, mh.KECCAK_384, mh.KECCAK_512, + + mh.SHA1: // not really secure but still useful for git + return true + default: + if code >= mh.BLAKE2B_MIN+19 && code <= mh.BLAKE2B_MAX { + return true + } + if code >= mh.BLAKE2S_MIN+19 && code <= mh.BLAKE2S_MAX { + return true + } + + return false + } +} diff --git a/verifcid/validate_test.go b/verifcid/allowlist_test.go similarity index 69% rename from verifcid/validate_test.go rename to verifcid/allowlist_test.go index 5129b861a..ab8c415e1 100644 --- a/verifcid/validate_test.go +++ b/verifcid/allowlist_test.go @@ -5,10 +5,10 @@ import ( mh "github.com/multiformats/go-multihash" - cid "github.com/ipfs/go-cid" + "github.com/ipfs/go-cid" ) -func TestValidateCids(t *testing.T) { +func TestDefaultAllowList(t *testing.T) { assertTrue := func(v bool) { t.Helper() if !v { @@ -21,17 +21,6 @@ func TestValidateCids(t *testing.T) { t.Fatal("expected failure") } } - - assertTrue(IsGoodHash(mh.SHA2_256)) - assertTrue(IsGoodHash(mh.BLAKE2B_MIN + 32)) - assertTrue(IsGoodHash(mh.DBL_SHA2_256)) - assertTrue(IsGoodHash(mh.KECCAK_256)) - assertTrue(IsGoodHash(mh.SHA3)) - - assertTrue(IsGoodHash(mh.SHA1)) - - assertFalse(IsGoodHash(mh.BLAKE2B_MIN + 5)) - mhcid := func(code uint64, length int) cid.Cid { mhash, err := mh.Sum([]byte{}, code, length) if err != nil { @@ -40,6 +29,15 @@ func TestValidateCids(t *testing.T) { return cid.NewCidV1(cid.DagCBOR, mhash) } + allowlist := DefaultAllowlist + assertTrue(allowlist.IsAllowed(mh.SHA2_256)) + assertTrue(allowlist.IsAllowed(mh.BLAKE2B_MIN + 32)) + assertTrue(allowlist.IsAllowed(mh.DBL_SHA2_256)) + assertTrue(allowlist.IsAllowed(mh.KECCAK_256)) + assertTrue(allowlist.IsAllowed(mh.SHA3)) + assertTrue(allowlist.IsAllowed(mh.SHA1)) + assertFalse(allowlist.IsAllowed(mh.BLAKE2B_MIN + 5)) + cases := []struct { cid cid.Cid err error @@ -53,9 +51,9 @@ func TestValidateCids(t *testing.T) { } for i, cas := range cases { - if ValidateCid(cas.cid) != cas.err { + if ValidateCid(allowlist, cas.cid) != cas.err { t.Errorf("wrong result in case of %s (index %d). Expected: %s, got %s", - cas.cid, i, cas.err, ValidateCid(cas.cid)) + cas.cid, i, cas.err, ValidateCid(DefaultAllowlist, cas.cid)) } } @@ -64,7 +62,7 @@ func TestValidateCids(t *testing.T) { if err != nil { t.Fatalf("failed to produce a multihash from the long blake3 hash: %v", err) } - if ValidateCid(cid.NewCidV1(cid.DagCBOR, longBlake3Mh)) != ErrAboveMaximumHashLength { + if ValidateCid(allowlist, cid.NewCidV1(cid.DagCBOR, longBlake3Mh)) != ErrAboveMaximumHashLength { t.Errorf("a CID that was longer than the maximum hash length did not error with ErrAboveMaximumHashLength") } } diff --git a/verifcid/cid.go b/verifcid/cid.go new file mode 100644 index 000000000..334da2671 --- /dev/null +++ b/verifcid/cid.go @@ -0,0 +1,33 @@ +package verifcid + +import ( + "fmt" + + "github.com/ipfs/go-cid" + mh "github.com/multiformats/go-multihash" +) + +var ErrPossiblyInsecureHashFunction = fmt.Errorf("potentially insecure hash functions not allowed") +var ErrBelowMinimumHashLength = fmt.Errorf("hashes must be at least %d bytes long", minimumHashLength) +var ErrAboveMaximumHashLength = fmt.Errorf("hashes must be at most %d bytes long", maximumHashLength) + +const minimumHashLength = 20 +const maximumHashLength = 128 + +// ValidateCid validates multihash allowance behind given CID. +func ValidateCid(allowlist Allowlist, c cid.Cid) error { + pref := c.Prefix() + if !allowlist.IsAllowed(pref.MhType) { + return ErrPossiblyInsecureHashFunction + } + + if pref.MhType != mh.IDENTITY && pref.MhLength < minimumHashLength { + return ErrBelowMinimumHashLength + } + + if pref.MhType != mh.IDENTITY && pref.MhLength > maximumHashLength { + return ErrAboveMaximumHashLength + } + + return nil +} diff --git a/verifcid/validate.go b/verifcid/validate.go deleted file mode 100644 index 7b27debc9..000000000 --- a/verifcid/validate.go +++ /dev/null @@ -1,69 +0,0 @@ -package verifcid - -import ( - "fmt" - - cid "github.com/ipfs/go-cid" - mh "github.com/multiformats/go-multihash" -) - -var ErrPossiblyInsecureHashFunction = fmt.Errorf("potentially insecure hash functions not allowed") -var ErrBelowMinimumHashLength = fmt.Errorf("hashes must be at least %d bytes long", minimumHashLength) -var ErrAboveMaximumHashLength = fmt.Errorf("hashes must be at most %d bytes long", maximumHashLength) - -const minimumHashLength = 20 -const maximumHashLength = 128 - -var goodset = map[uint64]bool{ - mh.SHA2_256: true, - mh.SHA2_512: true, - mh.SHA3_224: true, - mh.SHA3_256: true, - mh.SHA3_384: true, - mh.SHA3_512: true, - mh.SHAKE_256: true, - mh.DBL_SHA2_256: true, - mh.KECCAK_224: true, - mh.KECCAK_256: true, - mh.KECCAK_384: true, - mh.KECCAK_512: true, - mh.BLAKE3: true, - mh.IDENTITY: true, - - mh.SHA1: true, // not really secure but still useful -} - -func IsGoodHash(code uint64) bool { - good, found := goodset[code] - if good { - return true - } - - if !found { - if code >= mh.BLAKE2B_MIN+19 && code <= mh.BLAKE2B_MAX { - return true - } - if code >= mh.BLAKE2S_MIN+19 && code <= mh.BLAKE2S_MAX { - return true - } - } - - return false -} - -func ValidateCid(c cid.Cid) error { - pref := c.Prefix() - if !IsGoodHash(pref.MhType) { - return ErrPossiblyInsecureHashFunction - } - - if pref.MhType != mh.IDENTITY && pref.MhLength < minimumHashLength { - return ErrBelowMinimumHashLength - } - - if pref.MhType != mh.IDENTITY && pref.MhLength > maximumHashLength { - return ErrAboveMaximumHashLength - } - - return nil -} From dd32d670248f35c680c588c72c6f141ab05dd58c Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 16 Aug 2023 05:57:26 +0200 Subject: [PATCH 015/312] blockservice: use functional option pattern for construction and add Allowlist tests --- CHANGELOG.md | 3 ++ blockservice/blockservice.go | 50 +++++++++++++++++-------------- blockservice/blockservice_test.go | 47 +++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04021016c..8c8369a13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,9 @@ The following emojis are used to highlight certain changes: ### Changed +* 🛠 `blockservice.New` now accepts a variadic of func options following the [Functional + Options pattern](https://www.sohamkamani.com/golang/options-pattern/). + ### Removed ### Fixed diff --git a/blockservice/blockservice.go b/blockservice/blockservice.go index cdcac33cc..37c4b35da 100644 --- a/blockservice/blockservice.go +++ b/blockservice/blockservice.go @@ -80,43 +80,49 @@ type blockService struct { checkFirst bool } -// New creates a BlockService with given datastore instance. -func New(bs blockstore.Blockstore, exchange exchange.Interface) BlockService { - if exchange == nil { - logger.Debug("blockservice running in local (offline) mode.") +type Option func(*blockService) + +// WriteThrough disable cache checks for writes and make them go straight to +// the blockstore. +func WriteThrough() Option { + return func(bs *blockService) { + bs.checkFirst = false } +} - return &blockService{ - allowlist: verifcid.DefaultAllowlist, - blockstore: bs, - exchange: exchange, - checkFirst: true, +// WithAllowlist sets a custom [verifcid.Allowlist] which will be used +func WithAllowlist(allowlist verifcid.Allowlist) Option { + return func(bs *blockService) { + bs.allowlist = allowlist } } -// NewWriteThrough creates a BlockService that guarantees writes will go -// through to the blockstore and are not skipped by cache checks. -func NewWriteThrough(bs blockstore.Blockstore, exchange exchange.Interface) BlockService { +// New creates a BlockService with given datastore instance. +func New(bs blockstore.Blockstore, exchange exchange.Interface, opts ...Option) BlockService { if exchange == nil { logger.Debug("blockservice running in local (offline) mode.") } - return &blockService{ + service := &blockService{ allowlist: verifcid.DefaultAllowlist, blockstore: bs, exchange: exchange, - checkFirst: false, + checkFirst: true, } -} -// NewWithAllowList creates a BlockService with customized multihash Allowlist. -func NewWithAllowList(bs blockstore.Blockstore, exchange exchange.Interface, allowlist verifcid.Allowlist) BlockService { - return &blockService{ - allowlist: allowlist, - blockstore: bs, - exchange: exchange, - checkFirst: true, + for _, opt := range opts { + opt(service) } + + return service +} + +// NewWriteThrough creates a BlockService that guarantees writes will go +// through to the blockstore and are not skipped by cache checks. +// +// Deprecated: Use [New] with the [WriteThrough] option. +func NewWriteThrough(bs blockstore.Blockstore, exchange exchange.Interface) BlockService { + return New(bs, exchange, WriteThrough()) } // Blockstore returns the blockstore behind this blockservice. diff --git a/blockservice/blockservice_test.go b/blockservice/blockservice_test.go index 14396c8a1..e36058040 100644 --- a/blockservice/blockservice_test.go +++ b/blockservice/blockservice_test.go @@ -7,15 +7,20 @@ import ( blockstore "github.com/ipfs/boxo/blockstore" exchange "github.com/ipfs/boxo/exchange" offline "github.com/ipfs/boxo/exchange/offline" + "github.com/ipfs/boxo/verifcid" blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" ds "github.com/ipfs/go-datastore" dssync "github.com/ipfs/go-datastore/sync" butil "github.com/ipfs/go-ipfs-blocksutil" ipld "github.com/ipfs/go-ipld-format" + "github.com/multiformats/go-multihash" + "github.com/stretchr/testify/assert" ) func TestWriteThroughWorks(t *testing.T) { + t.Parallel() + bstore := &PutCountingBlockstore{ blockstore.NewBlockstore(dssync.MutexWrap(ds.NewMapDatastore())), 0, @@ -46,6 +51,8 @@ func TestWriteThroughWorks(t *testing.T) { } func TestExchangeWrite(t *testing.T) { + t.Parallel() + bstore := &PutCountingBlockstore{ blockstore.NewBlockstore(dssync.MutexWrap(ds.NewMapDatastore())), 0, @@ -117,6 +124,8 @@ func TestExchangeWrite(t *testing.T) { } func TestLazySessionInitialization(t *testing.T) { + t.Parallel() + ctx := context.Background() ctx, cancel := context.WithCancel(ctx) defer cancel() @@ -215,6 +224,8 @@ func (fe *fakeSessionExchange) NewSession(ctx context.Context) exchange.Fetcher } func TestNilExchange(t *testing.T) { + t.Parallel() + ctx := context.Background() ctx, cancel := context.WithCancel(ctx) defer cancel() @@ -241,3 +252,39 @@ func TestNilExchange(t *testing.T) { t.Fatal("got the wrong block") } } + +func TestAllowlist(t *testing.T) { + t.Parallel() + a := assert.New(t) + + ctx := context.Background() + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + bgen := butil.NewBlockGenerator() + block := bgen.Next() + + data := []byte("this is some blake3 block") + mh, err := multihash.Sum(data, multihash.BLAKE3, -1) + a.NoError(err) + blake3 := cid.NewCidV1(cid.Raw, mh) + + bs := blockstore.NewBlockstore(dssync.MutexWrap(ds.NewMapDatastore())) + a.NoError(bs.Put(ctx, block)) + b, err := blocks.NewBlockWithCid(data, blake3) + a.NoError(err) + a.NoError(bs.Put(ctx, b)) + + check := func(getBlock func(context.Context, cid.Cid) (blocks.Block, error)) { + _, err := getBlock(ctx, block.Cid()) + a.Error(err) + a.ErrorIs(err, verifcid.ErrPossiblyInsecureHashFunction) + + _, err = getBlock(ctx, blake3) + a.NoError(err) + } + + blockservice := New(bs, nil, WithAllowlist(verifcid.NewAllowlist(map[uint64]bool{multihash.BLAKE3: true}))) + check(blockservice.GetBlock) + check(NewSession(ctx, blockservice).GetBlock) +} From 1d2f5e511e9fb0e1ff4c2b93aea421fc2091e3f5 Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Thu, 17 Aug 2023 16:18:17 +1000 Subject: [PATCH 016/312] feat(connecteventmanager): block Connected() until accepted (#435) * feat(connecteventmanager): block Connected() until accepted Ref: https://github.com/ipfs/boxo/issues/432 Minimal attempt at solving #432 * fix(connecteventmanager): less complex channel signalling * fix(connecteventmanager): handle change queue edge cases and closure * fix(connecteventmanager): add test to confirm sync Connected() call flow --- CHANGELOG.md | 1 + bitswap/network/connecteventmanager.go | 102 +++++++++++++------- bitswap/network/connecteventmanager_test.go | 54 ++++++++++- 3 files changed, 121 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c8369a13..fcbd2769b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,6 +72,7 @@ The following emojis are used to highlight certain changes: - Removed mentions of unused ARC algorithm ([#336](https://github.com/ipfs/boxo/issues/366#issuecomment-1597253540)) - Handle `_redirects` file when `If-None-Match` header is present ([#412](https://github.com/ipfs/boxo/pull/412)) +- Address a Bitswap findpeers / connect race condition that can prevent peer communication ([#435](https://github.com/ipfs/boxo/issues/435)) ### Security diff --git a/bitswap/network/connecteventmanager.go b/bitswap/network/connecteventmanager.go index 88337fce3..e38598812 100644 --- a/bitswap/network/connecteventmanager.go +++ b/bitswap/network/connecteventmanager.go @@ -25,16 +25,25 @@ type connectEventManager struct { cond sync.Cond peers map[peer.ID]*peerState - changeQueue []peer.ID + changeQueue []change stop bool done chan struct{} } +type change struct { + pid peer.ID + handled chan struct{} +} + type peerState struct { newState, curState state pending bool } +type waitFn func() + +func waitNoop() {} + func newConnectEventManager(connListeners ...ConnectionListener) *connectEventManager { evtManager := &connectEventManager{ connListeners: connListeners, @@ -66,7 +75,16 @@ func (c *connectEventManager) getState(p peer.ID) state { } } -func (c *connectEventManager) setState(p peer.ID, newState state) { +func (c *connectEventManager) makeWaitFunc(handled chan struct{}) waitFn { + return func() { + select { + case <-handled: + case <-c.done: + } + } +} + +func (c *connectEventManager) setState(p peer.ID, newState state) waitFn { state, ok := c.peers[p] if !ok { state = new(peerState) @@ -75,9 +93,20 @@ func (c *connectEventManager) setState(p peer.ID, newState state) { state.newState = newState if !state.pending && state.newState != state.curState { state.pending = true - c.changeQueue = append(c.changeQueue, p) + change := change{p, make(chan struct{})} + c.changeQueue = append(c.changeQueue, change) c.cond.Broadcast() + return c.makeWaitFunc(change.handled) + } else if state.pending { + // Find the change in the queue and return a wait function for it + for _, change := range c.changeQueue { + if change.pid == p { + return c.makeWaitFunc(change.handled) + } + } + log.Error("a peer was marked as change pending but not found in the change queue") } + return waitNoop } // Waits for a change to be enqueued, or for the event manager to be stopped. Returns false if the @@ -95,67 +124,70 @@ func (c *connectEventManager) worker() { defer close(c.done) for c.waitChange() { - pid := c.changeQueue[0] - c.changeQueue[0] = peer.ID("") // free the peer ID (slicing won't do that) + pch := c.changeQueue[0] + c.changeQueue[0] = change{} // free the resources (slicing won't do that) c.changeQueue = c.changeQueue[1:] - state, ok := c.peers[pid] + state, ok := c.peers[pch.pid] // If we've disconnected and forgotten, continue. if !ok { // This shouldn't be possible because _this_ thread is responsible for // removing peers from this map, and we shouldn't get duplicate entries in // the change queue. log.Error("a change was enqueued for a peer we're not tracking") + close(pch.handled) continue } - // Record the fact that this "state" is no longer in the queue. - state.pending = false - - // Then, if there's nothing to do, continue. - if state.curState == state.newState { - continue - } - - // Or record the state update, then apply it. - oldState := state.curState - state.curState = state.newState - - switch state.newState { - case stateDisconnected: - delete(c.peers, pid) - fallthrough - case stateUnresponsive: - // Only trigger a disconnect event if the peer was responsive. - // We could be transitioning from unresponsive to disconnected. - if oldState == stateResponsive { + // Is there anything to do? + if state.curState != state.newState { + // Record the state update, then apply it. + oldState := state.curState + state.curState = state.newState + + switch state.newState { + case stateDisconnected: + delete(c.peers, pch.pid) + fallthrough + case stateUnresponsive: + // Only trigger a disconnect event if the peer was responsive. + // We could be transitioning from unresponsive to disconnected. + if oldState == stateResponsive { + c.lk.Unlock() + for _, v := range c.connListeners { + v.PeerDisconnected(pch.pid) + } + c.lk.Lock() + } + case stateResponsive: c.lk.Unlock() for _, v := range c.connListeners { - v.PeerDisconnected(pid) + v.PeerConnected(pch.pid) } c.lk.Lock() } - case stateResponsive: - c.lk.Unlock() - for _, v := range c.connListeners { - v.PeerConnected(pid) - } - c.lk.Lock() } + + // Record the fact that this "state" is no longer in the queue. + state.pending = false + // Signal that we've handled the state change + close(pch.handled) } } // Called whenever we receive a new connection. May be called many times. func (c *connectEventManager) Connected(p peer.ID) { c.lk.Lock() - defer c.lk.Unlock() // !responsive -> responsive if c.getState(p) == stateResponsive { + c.lk.Unlock() return } - c.setState(p, stateResponsive) + wait := c.setState(p, stateResponsive) + c.lk.Unlock() + wait() } // Called when we drop the final connection to a peer. diff --git a/bitswap/network/connecteventmanager_test.go b/bitswap/network/connecteventmanager_test.go index e3904ee55..5ce4e690c 100644 --- a/bitswap/network/connecteventmanager_test.go +++ b/bitswap/network/connecteventmanager_test.go @@ -18,7 +18,8 @@ type mockConnEvent struct { type mockConnListener struct { sync.Mutex - events []mockConnEvent + events []mockConnEvent + peerConnectedCb func(p peer.ID) } func newMockConnListener() *mockConnListener { @@ -29,6 +30,9 @@ func (cl *mockConnListener) PeerConnected(p peer.ID) { cl.Lock() defer cl.Unlock() cl.events = append(cl.events, mockConnEvent{connected: true, peer: p}) + if cl.peerConnectedCb != nil { + cl.peerConnectedCb(p) + } } func (cl *mockConnListener) PeerDisconnected(p peer.ID) { @@ -173,3 +177,51 @@ func TestConnectEventManagerDisconnectAfterMarkUnresponsive(t *testing.T) { require.Empty(t, cem.peers) // all disconnected require.Equal(t, expectedEvents, connListener.events) } + +func TestConnectEventManagerConnectFlowSynchronous(t *testing.T) { + connListener := newMockConnListener() + actionsCh := make(chan string) + connListener.peerConnectedCb = func(p peer.ID) { + actionsCh <- "PeerConnected:" + p.String() + time.Sleep(time.Millisecond * 50) + } + + peers := testutil.GeneratePeers(2) + cem := newConnectEventManager(connListener) + cem.Start() + t.Cleanup(cem.Stop) + + go func() { + actionsCh <- "Connected:" + peers[0].String() + cem.Connected(peers[0]) + actionsCh <- "Done:" + peers[0].String() + actionsCh <- "Connected:" + peers[1].String() + cem.Connected(peers[1]) + actionsCh <- "Done:" + peers[1].String() + close(actionsCh) + }() + + // We expect Done to be sent _after_ PeerConnected, which demonstrates the + // call to Connected() blocks until PeerConnected() returns. + gotActions := make([]string, 0, 3) + for event := range actionsCh { + gotActions = append(gotActions, event) + } + expectedActions := []string{ + "Connected:" + peers[0].String(), + "PeerConnected:" + peers[0].String(), + "Done:" + peers[0].String(), + "Connected:" + peers[1].String(), + "PeerConnected:" + peers[1].String(), + "Done:" + peers[1].String(), + } + require.Equal(t, expectedActions, gotActions) + + // Flush the event queue. + wait(t, cem) + expectedEvents := []mockConnEvent{ + {peer: peers[0], connected: true}, + {peer: peers[1], connected: true}, + } + require.Equal(t, expectedEvents, connListener.events) +} From 59a2bca3f0924d5a9cc61bbb6c33dbd483f4a0f4 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 17 Aug 2023 08:26:14 +0200 Subject: [PATCH 017/312] changelog: put the 435 fix in the right version --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fcbd2769b..4489b13fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,8 @@ The following emojis are used to highlight certain changes: ### Fixed +- Address a Bitswap findpeers / connect race condition that can prevent peer communication ([#435](https://github.com/ipfs/boxo/issues/435)) + ### Security ## [v0.11.0] @@ -72,7 +74,6 @@ The following emojis are used to highlight certain changes: - Removed mentions of unused ARC algorithm ([#336](https://github.com/ipfs/boxo/issues/366#issuecomment-1597253540)) - Handle `_redirects` file when `If-None-Match` header is present ([#412](https://github.com/ipfs/boxo/pull/412)) -- Address a Bitswap findpeers / connect race condition that can prevent peer communication ([#435](https://github.com/ipfs/boxo/issues/435)) ### Security From 7ec68c5e5adfb13e52f93c20e7c5aadf4860a871 Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Thu, 17 Aug 2023 16:29:37 +1000 Subject: [PATCH 018/312] fix(connecteventmanager): clean up tests for new synchronous flow --- bitswap/network/connecteventmanager_test.go | 22 ++++++--------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/bitswap/network/connecteventmanager_test.go b/bitswap/network/connecteventmanager_test.go index 5ce4e690c..c961a5a97 100644 --- a/bitswap/network/connecteventmanager_test.go +++ b/bitswap/network/connecteventmanager_test.go @@ -6,7 +6,6 @@ import ( "time" "github.com/ipfs/boxo/bitswap/internal/testutil" - "github.com/ipfs/boxo/internal/test" "github.com/libp2p/go-libp2p/core/peer" "github.com/stretchr/testify/require" ) @@ -50,8 +49,6 @@ func wait(t *testing.T, c *connectEventManager) { } func TestConnectEventManagerConnectDisconnect(t *testing.T) { - test.Flaky(t) - connListener := newMockConnListener() peers := testutil.GeneratePeers(2) cem := newConnectEventManager(connListener) @@ -68,31 +65,26 @@ func TestConnectEventManagerConnectDisconnect(t *testing.T) { connected: true, }) - // Flush the event queue. - wait(t, cem) require.Equal(t, expectedEvents, connListener.events) - // Block up the event loop. - connListener.Lock() cem.Connected(peers[1]) expectedEvents = append(expectedEvents, mockConnEvent{ peer: peers[1], connected: true, }) + require.Equal(t, expectedEvents, connListener.events) - // We don't expect this to show up. cem.Disconnected(peers[0]) - cem.Connected(peers[0]) - - connListener.Unlock() - + expectedEvents = append(expectedEvents, mockConnEvent{ + peer: peers[0], + connected: false, + }) + // Flush the event queue. wait(t, cem) require.Equal(t, expectedEvents, connListener.events) } func TestConnectEventManagerMarkUnresponsive(t *testing.T) { - test.Flaky(t) - connListener := newMockConnListener() p := testutil.GeneratePeers(1)[0] cem := newConnectEventManager(connListener) @@ -142,8 +134,6 @@ func TestConnectEventManagerMarkUnresponsive(t *testing.T) { } func TestConnectEventManagerDisconnectAfterMarkUnresponsive(t *testing.T) { - test.Flaky(t) - connListener := newMockConnListener() p := testutil.GeneratePeers(1)[0] cem := newConnectEventManager(connListener) From 654231b2bda38b130d32a63724a2205389e6354f Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Fri, 18 Aug 2023 02:27:47 -0400 Subject: [PATCH 019/312] fix(gw): IPIP-402 CARs return useful blocks on not found errors (#440) Co-authored-by: Henrique Dias --- CHANGELOG.md | 2 ++ gateway/blocks_backend.go | 36 ++++++++++++++++++++++++++++++++++++ gateway/errors.go | 7 ++----- gateway/gateway_test.go | 2 +- 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4489b13fd..c47ac1f10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,8 @@ The following emojis are used to highlight certain changes: ### Fixed - Address a Bitswap findpeers / connect race condition that can prevent peer communication ([#435](https://github.com/ipfs/boxo/issues/435)) +- HTTP Gateway API: Not having a block will result in a 5xx error rather than 404 +- HTTP Gateway API: CAR requests will return 200s and a CAR file proving a requested path does not exist rather than returning an error ### Security diff --git a/gateway/blocks_backend.go b/gateway/blocks_backend.go index 01ca49fec..82e7e1a3b 100644 --- a/gateway/blocks_backend.go +++ b/gateway/blocks_backend.go @@ -232,9 +232,45 @@ func (bb *BlocksBackend) Head(ctx context.Context, path ImmutablePath) (ContentP return md, fileNode, nil } +// emptyRoot is a CAR root with the empty identity CID. CAR files are recommended +// to always include a CID in their root, even if it's just the empty CID. +// https://ipld.io/specs/transport/car/carv1/#number-of-roots +var emptyRoot = []cid.Cid{cid.MustParse("bafkqaaa")} + func (bb *BlocksBackend) GetCAR(ctx context.Context, p ImmutablePath, params CarParams) (ContentPathMetadata, io.ReadCloser, error) { pathMetadata, err := bb.ResolvePath(ctx, p) if err != nil { + rootCid, err := cid.Decode(strings.Split(p.String(), "/")[2]) + if err != nil { + return ContentPathMetadata{}, nil, err + } + + var buf bytes.Buffer + cw, err := storage.NewWritable(&buf, emptyRoot, car.WriteAsCarV1(true)) + if err != nil { + return ContentPathMetadata{}, nil, err + } + + blockGetter := merkledag.NewDAGService(bb.blockService).Session(ctx) + + blockGetter = &nodeGetterToCarExporer{ + ng: blockGetter, + cw: cw, + } + + // Setup the UnixFS resolver. + f := newNodeGetterFetcherSingleUseFactory(ctx, blockGetter) + pathResolver := resolver.NewBasicResolver(f) + ip := ipfspath.FromString(p.String()) + _, _, err = pathResolver.ResolveToLastNode(ctx, ip) + + if isErrNotFound(err) { + return ContentPathMetadata{ + PathSegmentRoots: nil, + LastSegment: ifacepath.NewResolvedPath(ip, rootCid, rootCid, ""), + ContentType: "", + }, io.NopCloser(&buf), nil + } return ContentPathMetadata{}, nil, err } diff --git a/gateway/errors.go b/gateway/errors.go index e9671438e..17a22ca62 100644 --- a/gateway/errors.go +++ b/gateway/errors.go @@ -12,7 +12,6 @@ import ( "github.com/ipfs/boxo/gateway/assets" "github.com/ipfs/boxo/path/resolver" "github.com/ipfs/go-cid" - ipld "github.com/ipfs/go-ipld-format" "github.com/ipld/go-ipld-prime/datamodel" ) @@ -177,11 +176,9 @@ func webError(w http.ResponseWriter, r *http.Request, c *Config, err error, defa } } +// isErrNotFound returns true for IPLD errors that should return 4xx errors (e.g. the path doesn't exist, the data is +// the wrong type, etc.), rather than issues with just finding and retrieving the data. func isErrNotFound(err error) bool { - if ipld.IsNotFound(err) { - return true - } - // Checks if err is of a type that does not implement the .Is interface and // cannot be directly compared to. Therefore, errors.Is cannot be used. for { diff --git a/gateway/gateway_test.go b/gateway/gateway_test.go index 7fae55f3e..1c988ac9c 100644 --- a/gateway/gateway_test.go +++ b/gateway/gateway_test.go @@ -763,7 +763,7 @@ func TestErrorBubblingFromBackend(t *testing.T) { }) } - testError("404 Not Found from IPLD", &ipld.ErrNotFound{}, http.StatusNotFound) + testError("500 Not Found from IPLD", &ipld.ErrNotFound{}, http.StatusInternalServerError) testError("404 Not Found from path resolver", resolver.ErrNoLink{}, http.StatusNotFound) testError("502 Bad Gateway", ErrBadGateway, http.StatusBadGateway) testError("504 Gateway Timeout", ErrGatewayTimeout, http.StatusGatewayTimeout) From aa73ad5566b178a0f03a903f5ebe62773058841d Mon Sep 17 00:00:00 2001 From: Marin Kirkov Date: Fri, 18 Aug 2023 18:57:03 +0300 Subject: [PATCH 020/312] files: add wasm oses option for filewriter flags (#411) --- files/filewriter_unix.go | 2 +- files/filewriter_unix_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/files/filewriter_unix.go b/files/filewriter_unix.go index 98d040018..d70b9f4ff 100644 --- a/files/filewriter_unix.go +++ b/files/filewriter_unix.go @@ -1,4 +1,4 @@ -//go:build darwin || linux || netbsd || openbsd || freebsd || dragonfly +//go:build darwin || linux || netbsd || openbsd || freebsd || dragonfly || js || wasip1 package files diff --git a/files/filewriter_unix_test.go b/files/filewriter_unix_test.go index ffc33ce51..9f63fe0fe 100644 --- a/files/filewriter_unix_test.go +++ b/files/filewriter_unix_test.go @@ -1,4 +1,4 @@ -//go:build darwin || linux || netbsd || openbsd +//go:build darwin || linux || netbsd || openbsd || freebsd || dragonfly || js || wasip1 package files From c5a805eed56de5df9c8a220a4ce72b7bc3a0ae38 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Mon, 21 Aug 2023 10:01:00 +0200 Subject: [PATCH 021/312] style: run gofumpt --- bitswap/benchmarks_test.go | 48 ++++++++++--------- bitswap/bitswap.go | 8 ++-- bitswap/bitswap_test.go | 2 +- bitswap/client/client.go | 3 +- bitswap/client/internal/getter/getter.go | 7 +-- .../messagequeue/donthavetimeoutmgr.go | 5 +- .../internal/messagequeue/messagequeue.go | 10 ++-- .../messagequeue/messagequeue_test.go | 11 +++-- .../internal/notifications/notifications.go | 1 - .../notifications/notifications_test.go | 1 - .../internal/peermanager/peermanager_test.go | 7 ++- .../peermanager/peerwantmanager_test.go | 4 ++ .../providerquerymanager_test.go | 2 - bitswap/client/internal/session/session.go | 10 ++-- .../client/internal/session/session_test.go | 2 - .../internal/session/sessionwantsender.go | 10 ++-- .../session/sessionwantsender_test.go | 3 +- .../internal/sessionmanager/sessionmanager.go | 7 +-- .../sessionmanager/sessionmanager_test.go | 11 +++-- bitswap/client/wantlist/wantlist_test.go | 2 - bitswap/internal/testutil/testutil.go | 6 ++- bitswap/message/message_test.go | 3 -- bitswap/message/pb/cid_test.go | 2 +- bitswap/message/pb/message.pb.go | 46 ++++++++++++++++-- bitswap/network/ipfs_impl.go | 17 +++---- bitswap/network/ipfs_impl_test.go | 3 +- bitswap/server/internal/decision/engine.go | 1 - .../server/internal/decision/engine_test.go | 2 +- bitswap/server/server.go | 9 ++-- .../internet_latency_delay_generator.go | 3 +- bitswap/testnet/network_test.go | 12 +++-- bitswap/testnet/virtual.go | 8 ++-- blockservice/test/blocks_test.go | 2 +- blockstore/blockstore.go | 1 - blockstore/blockstore_test.go | 4 +- blockstore/bloom_cache.go | 6 ++- blockstore/bloom_cache_test.go | 1 + blockstore/caching.go | 3 +- blockstore/idstore.go | 8 ++-- blockstore/twoqueue_cache.go | 12 +++-- blockstore/twoqueue_cache_test.go | 4 +- chunker/buzhash.go | 3 +- chunker/parse_test.go | 1 - chunker/splitting_test.go | 1 - cmd/deprecator/main.go | 1 - coreiface/options/block.go | 7 +-- coreiface/options/dht.go | 6 ++- coreiface/options/key.go | 6 ++- coreiface/options/name.go | 6 ++- coreiface/options/object.go | 8 ++-- coreiface/options/pubsub.go | 6 ++- coreiface/options/unixfs.go | 6 ++- coreiface/tests/dag.go | 16 +++---- coreiface/tests/name.go | 2 +- coreiface/tests/object.go | 2 +- coreiface/tests/unixfs.go | 8 ++-- examples/unixfs-file-cid/main_test.go | 3 +- fetcher/impl/blockservice/fetcher.go | 4 +- fetcher/impl/blockservice/fetcher_test.go | 1 - files/file_test.go | 1 + files/filewriter.go | 8 ++-- files/filewriter_unix.go | 2 +- files/filewriter_windows.go | 2 +- files/filewriter_windows_test.go | 6 ++- files/filter_test.go | 2 +- files/readerfile.go | 6 ++- files/serialfile.go | 6 ++- files/serialfile_test.go | 4 +- files/slicedirectory.go | 6 ++- files/tarwriter.go | 10 ++-- files/webfile.go | 6 ++- filestore/filestore.go | 6 ++- filestore/fsrefstore.go | 18 ++++--- filestore/pb/dataobj.pb.go | 17 +++++-- gateway/assets/assets.go | 3 +- gateway/blocks_backend.go | 6 ++- gateway/gateway_test.go | 1 - gateway/handler_car.go | 1 - gateway/hostname.go | 1 - ipld/merkledag/coding.go | 1 + ipld/merkledag/dagutils/diffenum.go | 2 +- ipld/merkledag/dagutils/diffenum_test.go | 1 - ipld/merkledag/merkledag.go | 11 +++-- ipld/merkledag/merkledag_test.go | 3 -- ipld/merkledag/node.go | 6 ++- ipld/merkledag/pb/compat_test.go | 18 +++---- ipld/merkledag/pb/merkledag.pb.go | 42 ++++++++++++++-- ipld/merkledag/pb/merkledagpb_test.go | 17 +++++-- ipld/merkledag/pb/stability_test.go | 1 - ipld/merkledag/traverse/traverse.go | 2 - ipld/unixfs/file/unixfile.go | 6 ++- ipld/unixfs/hamt/hamt_test.go | 3 +- .../unixfs/importer/balanced/balanced_test.go | 1 - ipld/unixfs/importer/helpers/dagbuilder.go | 1 - ipld/unixfs/importer/helpers/helpers.go | 6 ++- ipld/unixfs/importer/trickle/trickle_test.go | 1 - ipld/unixfs/io/dagreader.go | 4 -- ipld/unixfs/io/dagreader_test.go | 2 - ipld/unixfs/io/directory.go | 1 - ipld/unixfs/mod/dagmodifier_test.go | 19 ++++++-- ipld/unixfs/pb/unixfs.pb.go | 21 ++++++-- ipld/unixfs/unixfs.go | 3 +- ipld/unixfs/unixfs_test.go | 1 - ipns/pb/record.pb.go | 20 ++++---- keystore/keystore.go | 7 ++- keystore/keystore_test.go | 5 +- mfs/dir.go | 8 ++-- mfs/mfs_test.go | 4 -- mfs/root.go | 8 ++-- namesys/interface.go | 4 +- namesys/namesys.go | 1 - path/path.go | 3 +- path/resolver/resolver_test.go | 1 + pinning/remote/client/client.go | 6 ++- pinning/remote/client/openapi/client.go | 4 +- pinning/remote/client/openapi/response.go | 2 - provider/internal/queue/queue.go | 1 - provider/provider.go | 1 - provider/reprovider.go | 6 ++- routing/http/client/client_test.go | 1 + routing/http/client/transport_test.go | 1 - .../http/contentrouter/contentrouter_test.go | 3 +- routing/http/server/server.go | 7 +-- routing/http/server/server_test.go | 7 ++- routing/http/types/iter/json_test.go | 1 - routing/http/types/provider_bitswap.go | 6 ++- routing/http/types/provider_unknown.go | 8 ++-- routing/http/types/time.go | 1 + routing/mock/centralized_test.go | 7 ++- routing/none/none_client.go | 3 +- tar/extractor.go | 10 ++-- tar/extractor_test.go | 23 +++++---- tar/sanitize_windows.go | 4 +- tracing/file_exporter.go | 2 +- verifcid/cid.go | 14 ++++-- 135 files changed, 522 insertions(+), 336 deletions(-) diff --git a/bitswap/benchmarks_test.go b/bitswap/benchmarks_test.go index 0878614c5..80eb373ab 100644 --- a/bitswap/benchmarks_test.go +++ b/bitswap/benchmarks_test.go @@ -114,7 +114,7 @@ func BenchmarkFixedDelay(b *testing.B) { } out, _ := json.MarshalIndent(benchmarkLog, "", " ") - _ = os.WriteFile("tmp/benchmark.json", out, 0666) + _ = os.WriteFile("tmp/benchmark.json", out, 0o666) printResults(benchmarkLog) } @@ -182,28 +182,30 @@ func BenchmarkFetchFromOldBitswap(b *testing.B) { } out, _ := json.MarshalIndent(benchmarkLog, "", " ") - _ = os.WriteFile("tmp/benchmark.json", out, 0666) + _ = os.WriteFile("tmp/benchmark.json", out, 0o666) printResults(benchmarkLog) } -const datacenterSpeed = 5 * time.Millisecond -const fastSpeed = 60 * time.Millisecond -const mediumSpeed = 200 * time.Millisecond -const slowSpeed = 800 * time.Millisecond -const superSlowSpeed = 4000 * time.Millisecond -const datacenterDistribution = 3 * time.Millisecond -const distribution = 20 * time.Millisecond -const datacenterBandwidth = 125000000.0 -const datacenterBandwidthDeviation = 3000000.0 -const fastBandwidth = 1250000.0 -const fastBandwidthDeviation = 300000.0 -const mediumBandwidth = 500000.0 -const mediumBandwidthDeviation = 80000.0 -const slowBandwidth = 100000.0 -const slowBandwidthDeviation = 16500.0 -const rootBlockSize = 800 -const stdBlockSize = 8000 -const largeBlockSize = int64(256 * 1024) +const ( + datacenterSpeed = 5 * time.Millisecond + fastSpeed = 60 * time.Millisecond + mediumSpeed = 200 * time.Millisecond + slowSpeed = 800 * time.Millisecond + superSlowSpeed = 4000 * time.Millisecond + datacenterDistribution = 3 * time.Millisecond + distribution = 20 * time.Millisecond + datacenterBandwidth = 125000000.0 + datacenterBandwidthDeviation = 3000000.0 + fastBandwidth = 1250000.0 + fastBandwidthDeviation = 300000.0 + mediumBandwidth = 500000.0 + mediumBandwidthDeviation = 80000.0 + slowBandwidth = 100000.0 + slowBandwidthDeviation = 16500.0 + rootBlockSize = 800 + stdBlockSize = 8000 + largeBlockSize = int64(256 * 1024) +) func BenchmarkRealWorld(b *testing.B) { benchmarkLog = nil @@ -240,7 +242,7 @@ func BenchmarkRealWorld(b *testing.B) { subtestDistributeAndFetchRateLimited(b, 300, 200, slowNetworkDelay, slowBandwidthGenerator, stdBlockSize, bstoreLatency, allToAll, batchFetchAll) }) out, _ := json.MarshalIndent(benchmarkLog, "", " ") - _ = os.WriteFile("tmp/rw-benchmark.json", out, 0666) + _ = os.WriteFile("tmp/rw-benchmark.json", out, 0o666) printResults(benchmarkLog) } @@ -263,7 +265,7 @@ func BenchmarkDatacenter(b *testing.B) { subtestDistributeAndFetchRateLimited(b, 3, 100, datacenterNetworkDelay, datacenterBandwidthGenerator, largeBlockSize, bstoreLatency, allToAll, unixfsFileFetch) }) out, _ := json.MarshalIndent(benchmarkLog, "", " ") - _ = os.WriteFile("tmp/rb-benchmark.json", out, 0666) + _ = os.WriteFile("tmp/rb-benchmark.json", out, 0o666) printResults(benchmarkLog) } @@ -304,7 +306,7 @@ func BenchmarkDatacenterMultiLeechMultiSeed(b *testing.B) { }) out, _ := json.MarshalIndent(benchmarkLog, "", " ") - _ = os.WriteFile("tmp/rb-benchmark.json", out, 0666) + _ = os.WriteFile("tmp/rb-benchmark.json", out, 0o666) printResults(benchmarkLog) } diff --git a/bitswap/bitswap.go b/bitswap/bitswap.go index 3863538ee..393ab96ad 100644 --- a/bitswap/bitswap.go +++ b/bitswap/bitswap.go @@ -44,9 +44,11 @@ type bitswap interface { WantlistForPeer(p peer.ID) []cid.Cid } -var _ exchange.SessionExchange = (*Bitswap)(nil) -var _ bitswap = (*Bitswap)(nil) -var HasBlockBufferSize = defaults.HasBlockBufferSize +var ( + _ exchange.SessionExchange = (*Bitswap)(nil) + _ bitswap = (*Bitswap)(nil) + HasBlockBufferSize = defaults.HasBlockBufferSize +) type Bitswap struct { *client.Client diff --git a/bitswap/bitswap_test.go b/bitswap/bitswap_test.go index 7d478ca73..02bd57947 100644 --- a/bitswap/bitswap_test.go +++ b/bitswap/bitswap_test.go @@ -390,7 +390,6 @@ func TestSendToWantingPeer(t *testing.T) { if !blkrecvd.Cid().Equals(alpha.Cid()) { t.Fatal("Wrong block!") } - } func TestEmptyKey(t *testing.T) { @@ -828,6 +827,7 @@ func (tsl *testingScoreLedger) Start(scorePeer server.ScorePeerFunc) { tsl.scorePeer = scorePeer close(tsl.started) } + func (tsl *testingScoreLedger) Stop() { close(tsl.closed) } diff --git a/bitswap/client/client.go b/bitswap/client/client.go index d29eb6faf..854d030d1 100644 --- a/bitswap/client/client.go +++ b/bitswap/client/client.go @@ -132,7 +132,8 @@ func New(parent context.Context, network bsnet.BitSwapNetwork, bstore blockstore notif notifications.PubSub, provSearchDelay time.Duration, rebroadcastDelay delay.D, - self peer.ID) bssm.Session { + self peer.ID, + ) bssm.Session { return bssession.New(sessctx, sessmgr, id, spm, pqm, sim, pm, bpm, notif, provSearchDelay, rebroadcastDelay, self) } sessionPeerManagerFactory := func(ctx context.Context, id uint64) bssession.SessionPeerManager { diff --git a/bitswap/client/internal/getter/getter.go b/bitswap/client/internal/getter/getter.go index f4d0bbe1f..713394b08 100644 --- a/bitswap/client/internal/getter/getter.go +++ b/bitswap/client/internal/getter/getter.go @@ -68,7 +68,8 @@ type WantFunc func(context.Context, []cid.Cid) // blocks, a want function, and a close function, and returns a channel of // incoming blocks. func AsyncGetBlocks(ctx context.Context, sessctx context.Context, keys []cid.Cid, notif notifications.PubSub, - want WantFunc, cwants func([]cid.Cid)) (<-chan blocks.Block, error) { + want WantFunc, cwants func([]cid.Cid), +) (<-chan blocks.Block, error) { ctx, span := internal.StartSpan(ctx, "Getter.AsyncGetBlocks") defer span.End() @@ -99,8 +100,8 @@ func AsyncGetBlocks(ctx context.Context, sessctx context.Context, keys []cid.Cid // If the context is cancelled or the incoming channel closes, calls cfun with // any keys corresponding to blocks that were never received. func handleIncoming(ctx context.Context, sessctx context.Context, remaining *cid.Set, - in <-chan blocks.Block, out chan blocks.Block, cfun func([]cid.Cid)) { - + in <-chan blocks.Block, out chan blocks.Block, cfun func([]cid.Cid), +) { ctx, cancel := context.WithCancel(ctx) // Clean up before exiting this function, and call the cancel function on diff --git a/bitswap/client/internal/messagequeue/donthavetimeoutmgr.go b/bitswap/client/internal/messagequeue/donthavetimeoutmgr.go index e1b42c421..cdeee68ec 100644 --- a/bitswap/client/internal/messagequeue/donthavetimeoutmgr.go +++ b/bitswap/client/internal/messagequeue/donthavetimeoutmgr.go @@ -107,8 +107,8 @@ func newDontHaveTimeoutMgrWithParams( messageLatencyMultiplier int, maxExpectedWantProcessTime time.Duration, clock clock.Clock, - timeoutsTriggered chan struct{}) *dontHaveTimeoutMgr { - + timeoutsTriggered chan struct{}, +) *dontHaveTimeoutMgr { ctx, shutdown := context.WithCancel(context.Background()) mqp := &dontHaveTimeoutMgr{ clock: clock, @@ -222,7 +222,6 @@ func (dhtm *dontHaveTimeoutMgr) measurePingLatency() { // checkForTimeouts checks pending wants to see if any are over the timeout. // Note: this function should only be called within the lock. func (dhtm *dontHaveTimeoutMgr) checkForTimeouts() { - if len(dhtm.wantQueue) == 0 { return } diff --git a/bitswap/client/internal/messagequeue/messagequeue.go b/bitswap/client/internal/messagequeue/messagequeue.go index 117d46b98..4f90f239b 100644 --- a/bitswap/client/internal/messagequeue/messagequeue.go +++ b/bitswap/client/internal/messagequeue/messagequeue.go @@ -18,8 +18,10 @@ import ( "go.uber.org/zap" ) -var log = logging.Logger("bitswap") -var sflog = log.Desugar() +var ( + log = logging.Logger("bitswap") + sflog = log.Desugar() +) const ( defaultRebroadcastInterval = 30 * time.Second @@ -240,8 +242,8 @@ func newMessageQueue( maxValidLatency time.Duration, dhTimeoutMgr DontHaveTimeoutManager, clock clock.Clock, - events chan messageEvent) *MessageQueue { - + events chan messageEvent, +) *MessageQueue { ctx, cancel := context.WithCancel(ctx) return &MessageQueue{ ctx: ctx, diff --git a/bitswap/client/internal/messagequeue/messagequeue_test.go b/bitswap/client/internal/messagequeue/messagequeue_test.go index 59788f50b..886e60772 100644 --- a/bitswap/client/internal/messagequeue/messagequeue_test.go +++ b/bitswap/client/internal/messagequeue/messagequeue_test.go @@ -61,6 +61,7 @@ func (fp *fakeDontHaveTimeoutMgr) AddPending(ks []cid.Cid) { } fp.ks = s.Keys() } + func (fp *fakeDontHaveTimeoutMgr) CancelPending(ks []cid.Cid) { fp.lk.Lock() defer fp.lk.Unlock() @@ -74,18 +75,21 @@ func (fp *fakeDontHaveTimeoutMgr) CancelPending(ks []cid.Cid) { } fp.ks = s.Keys() } + func (fp *fakeDontHaveTimeoutMgr) UpdateMessageLatency(elapsed time.Duration) { fp.lk.Lock() defer fp.lk.Unlock() fp.latencyUpds = append(fp.latencyUpds, elapsed) } + func (fp *fakeDontHaveTimeoutMgr) latencyUpdates() []time.Duration { fp.lk.Lock() defer fp.lk.Unlock() return fp.latencyUpds } + func (fp *fakeDontHaveTimeoutMgr) pendingCount() int { fp.lk.Lock() defer fp.lk.Unlock() @@ -101,8 +105,8 @@ type fakeMessageSender struct { } func newFakeMessageSender(reset chan<- struct{}, - messagesSent chan<- []bsmsg.Entry, supportsHave bool) *fakeMessageSender { - + messagesSent chan<- []bsmsg.Entry, supportsHave bool, +) *fakeMessageSender { return &fakeMessageSender{ reset: reset, messagesSent: messagesSent, @@ -126,7 +130,8 @@ func mockTimeoutCb(peer.ID, []cid.Cid) {} func collectMessages(ctx context.Context, t *testing.T, messagesSent <-chan []bsmsg.Entry, - timeout time.Duration) [][]bsmsg.Entry { + timeout time.Duration, +) [][]bsmsg.Entry { var messagesReceived [][]bsmsg.Entry timeoutctx, cancel := context.WithTimeout(ctx, timeout) defer cancel() diff --git a/bitswap/client/internal/notifications/notifications.go b/bitswap/client/internal/notifications/notifications.go index dc6dda899..499a61c42 100644 --- a/bitswap/client/internal/notifications/notifications.go +++ b/bitswap/client/internal/notifications/notifications.go @@ -68,7 +68,6 @@ func (ps *impl) Shutdown() { // is closed if the |ctx| times out or is cancelled, or after receiving the blocks // corresponding to |keys|. func (ps *impl) Subscribe(ctx context.Context, keys ...cid.Cid) <-chan blocks.Block { - blocksCh := make(chan blocks.Block, len(keys)) valuesCh := make(chan interface{}, len(keys)) // provide our own channel to control buffer, prevent blocking if len(keys) == 0 { diff --git a/bitswap/client/internal/notifications/notifications_test.go b/bitswap/client/internal/notifications/notifications_test.go index 25b580f6a..b4b8ef55d 100644 --- a/bitswap/client/internal/notifications/notifications_test.go +++ b/bitswap/client/internal/notifications/notifications_test.go @@ -58,7 +58,6 @@ func TestPublishSubscribe(t *testing.T) { } assertBlocksEqual(t, blockRecvd, blockSent) - } func TestSubscribeMany(t *testing.T) { diff --git a/bitswap/client/internal/peermanager/peermanager_test.go b/bitswap/client/internal/peermanager/peermanager_test.go index 40e1f072c..a2569201f 100644 --- a/bitswap/client/internal/peermanager/peermanager_test.go +++ b/bitswap/client/internal/peermanager/peermanager_test.go @@ -30,12 +30,15 @@ func (fp *mockPeerQueue) Shutdown() {} func (fp *mockPeerQueue) AddBroadcastWantHaves(whs []cid.Cid) { fp.msgs <- msg{fp.p, nil, whs, nil} } + func (fp *mockPeerQueue) AddWants(wbs []cid.Cid, whs []cid.Cid) { fp.msgs <- msg{fp.p, wbs, whs, nil} } + func (fp *mockPeerQueue) AddCancels(cs []cid.Cid) { fp.msgs <- msg{fp.p, nil, nil, cs} } + func (fp *mockPeerQueue) ResponseReceived(ks []cid.Cid) { } @@ -271,6 +274,7 @@ func TestSendCancels(t *testing.T) { func (s *sess) ID() uint64 { return s.id } + func (s *sess) SignalAvailability(p peer.ID, isAvailable bool) { s.available[p] = isAvailable } @@ -332,8 +336,7 @@ func TestSessionRegistration(t *testing.T) { } } -type benchPeerQueue struct { -} +type benchPeerQueue struct{} func (*benchPeerQueue) Startup() {} func (*benchPeerQueue) Shutdown() {} diff --git a/bitswap/client/internal/peermanager/peerwantmanager_test.go b/bitswap/client/internal/peermanager/peerwantmanager_test.go index 618217d6b..b4c3d5029 100644 --- a/bitswap/client/internal/peermanager/peerwantmanager_test.go +++ b/bitswap/client/internal/peermanager/peerwantmanager_test.go @@ -16,6 +16,7 @@ type gauge struct { func (g *gauge) Inc() { g.count++ } + func (g *gauge) Dec() { g.count-- } @@ -40,13 +41,16 @@ func (mpq *mockPQ) Shutdown() {} func (mpq *mockPQ) AddBroadcastWantHaves(whs []cid.Cid) { mpq.bcst = append(mpq.bcst, whs...) } + func (mpq *mockPQ) AddWants(wbs []cid.Cid, whs []cid.Cid) { mpq.wbs = append(mpq.wbs, wbs...) mpq.whs = append(mpq.whs, whs...) } + func (mpq *mockPQ) AddCancels(cs []cid.Cid) { mpq.cancels = append(mpq.cancels, cs...) } + func (mpq *mockPQ) ResponseReceived(ks []cid.Cid) { } diff --git a/bitswap/client/internal/providerquerymanager/providerquerymanager_test.go b/bitswap/client/internal/providerquerymanager/providerquerymanager_test.go index 6cf5fa4a2..04b309286 100644 --- a/bitswap/client/internal/providerquerymanager/providerquerymanager_test.go +++ b/bitswap/client/internal/providerquerymanager/providerquerymanager_test.go @@ -95,7 +95,6 @@ func TestNormalSimultaneousFetch(t *testing.T) { if fpn.queriesMade != 2 { t.Fatal("Did not dedup provider requests running simultaneously") } - } func TestDedupingProviderRequests(t *testing.T) { @@ -256,7 +255,6 @@ func TestPeersWithConnectionErrorsNotAddedToPeerList(t *testing.T) { if len(firstPeersReceived) != 0 || len(secondPeersReceived) != 0 { t.Fatal("Did not filter out peers with connection issues") } - } func TestRateLimitingRequests(t *testing.T) { diff --git a/bitswap/client/internal/session/session.go b/bitswap/client/internal/session/session.go index 127004dc7..39266a5e6 100644 --- a/bitswap/client/internal/session/session.go +++ b/bitswap/client/internal/session/session.go @@ -18,8 +18,10 @@ import ( "go.uber.org/zap" ) -var log = logging.Logger("bs:sess") -var sflog = log.Desugar() +var ( + log = logging.Logger("bs:sess") + sflog = log.Desugar() +) const ( broadcastLiveWantsLimit = 64 @@ -146,8 +148,8 @@ func New( notif notifications.PubSub, initialSearchDelay time.Duration, periodicSearchDelay delay.D, - self peer.ID) *Session { - + self peer.ID, +) *Session { ctx, cancel := context.WithCancel(ctx) s := &Session{ sw: newSessionWants(broadcastLiveWantsLimit), diff --git a/bitswap/client/internal/session/session_test.go b/bitswap/client/internal/session/session_test.go index b60c7d1af..cf6de1e5a 100644 --- a/bitswap/client/internal/session/session_test.go +++ b/bitswap/client/internal/session/session_test.go @@ -170,7 +170,6 @@ func TestSessionGetBlocks(t *testing.T) { } _, err := session.GetBlocks(ctx, cids) - if err != nil { t.Fatal("error getting blocks") } @@ -344,7 +343,6 @@ func TestSessionOnPeersExhausted(t *testing.T) { cids = append(cids, block.Cid()) } _, err := session.GetBlocks(ctx, cids) - if err != nil { t.Fatal("error getting blocks") } diff --git a/bitswap/client/internal/session/sessionwantsender.go b/bitswap/client/internal/session/sessionwantsender.go index 41145fbf6..390fdf29d 100644 --- a/bitswap/client/internal/session/sessionwantsender.go +++ b/bitswap/client/internal/session/sessionwantsender.go @@ -67,8 +67,10 @@ type change struct { availability peerAvailability } -type onSendFn func(to peer.ID, wantBlocks []cid.Cid, wantHaves []cid.Cid) -type onPeersExhaustedFn func([]cid.Cid) +type ( + onSendFn func(to peer.ID, wantBlocks []cid.Cid, wantHaves []cid.Cid) + onPeersExhaustedFn func([]cid.Cid) +) // sessionWantSender is responsible for sending want-have and want-block to // peers. For each want, it sends a single optimistic want-block request to @@ -111,8 +113,8 @@ type sessionWantSender struct { } func newSessionWantSender(sid uint64, pm PeerManager, spm SessionPeerManager, canceller SessionWantsCanceller, - bpm *bsbpm.BlockPresenceManager, onSend onSendFn, onPeersExhausted onPeersExhaustedFn) sessionWantSender { - + bpm *bsbpm.BlockPresenceManager, onSend onSendFn, onPeersExhausted onPeersExhaustedFn, +) sessionWantSender { ctx, cancel := context.WithCancel(context.Background()) sws := sessionWantSender{ ctx: ctx, diff --git a/bitswap/client/internal/session/sessionwantsender_test.go b/bitswap/client/internal/session/sessionwantsender_test.go index 97ff788a9..476b13991 100644 --- a/bitswap/client/internal/session/sessionwantsender_test.go +++ b/bitswap/client/internal/session/sessionwantsender_test.go @@ -34,13 +34,14 @@ func (sw *sentWants) add(wantBlocks []cid.Cid, wantHaves []cid.Cid) { sw.wantHaves.Add(c) } } - } + func (sw *sentWants) wantHavesKeys() []cid.Cid { sw.Lock() defer sw.Unlock() return sw.wantHaves.Keys() } + func (sw *sentWants) wantBlocksKeys() []cid.Cid { sw.Lock() defer sw.Unlock() diff --git a/bitswap/client/internal/sessionmanager/sessionmanager.go b/bitswap/client/internal/sessionmanager/sessionmanager.go index 38e490a2e..a75a3f769 100644 --- a/bitswap/client/internal/sessionmanager/sessionmanager.go +++ b/bitswap/client/internal/sessionmanager/sessionmanager.go @@ -69,8 +69,8 @@ type SessionManager struct { // New creates a new SessionManager. func New(ctx context.Context, sessionFactory SessionFactory, sessionInterestManager *bssim.SessionInterestManager, peerManagerFactory PeerManagerFactory, - blockPresenceManager *bsbpm.BlockPresenceManager, peerManager bssession.PeerManager, notif notifications.PubSub, self peer.ID) *SessionManager { - + blockPresenceManager *bsbpm.BlockPresenceManager, peerManager bssession.PeerManager, notif notifications.PubSub, self peer.ID, +) *SessionManager { return &SessionManager{ ctx: ctx, sessionFactory: sessionFactory, @@ -88,7 +88,8 @@ func New(ctx context.Context, sessionFactory SessionFactory, sessionInterestMana // session manager. func (sm *SessionManager) NewSession(ctx context.Context, provSearchDelay time.Duration, - rebroadcastDelay delay.D) exchange.Fetcher { + rebroadcastDelay delay.D, +) exchange.Fetcher { id := sm.GetNextSessionID() ctx, span := internal.StartSpan(ctx, "SessionManager.NewSession", trace.WithAttributes(attribute.String("ID", strconv.FormatUint(id, 10)))) diff --git a/bitswap/client/internal/sessionmanager/sessionmanager_test.go b/bitswap/client/internal/sessionmanager/sessionmanager_test.go index 51dde7fda..5ecabfdb3 100644 --- a/bitswap/client/internal/sessionmanager/sessionmanager_test.go +++ b/bitswap/client/internal/sessionmanager/sessionmanager_test.go @@ -33,23 +33,26 @@ type fakeSession struct { func (*fakeSession) GetBlock(context.Context, cid.Cid) (blocks.Block, error) { return nil, nil } + func (*fakeSession) GetBlocks(context.Context, []cid.Cid) (<-chan blocks.Block, error) { return nil, nil } + func (fs *fakeSession) ID() uint64 { return fs.id } + func (fs *fakeSession) ReceiveFrom(p peer.ID, ks []cid.Cid, wantBlocks []cid.Cid, wantHaves []cid.Cid) { fs.ks = append(fs.ks, ks...) fs.wantBlocks = append(fs.wantBlocks, wantBlocks...) fs.wantHaves = append(fs.wantHaves, wantHaves...) } + func (fs *fakeSession) Shutdown() { fs.sm.RemoveSession(fs.id) } -type fakeSesPeerManager struct { -} +type fakeSesPeerManager struct{} func (*fakeSesPeerManager) Peers() []peer.ID { return nil } func (*fakeSesPeerManager) PeersDiscovered() bool { return false } @@ -73,6 +76,7 @@ func (fpm *fakePeerManager) SendCancels(ctx context.Context, cancels []cid.Cid) defer fpm.lk.Unlock() fpm.cancels = append(fpm.cancels, cancels...) } + func (fpm *fakePeerManager) cancelled() []cid.Cid { fpm.lk.Lock() defer fpm.lk.Unlock() @@ -89,7 +93,8 @@ func sessionFactory(ctx context.Context, notif notifications.PubSub, provSearchDelay time.Duration, rebroadcastDelay delay.D, - self peer.ID) Session { + self peer.ID, +) Session { fs := &fakeSession{ id: id, pm: sprm.(*fakeSesPeerManager), diff --git a/bitswap/client/wantlist/wantlist_test.go b/bitswap/client/wantlist/wantlist_test.go index 829af50a6..035786ea3 100644 --- a/bitswap/client/wantlist/wantlist_test.go +++ b/bitswap/client/wantlist/wantlist_test.go @@ -24,7 +24,6 @@ func init() { } testcids = append(testcids, c) } - } type wli interface { @@ -236,7 +235,6 @@ func TestSortEntries(t *testing.T) { !entries[2].Cid.Equals(testcids[0]) { t.Fatal("wrong order") } - } // Test adding and removing interleaved with checking entries to make sure we clear the cache. diff --git a/bitswap/internal/testutil/testutil.go b/bitswap/internal/testutil/testutil.go index d35bdb743..eb633bfc3 100644 --- a/bitswap/internal/testutil/testutil.go +++ b/bitswap/internal/testutil/testutil.go @@ -12,8 +12,10 @@ import ( peer "github.com/libp2p/go-libp2p/core/peer" ) -var blockGenerator = blocksutil.NewBlockGenerator() -var prioritySeq int32 +var ( + blockGenerator = blocksutil.NewBlockGenerator() + prioritySeq int32 +) // GenerateBlocksOfSize generates a series of blocks of the given byte size func GenerateBlocksOfSize(n int, size int64) []blocks.Block { diff --git a/bitswap/message/message_test.go b/bitswap/message/message_test.go index 520abd22b..ec07cbcff 100644 --- a/bitswap/message/message_test.go +++ b/bitswap/message/message_test.go @@ -47,7 +47,6 @@ func TestNewMessageFromProto(t *testing.T) { } func TestAppendBlock(t *testing.T) { - strs := make([]string, 2) strs = append(strs, "Celeritas") strs = append(strs, "Incendia") @@ -78,7 +77,6 @@ func TestWantlist(t *testing.T) { for _, k := range exported { present := false for _, s := range keystrs { - if s.Equals(k.Cid) { present = true } @@ -135,7 +133,6 @@ func TestToNetFromNetPreservesWantList(t *testing.T) { } func TestToAndFromNetMessage(t *testing.T) { - original := New(true) original.AddBlock(blocks.NewBlock([]byte("W"))) original.AddBlock(blocks.NewBlock([]byte("E"))) diff --git a/bitswap/message/pb/cid_test.go b/bitswap/message/pb/cid_test.go index 490e6b997..6d346488a 100644 --- a/bitswap/message/pb/cid_test.go +++ b/bitswap/message/pb/cid_test.go @@ -11,7 +11,7 @@ import ( ) func TestCID(t *testing.T) { - var expected = [...]byte{ + expected := [...]byte{ 10, 34, 18, 32, 195, 171, 143, 241, 55, 32, 232, 173, 144, 71, 221, 57, 70, 107, diff --git a/bitswap/message/pb/message.pb.go b/bitswap/message/pb/message.pb.go index ec80b2512..cf22ce525 100644 --- a/bitswap/message/pb/message.pb.go +++ b/bitswap/message/pb/message.pb.go @@ -5,17 +5,20 @@ package bitswap_message_pb import ( fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" io "io" math "math" math_bits "math/bits" + + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" ) // Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf +var ( + _ = proto.Marshal + _ = fmt.Errorf + _ = math.Inf +) // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. @@ -87,9 +90,11 @@ func (*Message) ProtoMessage() {} func (*Message) Descriptor() ([]byte, []int) { return fileDescriptor_33c57e4bae7b9afd, []int{0} } + func (m *Message) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } + func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { return xxx_messageInfo_Message.Marshal(b, m, deterministic) @@ -102,12 +107,15 @@ func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return b[:n], nil } } + func (m *Message) XXX_Merge(src proto.Message) { xxx_messageInfo_Message.Merge(m, src) } + func (m *Message) XXX_Size() int { return m.Size() } + func (m *Message) XXX_DiscardUnknown() { xxx_messageInfo_Message.DiscardUnknown(m) } @@ -160,9 +168,11 @@ func (*Message_Wantlist) ProtoMessage() {} func (*Message_Wantlist) Descriptor() ([]byte, []int) { return fileDescriptor_33c57e4bae7b9afd, []int{0, 0} } + func (m *Message_Wantlist) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } + func (m *Message_Wantlist) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { return xxx_messageInfo_Message_Wantlist.Marshal(b, m, deterministic) @@ -175,12 +185,15 @@ func (m *Message_Wantlist) XXX_Marshal(b []byte, deterministic bool) ([]byte, er return b[:n], nil } } + func (m *Message_Wantlist) XXX_Merge(src proto.Message) { xxx_messageInfo_Message_Wantlist.Merge(m, src) } + func (m *Message_Wantlist) XXX_Size() int { return m.Size() } + func (m *Message_Wantlist) XXX_DiscardUnknown() { xxx_messageInfo_Message_Wantlist.DiscardUnknown(m) } @@ -215,9 +228,11 @@ func (*Message_Wantlist_Entry) ProtoMessage() {} func (*Message_Wantlist_Entry) Descriptor() ([]byte, []int) { return fileDescriptor_33c57e4bae7b9afd, []int{0, 0, 0} } + func (m *Message_Wantlist_Entry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } + func (m *Message_Wantlist_Entry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { return xxx_messageInfo_Message_Wantlist_Entry.Marshal(b, m, deterministic) @@ -230,12 +245,15 @@ func (m *Message_Wantlist_Entry) XXX_Marshal(b []byte, deterministic bool) ([]by return b[:n], nil } } + func (m *Message_Wantlist_Entry) XXX_Merge(src proto.Message) { xxx_messageInfo_Message_Wantlist_Entry.Merge(m, src) } + func (m *Message_Wantlist_Entry) XXX_Size() int { return m.Size() } + func (m *Message_Wantlist_Entry) XXX_DiscardUnknown() { xxx_messageInfo_Message_Wantlist_Entry.DiscardUnknown(m) } @@ -281,9 +299,11 @@ func (*Message_Block) ProtoMessage() {} func (*Message_Block) Descriptor() ([]byte, []int) { return fileDescriptor_33c57e4bae7b9afd, []int{0, 1} } + func (m *Message_Block) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } + func (m *Message_Block) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { return xxx_messageInfo_Message_Block.Marshal(b, m, deterministic) @@ -296,12 +316,15 @@ func (m *Message_Block) XXX_Marshal(b []byte, deterministic bool) ([]byte, error return b[:n], nil } } + func (m *Message_Block) XXX_Merge(src proto.Message) { xxx_messageInfo_Message_Block.Merge(m, src) } + func (m *Message_Block) XXX_Size() int { return m.Size() } + func (m *Message_Block) XXX_DiscardUnknown() { xxx_messageInfo_Message_Block.DiscardUnknown(m) } @@ -333,9 +356,11 @@ func (*Message_BlockPresence) ProtoMessage() {} func (*Message_BlockPresence) Descriptor() ([]byte, []int) { return fileDescriptor_33c57e4bae7b9afd, []int{0, 2} } + func (m *Message_BlockPresence) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } + func (m *Message_BlockPresence) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { return xxx_messageInfo_Message_BlockPresence.Marshal(b, m, deterministic) @@ -348,12 +373,15 @@ func (m *Message_BlockPresence) XXX_Marshal(b []byte, deterministic bool) ([]byt return b[:n], nil } } + func (m *Message_BlockPresence) XXX_Merge(src proto.Message) { xxx_messageInfo_Message_BlockPresence.Merge(m, src) } + func (m *Message_BlockPresence) XXX_Size() int { return m.Size() } + func (m *Message_BlockPresence) XXX_DiscardUnknown() { xxx_messageInfo_Message_BlockPresence.DiscardUnknown(m) } @@ -685,6 +713,7 @@ func encodeVarintMessage(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } + func (m *Message) Size() (n int) { if m == nil { return 0 @@ -792,9 +821,11 @@ func (m *Message_BlockPresence) Size() (n int) { func sovMessage(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } + func sozMessage(x uint64) (n int) { return sovMessage(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } + func (m *Message) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -997,6 +1028,7 @@ func (m *Message) Unmarshal(dAtA []byte) error { } return nil } + func (m *Message_Wantlist) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -1101,6 +1133,7 @@ func (m *Message_Wantlist) Unmarshal(dAtA []byte) error { } return nil } + func (m *Message_Wantlist_Entry) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -1262,6 +1295,7 @@ func (m *Message_Wantlist_Entry) Unmarshal(dAtA []byte) error { } return nil } + func (m *Message_Block) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -1380,6 +1414,7 @@ func (m *Message_Block) Unmarshal(dAtA []byte) error { } return nil } + func (m *Message_BlockPresence) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -1482,6 +1517,7 @@ func (m *Message_BlockPresence) Unmarshal(dAtA []byte) error { } return nil } + func skipMessage(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/bitswap/network/ipfs_impl.go b/bitswap/network/ipfs_impl.go index 039121cfc..a1446775c 100644 --- a/bitswap/network/ipfs_impl.go +++ b/bitswap/network/ipfs_impl.go @@ -30,10 +30,12 @@ var log = logging.Logger("bitswap_network") var connectTimeout = time.Second * 5 -var maxSendTimeout = 2 * time.Minute -var minSendTimeout = 10 * time.Second -var sendLatency = 2 * time.Second -var minSendRate = (100 * 1000) / 8 // 100kbit/s +var ( + maxSendTimeout = 2 * time.Minute + minSendTimeout = 10 * time.Second + sendLatency = 2 * time.Second + minSendRate = (100 * 1000) / 8 // 100kbit/s +) // NewFromIpfsHost returns a BitSwapNetwork supported by underlying IPFS host. func NewFromIpfsHost(host host.Host, r routing.ContentRouting, opts ...NetOpt) BitSwapNetwork { @@ -284,7 +286,6 @@ func (bsnet *impl) NewMessageSender(ctx context.Context, p peer.ID, opts *Messag _, err := sender.Connect(ctx) return err }) - if err != nil { return nil, err } @@ -320,8 +321,8 @@ func sendTimeout(size int) time.Duration { func (bsnet *impl) SendMessage( ctx context.Context, p peer.ID, - outgoing bsmsg.BitSwapMessage) error { - + outgoing bsmsg.BitSwapMessage, +) error { tctx, cancel := context.WithTimeout(ctx, connectTimeout) defer cancel() @@ -357,7 +358,6 @@ func (bsnet *impl) Start(r ...Receiver) { } bsnet.host.Network().Notify((*netNotifiee)(bsnet)) bsnet.connectEvtMgr.Start() - } func (bsnet *impl) Stop() { @@ -458,6 +458,7 @@ func (nn *netNotifiee) Connected(n network.Network, v network.Conn) { nn.impl().connectEvtMgr.Connected(v.RemotePeer()) } + func (nn *netNotifiee) Disconnected(n network.Network, v network.Conn) { // Only record a "disconnect" when we actually disconnect. if n.Connectedness(v.RemotePeer()) == network.Connected { diff --git a/bitswap/network/ipfs_impl_test.go b/bitswap/network/ipfs_impl_test.go index 61b00baa3..175957799 100644 --- a/bitswap/network/ipfs_impl_test.go +++ b/bitswap/network/ipfs_impl_test.go @@ -47,7 +47,8 @@ func newReceiver() *receiver { func (r *receiver) ReceiveMessage( ctx context.Context, sender peer.ID, - incoming bsmsg.BitSwapMessage) { + incoming bsmsg.BitSwapMessage, +) { r.lastSender = sender r.lastMessage = incoming select { diff --git a/bitswap/server/internal/decision/engine.go b/bitswap/server/internal/decision/engine.go index 02f317e07..a7b6c11d0 100644 --- a/bitswap/server/internal/decision/engine.go +++ b/bitswap/server/internal/decision/engine.go @@ -456,7 +456,6 @@ func (e *Engine) StartWorkers(ctx context.Context, px process.Process) { e.taskWorker(ctx) }) } - } func (e *Engine) onPeerAdded(p peer.ID) { diff --git a/bitswap/server/internal/decision/engine_test.go b/bitswap/server/internal/decision/engine_test.go index 9b4dbc2de..1391f4f70 100644 --- a/bitswap/server/internal/decision/engine_test.go +++ b/bitswap/server/internal/decision/engine_test.go @@ -105,7 +105,7 @@ func newTestEngineWithSampling(ctx context.Context, idStr string, peerSampleInte e.StartWorkers(ctx, process.WithTeardown(func() error { return nil })) return engineSet{ Peer: peer.ID(idStr), - //Strategy: New(true), + // Strategy: New(true), PeerTagger: fpt, Blockstore: bs, Engine: e, diff --git a/bitswap/server/server.go b/bitswap/server/server.go index 9c8e4cdb3..f71d6f5f1 100644 --- a/bitswap/server/server.go +++ b/bitswap/server/server.go @@ -28,8 +28,10 @@ import ( var provideKeysBufferSize = 2048 -var log = logging.Logger("bitswap-server") -var sflog = log.Desugar() +var ( + log = logging.Logger("bitswap-server") + sflog = log.Desugar() +) const provideWorkerMax = 6 @@ -545,11 +547,12 @@ func (*Server) ReceiveError(err error) { log.Infof("Bitswap Client ReceiveError: %s", err) // TODO log the network error // TODO bubble the network error up to the parent context/error logger - } + func (bs *Server) PeerConnected(p peer.ID) { bs.engine.PeerConnected(p) } + func (bs *Server) PeerDisconnected(p peer.ID) { bs.engine.PeerDisconnected(p) } diff --git a/bitswap/testnet/internet_latency_delay_generator.go b/bitswap/testnet/internet_latency_delay_generator.go index 25b9f5b80..d133ae4cb 100644 --- a/bitswap/testnet/internet_latency_delay_generator.go +++ b/bitswap/testnet/internet_latency_delay_generator.go @@ -27,7 +27,8 @@ func InternetLatencyDelayGenerator( percentMedium float64, percentLarge float64, std time.Duration, - rng *rand.Rand) delay.Generator { + rng *rand.Rand, +) delay.Generator { if rng == nil { rng = sharedRNG } diff --git a/bitswap/testnet/network_test.go b/bitswap/testnet/network_test.go index fc055a2d1..0947eff3e 100644 --- a/bitswap/testnet/network_test.go +++ b/bitswap/testnet/network_test.go @@ -31,8 +31,8 @@ func TestSendMessageAsyncButWaitForResponse(t *testing.T) { responder.Start(lambda(func( ctx context.Context, fromWaiter peer.ID, - msgFromWaiter bsmsg.BitSwapMessage) { - + msgFromWaiter bsmsg.BitSwapMessage, + ) { msgToWaiter := bsmsg.New(true) msgToWaiter.AddBlock(blocks.NewBlock([]byte(expectedStr))) err := waiter.SendMessage(ctx, fromWaiter, msgToWaiter) @@ -45,8 +45,8 @@ func TestSendMessageAsyncButWaitForResponse(t *testing.T) { waiter.Start(lambda(func( ctx context.Context, fromResponder peer.ID, - msgFromResponder bsmsg.BitSwapMessage) { - + msgFromResponder bsmsg.BitSwapMessage, + ) { // TODO assert that this came from the correct peer and that the message contents are as expected ok := false for _, b := range msgFromResponder.Blocks() { @@ -88,7 +88,8 @@ type lambdaImpl struct { } func (lam *lambdaImpl) ReceiveMessage(ctx context.Context, - p peer.ID, incoming bsmsg.BitSwapMessage) { + p peer.ID, incoming bsmsg.BitSwapMessage, +) { lam.f(ctx, p, incoming) } @@ -99,6 +100,7 @@ func (lam *lambdaImpl) ReceiveError(err error) { func (lam *lambdaImpl) PeerConnected(p peer.ID) { // TODO } + func (lam *lambdaImpl) PeerDisconnected(peer.ID) { // TODO } diff --git a/bitswap/testnet/virtual.go b/bitswap/testnet/virtual.go index 0deb1b1ab..914044aed 100644 --- a/bitswap/testnet/virtual.go +++ b/bitswap/testnet/virtual.go @@ -126,8 +126,8 @@ func (n *network) SendMessage( ctx context.Context, from peer.ID, to peer.ID, - mes bsmsg.BitSwapMessage) error { - + mes bsmsg.BitSwapMessage, +) error { mes = mes.Clone() n.mu.Lock() @@ -213,6 +213,7 @@ func (nc *networkClient) PeerConnected(p peer.ID) { v.PeerConnected(p) } } + func (nc *networkClient) PeerDisconnected(p peer.ID) { for _, v := range nc.receivers { v.PeerDisconnected(p) @@ -236,7 +237,8 @@ func (nc *networkClient) Latency(p peer.ID) time.Duration { func (nc *networkClient) SendMessage( ctx context.Context, to peer.ID, - message bsmsg.BitSwapMessage) error { + message bsmsg.BitSwapMessage, +) error { if err := nc.network.SendMessage(ctx, nc.local, to, message); err != nil { return err } diff --git a/blockservice/test/blocks_test.go b/blockservice/test/blocks_test.go index 6bfe603e4..6cb56faab 100644 --- a/blockservice/test/blocks_test.go +++ b/blockservice/test/blocks_test.go @@ -65,7 +65,7 @@ func makeObjects(n int) []blocks.Block { } func TestGetBlocksSequential(t *testing.T) { - var servs = Mocks(4) + servs := Mocks(4) for _, s := range servs { defer s.Close() } diff --git a/blockstore/blockstore.go b/blockstore/blockstore.go index 6a606f1e1..27260e5d8 100644 --- a/blockstore/blockstore.go +++ b/blockstore/blockstore.go @@ -268,7 +268,6 @@ func (bs *blockstore) DeleteBlock(ctx context.Context, k cid.Cid) error { // // AllKeysChan respects context. func (bs *blockstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) { - // KeysOnly, because that would be _a lot_ of data. q := dsq.Query{KeysOnly: true} res, err := bs.datastore.Query(ctx, q) diff --git a/blockstore/blockstore_test.go b/blockstore/blockstore_test.go index afcaec40e..684a9968f 100644 --- a/blockstore/blockstore_test.go +++ b/blockstore/blockstore_test.go @@ -229,7 +229,7 @@ func TestAllKeysRespectsContext(t *testing.T) { } var results dsq.Results - var resultsmu = make(chan struct{}) + resultsmu := make(chan struct{}) resultChan := make(chan dsq.Result) d.SetFunc(func(q dsq.Query) (dsq.Results, error) { results = dsq.ResultsWithChan(q, resultChan) @@ -265,7 +265,6 @@ func TestAllKeysRespectsContext(t *testing.T) { } t.Error(err) } - } func expectMatches(t *testing.T, expect, actual []cid.Cid) { @@ -328,6 +327,7 @@ func (c *queryTestDS) Sync(ctx context.Context, key ds.Key) error { func (c *queryTestDS) Batch(_ context.Context) (ds.Batch, error) { return ds.NewBasicBatch(c), nil } + func (c *queryTestDS) Close() error { return nil } diff --git a/blockstore/bloom_cache.go b/blockstore/bloom_cache.go index fddab1e53..a0a1b9ad2 100644 --- a/blockstore/bloom_cache.go +++ b/blockstore/bloom_cache.go @@ -78,8 +78,10 @@ type bloomcache struct { total metrics.Counter } -var _ Blockstore = (*bloomcache)(nil) -var _ Viewer = (*bloomcache)(nil) +var ( + _ Blockstore = (*bloomcache)(nil) + _ Viewer = (*bloomcache)(nil) +) func (b *bloomcache) BloomActive() bool { return atomic.LoadInt32(&b.active) != 0 diff --git a/blockstore/bloom_cache_test.go b/blockstore/bloom_cache_test.go index 70d118e09..a1daa0ae5 100644 --- a/blockstore/bloom_cache_test.go +++ b/blockstore/bloom_cache_test.go @@ -93,6 +93,7 @@ func TestReturnsErrorWhenSizeNegative(t *testing.T) { t.Fail() } } + func TestHasIsBloomCached(t *testing.T) { cd := &callbackDatastore{f: func() {}, ds: ds.NewMapDatastore()} bs := NewBlockstore(syncds.MutexWrap(cd)) diff --git a/blockstore/caching.go b/blockstore/caching.go index bfbe449a9..67fe8cade 100644 --- a/blockstore/caching.go +++ b/blockstore/caching.go @@ -29,7 +29,8 @@ func DefaultCacheOpts() CacheOpts { func CachedBlockstore( ctx context.Context, bs Blockstore, - opts CacheOpts) (cbs Blockstore, err error) { + opts CacheOpts, +) (cbs Blockstore, err error) { cbs = bs if opts.HasBloomFilterSize < 0 || opts.HasBloomFilterHashes < 0 || diff --git a/blockstore/idstore.go b/blockstore/idstore.go index 25a6284c8..340b8b18b 100644 --- a/blockstore/idstore.go +++ b/blockstore/idstore.go @@ -15,9 +15,11 @@ type idstore struct { viewer Viewer } -var _ Blockstore = (*idstore)(nil) -var _ Viewer = (*idstore)(nil) -var _ io.Closer = (*idstore)(nil) +var ( + _ Blockstore = (*idstore)(nil) + _ Viewer = (*idstore)(nil) + _ io.Closer = (*idstore)(nil) +) func NewIdStore(bs Blockstore) Blockstore { ids := &idstore{bs: bs} diff --git a/blockstore/twoqueue_cache.go b/blockstore/twoqueue_cache.go index 97374ad5b..2b03cb972 100644 --- a/blockstore/twoqueue_cache.go +++ b/blockstore/twoqueue_cache.go @@ -12,8 +12,10 @@ import ( metrics "github.com/ipfs/go-metrics-interface" ) -type cacheHave bool -type cacheSize int +type ( + cacheHave bool + cacheSize int +) type lock struct { mu sync.RWMutex @@ -39,8 +41,10 @@ type tqcache struct { total metrics.Counter } -var _ Blockstore = (*tqcache)(nil) -var _ Viewer = (*tqcache)(nil) +var ( + _ Blockstore = (*tqcache)(nil) + _ Viewer = (*tqcache)(nil) +) func newTwoQueueCachedBS(ctx context.Context, bs Blockstore, lruSize int) (*tqcache, error) { cache, err := lru.New2Q[string, any](lruSize) diff --git a/blockstore/twoqueue_cache_test.go b/blockstore/twoqueue_cache_test.go index b4ed91893..c93f6b8ec 100644 --- a/blockstore/twoqueue_cache_test.go +++ b/blockstore/twoqueue_cache_test.go @@ -46,6 +46,7 @@ func trap(message string, cd *callbackDatastore, t *testing.T) { t.Fatal(message) }) } + func untrap(cd *callbackDatastore) { cd.SetFunc(func() {}) } @@ -317,7 +318,7 @@ func BenchmarkTwoQueueCacheConcurrentOps(b *testing.B) { // We always mix just two operations at a time. const numOps = 2 - var testOps = []struct { + testOps := []struct { name string ops [numOps]func(*tqcache, blocks.Block) }{ @@ -393,7 +394,6 @@ func BenchmarkTwoQueueCacheConcurrentOps(b *testing.B) { b.Fatalf("op %d ran %fx as many times as %d", maxIdx, ratio, minIdx) } } - }) } } diff --git a/chunker/buzhash.go b/chunker/buzhash.go index 83ab019dd..790bb0e7f 100644 --- a/chunker/buzhash.go +++ b/chunker/buzhash.go @@ -148,4 +148,5 @@ var bytehash = [256]uint32{ 0xe981a4c4, 0x82991da1, 0x708f7294, 0xe6e2ae62, 0xfc441870, 0x95e1b0b6, 0x445f825, 0x5a93b47f, 0x5e9cf4be, 0x84da71e7, 0x9d9582b0, 0x9bf835ef, 0x591f61e2, 0x43325985, 0x5d2de32e, 0x8d8fbf0f, 0x95b30f38, 0x7ad5b6e, - 0x4e934edf, 0x3cd4990e, 0x9053e259, 0x5c41857d} + 0x4e934edf, 0x3cd4990e, 0x9053e259, 0x5c41857d, +} diff --git a/chunker/parse_test.go b/chunker/parse_test.go index 237a2b439..2a33d64de 100644 --- a/chunker/parse_test.go +++ b/chunker/parse_test.go @@ -52,7 +52,6 @@ func TestParseRabin(t *testing.T) { if err != ErrSizeMax { t.Fatalf("Expected 'ErrSizeMax', got: %#v", err) } - } func TestParseSize(t *testing.T) { diff --git a/chunker/splitting_test.go b/chunker/splitting_test.go index c53dfb4a7..4a9f7f332 100644 --- a/chunker/splitting_test.go +++ b/chunker/splitting_test.go @@ -110,7 +110,6 @@ type clipReader struct { } func (s *clipReader) Read(buf []byte) (int, error) { - // clip the incoming buffer to produce smaller chunks if len(buf) > s.size { buf = buf[:s.size] diff --git a/cmd/deprecator/main.go b/cmd/deprecator/main.go index 7b3bc3d17..02dd2ae04 100644 --- a/cmd/deprecator/main.go +++ b/cmd/deprecator/main.go @@ -143,7 +143,6 @@ func inspectASTNode(addComment func(string, *dst.Decorations), n dst.Node) bool } } return true - } func getModulePath(dir string) (string, error) { diff --git a/coreiface/options/block.go b/coreiface/options/block.go index 130648682..83a43702c 100644 --- a/coreiface/options/block.go +++ b/coreiface/options/block.go @@ -17,8 +17,10 @@ type BlockRmSettings struct { Force bool } -type BlockPutOption func(*BlockPutSettings) error -type BlockRmOption func(*BlockRmSettings) error +type ( + BlockPutOption func(*BlockPutSettings) error + BlockRmOption func(*BlockRmSettings) error +) func BlockPutOptions(opts ...BlockPutOption) (*BlockPutSettings, error) { var cidPrefix cid.Prefix @@ -131,7 +133,6 @@ func (blockOpts) Format(format string) BlockPutOption { return nil } - } // Hash is an option for Block.Put which specifies the multihash settings to use diff --git a/coreiface/options/dht.go b/coreiface/options/dht.go index e13e16020..b43bf3e7a 100644 --- a/coreiface/options/dht.go +++ b/coreiface/options/dht.go @@ -8,8 +8,10 @@ type DhtFindProvidersSettings struct { NumProviders int } -type DhtProvideOption func(*DhtProvideSettings) error -type DhtFindProvidersOption func(*DhtFindProvidersSettings) error +type ( + DhtProvideOption func(*DhtProvideSettings) error + DhtFindProvidersOption func(*DhtFindProvidersSettings) error +) func DhtProvideOptions(opts ...DhtProvideOption) (*DhtProvideSettings, error) { options := &DhtProvideSettings{ diff --git a/coreiface/options/key.go b/coreiface/options/key.go index 4bc53a65f..ebff6d5a7 100644 --- a/coreiface/options/key.go +++ b/coreiface/options/key.go @@ -16,8 +16,10 @@ type KeyRenameSettings struct { Force bool } -type KeyGenerateOption func(*KeyGenerateSettings) error -type KeyRenameOption func(*KeyRenameSettings) error +type ( + KeyGenerateOption func(*KeyGenerateSettings) error + KeyRenameOption func(*KeyRenameSettings) error +) func KeyGenerateOptions(opts ...KeyGenerateOption) (*KeyGenerateSettings, error) { options := &KeyGenerateSettings{ diff --git a/coreiface/options/name.go b/coreiface/options/name.go index 8e9b5183d..35e78c394 100644 --- a/coreiface/options/name.go +++ b/coreiface/options/name.go @@ -24,8 +24,10 @@ type NameResolveSettings struct { ResolveOpts []ropts.ResolveOpt } -type NamePublishOption func(*NamePublishSettings) error -type NameResolveOption func(*NameResolveSettings) error +type ( + NamePublishOption func(*NamePublishSettings) error + NameResolveOption func(*NameResolveSettings) error +) func NamePublishOptions(opts ...NamePublishOption) (*NamePublishSettings, error) { options := &NamePublishSettings{ diff --git a/coreiface/options/object.go b/coreiface/options/object.go index e484a9f36..b5625a1d6 100644 --- a/coreiface/options/object.go +++ b/coreiface/options/object.go @@ -14,9 +14,11 @@ type ObjectAddLinkSettings struct { Create bool } -type ObjectNewOption func(*ObjectNewSettings) error -type ObjectPutOption func(*ObjectPutSettings) error -type ObjectAddLinkOption func(*ObjectAddLinkSettings) error +type ( + ObjectNewOption func(*ObjectNewSettings) error + ObjectPutOption func(*ObjectPutSettings) error + ObjectAddLinkOption func(*ObjectAddLinkSettings) error +) func ObjectNewOptions(opts ...ObjectNewOption) (*ObjectNewSettings, error) { options := &ObjectNewSettings{ diff --git a/coreiface/options/pubsub.go b/coreiface/options/pubsub.go index c387d613d..839ef97b1 100644 --- a/coreiface/options/pubsub.go +++ b/coreiface/options/pubsub.go @@ -8,8 +8,10 @@ type PubSubSubscribeSettings struct { Discover bool } -type PubSubPeersOption func(*PubSubPeersSettings) error -type PubSubSubscribeOption func(*PubSubSubscribeSettings) error +type ( + PubSubPeersOption func(*PubSubPeersSettings) error + PubSubSubscribeOption func(*PubSubSubscribeSettings) error +) func PubSubPeersOptions(opts ...PubSubPeersOption) (*PubSubPeersSettings, error) { options := &PubSubPeersSettings{ diff --git a/coreiface/options/unixfs.go b/coreiface/options/unixfs.go index dd12502e6..f00fffb87 100644 --- a/coreiface/options/unixfs.go +++ b/coreiface/options/unixfs.go @@ -43,8 +43,10 @@ type UnixfsLsSettings struct { UseCumulativeSize bool } -type UnixfsAddOption func(*UnixfsAddSettings) error -type UnixfsLsOption func(*UnixfsLsSettings) error +type ( + UnixfsAddOption func(*UnixfsAddSettings) error + UnixfsLsOption func(*UnixfsLsSettings) error +) func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, error) { options := &UnixfsAddSettings{ diff --git a/coreiface/tests/dag.go b/coreiface/tests/dag.go index ba74031f9..b9a03c8f4 100644 --- a/coreiface/tests/dag.go +++ b/coreiface/tests/dag.go @@ -31,15 +31,13 @@ func (tp *TestSuite) TestDag(t *testing.T) { t.Run("TestBatch", tp.TestBatch) } -var ( - treeExpected = map[string]struct{}{ - "a": {}, - "b": {}, - "c": {}, - "c/d": {}, - "c/e": {}, - } -) +var treeExpected = map[string]struct{}{ + "a": {}, + "b": {}, + "c": {}, + "c/d": {}, + "c/e": {}, +} func (tp *TestSuite) TestPut(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) diff --git a/coreiface/tests/name.go b/coreiface/tests/name.go index ab55d0425..74d88edff 100644 --- a/coreiface/tests/name.go +++ b/coreiface/tests/name.go @@ -164,4 +164,4 @@ func (tp *TestSuite) TestBasicPublishResolveTimeout(t *testing.T) { require.NoError(t, err) } -//TODO: When swarm api is created, add multinode tests +// TODO: When swarm api is created, add multinode tests diff --git a/coreiface/tests/object.go b/coreiface/tests/object.go index 77061b699..63c218eb3 100644 --- a/coreiface/tests/object.go +++ b/coreiface/tests/object.go @@ -74,7 +74,7 @@ func (tp *TestSuite) TestObjectPut(t *testing.T) { t.Fatal(err) } - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"YmFy"}`), opt.Object.DataType("base64")) //bar + p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"YmFy"}`), opt.Object.DataType("base64")) // bar if err != nil { t.Fatal(err) } diff --git a/coreiface/tests/unixfs.go b/coreiface/tests/unixfs.go index 2842b47bc..25c3ac1b7 100644 --- a/coreiface/tests/unixfs.go +++ b/coreiface/tests/unixfs.go @@ -53,8 +53,10 @@ func (tp *TestSuite) TestUnixfs(t *testing.T) { } // `echo -n 'hello, world!' | ipfs add` -var hello = "/ipfs/QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk" -var helloStr = "hello, world!" +var ( + hello = "/ipfs/QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk" + helloStr = "hello, world!" +) // `echo -n | ipfs add` var emptyFile = "/ipfs/QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH" @@ -213,7 +215,7 @@ func (tp *TestSuite) TestAdd(t *testing.T) { path: "/ipfs/bafkqaaa", opts: []options.UnixfsAddOption{options.Unixfs.InlineLimit(0), options.Unixfs.Inline(true), options.Unixfs.RawLeaves(true)}, }, - { //TODO: after coreapi add is used in `ipfs add`, consider making this default for inline + { // TODO: after coreapi add is used in `ipfs add`, consider making this default for inline name: "addInlineRaw", data: strFile(helloStr), path: "/ipfs/bafkqadlimvwgy3zmeb3w64tmmqqq", diff --git a/examples/unixfs-file-cid/main_test.go b/examples/unixfs-file-cid/main_test.go index 7b69fb52b..39586fed2 100644 --- a/examples/unixfs-file-cid/main_test.go +++ b/examples/unixfs-file-cid/main_test.go @@ -3,9 +3,10 @@ package main import ( "bytes" "context" - "github.com/ipfs/go-cid" "testing" + "github.com/ipfs/go-cid" + "github.com/libp2p/go-libp2p/core/peer" ) diff --git a/fetcher/impl/blockservice/fetcher.go b/fetcher/impl/blockservice/fetcher.go index cbacd5984..a02e6ebbf 100644 --- a/fetcher/impl/blockservice/fetcher.go +++ b/fetcher/impl/blockservice/fetcher.go @@ -101,8 +101,8 @@ func (f *fetcherSession) NodeMatching(ctx context.Context, node ipld.Node, match } func (f *fetcherSession) BlockMatchingOfType(ctx context.Context, root ipld.Link, match ipld.Node, - _ ipld.NodePrototype, cb fetcher.FetchCallback) error { - + _ ipld.NodePrototype, cb fetcher.FetchCallback, +) error { // retrieve first node prototype, err := f.PrototypeFromLink(root) if err != nil { diff --git a/fetcher/impl/blockservice/fetcher_test.go b/fetcher/impl/blockservice/fetcher_test.go index ee5b5203c..5a0b071f4 100644 --- a/fetcher/impl/blockservice/fetcher_test.go +++ b/fetcher/impl/blockservice/fetcher_test.go @@ -362,5 +362,4 @@ func TestNodeReification(t *testing.T) { require.NoError(t, err) underlying4 := retrievedNode4.(*selfLoader).Node assert.Equal(t, node4, underlying4) - } diff --git a/files/file_test.go b/files/file_test.go index 8c6c62229..3edecf107 100644 --- a/files/file_test.go +++ b/files/file_test.go @@ -48,6 +48,7 @@ func TestReaderFiles(t *testing.T) { t.Fatal("Expected EOF when reading after close") } } + func TestMultipartFiles(t *testing.T) { data := ` --Boundary! diff --git a/files/filewriter.go b/files/filewriter.go index bf4bcf649..707d8bc2d 100644 --- a/files/filewriter.go +++ b/files/filewriter.go @@ -8,8 +8,10 @@ import ( "path/filepath" ) -var ErrInvalidDirectoryEntry = errors.New("invalid directory entry name") -var ErrPathExistsOverwrite = errors.New("path already exists and overwriting is not allowed") +var ( + ErrInvalidDirectoryEntry = errors.New("invalid directory entry name") + ErrPathExistsOverwrite = errors.New("path already exists and overwriting is not allowed") +) // WriteTo writes the given node to the local filesystem at fpath. func WriteTo(nd Node, fpath string) error { @@ -33,7 +35,7 @@ func WriteTo(nd Node, fpath string) error { } return nil case Directory: - err := os.Mkdir(fpath, 0777) + err := os.Mkdir(fpath, 0o777) if err != nil { return err } diff --git a/files/filewriter_unix.go b/files/filewriter_unix.go index d70b9f4ff..cd99aeb9a 100644 --- a/files/filewriter_unix.go +++ b/files/filewriter_unix.go @@ -15,5 +15,5 @@ func isValidFilename(filename string) bool { } func createNewFile(path string) (*os.File, error) { - return os.OpenFile(path, os.O_EXCL|os.O_CREATE|os.O_WRONLY|syscall.O_NOFOLLOW, 0666) + return os.OpenFile(path, os.O_EXCL|os.O_CREATE|os.O_WRONLY|syscall.O_NOFOLLOW, 0o666) } diff --git a/files/filewriter_windows.go b/files/filewriter_windows.go index a5d626199..8f61315e9 100644 --- a/files/filewriter_windows.go +++ b/files/filewriter_windows.go @@ -41,5 +41,5 @@ func isValidFilename(filename string) bool { } func createNewFile(path string) (*os.File, error) { - return os.OpenFile(path, os.O_EXCL|os.O_CREATE|os.O_WRONLY, 0666) + return os.OpenFile(path, os.O_EXCL|os.O_CREATE|os.O_WRONLY, 0o666) } diff --git a/files/filewriter_windows_test.go b/files/filewriter_windows_test.go index ca0222ba3..dced6e6ef 100644 --- a/files/filewriter_windows_test.go +++ b/files/filewriter_windows_test.go @@ -24,9 +24,11 @@ func TestWriteToInvalidPaths(t *testing.T) { os.RemoveAll(path) // Now try all invalid entry names - for _, entryName := range []string{"", ".", "..", "/", "", "not/a/base/path", + for _, entryName := range []string{ + "", ".", "..", "/", "", "not/a/base/path", "<", ">", ":", "\"", "\\", "|", "?", "*", "\x00", - "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"} { + "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9", + } { assert.Equal(t, ErrInvalidDirectoryEntry, WriteTo(NewMapDirectory(map[string]Node{ entryName: NewBytesFile(nil), }), filepath.Join(path))) diff --git a/files/filter_test.go b/files/filter_test.go index 8ce25ee3b..00b2e8baf 100644 --- a/files/filter_test.go +++ b/files/filter_test.go @@ -40,7 +40,7 @@ func TestFileFilter(t *testing.T) { } ignoreFilePath := filepath.Join(tmppath, "ignoreFile") ignoreFileContents := []byte("a.txt") - if err := os.WriteFile(ignoreFilePath, ignoreFileContents, 0666); err != nil { + if err := os.WriteFile(ignoreFilePath, ignoreFileContents, 0o666); err != nil { t.Fatal(err) } filterWithIgnoreFile, err := NewFilter(ignoreFilePath, nil, false) diff --git a/files/readerfile.go b/files/readerfile.go index 7b4e07954..bf3fa1c9e 100644 --- a/files/readerfile.go +++ b/files/readerfile.go @@ -88,5 +88,7 @@ func (f *ReaderFile) Seek(offset int64, whence int) (int64, error) { return 0, ErrNotSupported } -var _ File = &ReaderFile{} -var _ FileInfo = &ReaderFile{} +var ( + _ File = &ReaderFile{} + _ FileInfo = &ReaderFile{} +) diff --git a/files/serialfile.go b/files/serialfile.go index ab4c1e2fe..bd25bd1bc 100644 --- a/files/serialfile.go +++ b/files/serialfile.go @@ -164,5 +164,7 @@ func (f *serialFile) Size() (int64, error) { return du, err } -var _ Directory = &serialFile{} -var _ DirIterator = &serialIterator{} +var ( + _ Directory = &serialFile{} + _ DirIterator = &serialIterator{} +) diff --git a/files/serialfile_test.go b/files/serialfile_test.go index 80c252a7e..2d480a1df 100644 --- a/files/serialfile_test.go +++ b/files/serialfile_test.go @@ -57,7 +57,7 @@ func testSerialFile(t *testing.T, hidden, withIgnoreRules bool) { if c != "" { continue } - if err := os.MkdirAll(path, 0777); err != nil { + if err := os.MkdirAll(path, 0o777); err != nil { t.Fatal(err) } } @@ -67,7 +67,7 @@ func testSerialFile(t *testing.T, hidden, withIgnoreRules bool) { if c == "" { continue } - if err := os.WriteFile(path, []byte(c), 0666); err != nil { + if err := os.WriteFile(path, []byte(c), 0o666); err != nil { t.Fatal(err) } } diff --git a/files/slicedirectory.go b/files/slicedirectory.go index d11656261..9cf910c6a 100644 --- a/files/slicedirectory.go +++ b/files/slicedirectory.go @@ -93,5 +93,7 @@ func (f *SliceFile) Size() (int64, error) { return size, nil } -var _ Directory = &SliceFile{} -var _ DirEntry = fileEntry{} +var ( + _ Directory = &SliceFile{} + _ DirEntry = fileEntry{} +) diff --git a/files/tarwriter.go b/files/tarwriter.go index cecbcae42..e5d857116 100644 --- a/files/tarwriter.go +++ b/files/tarwriter.go @@ -10,9 +10,7 @@ import ( "time" ) -var ( - ErrUnixFSPathOutsideRoot = errors.New("relative UnixFS paths outside the root are now allowed, use CAR instead") -) +var ErrUnixFSPathOutsideRoot = errors.New("relative UnixFS paths outside the root are now allowed, use CAR instead") type TarWriter struct { TarW *tar.Writer @@ -110,7 +108,7 @@ func writeDirHeader(w *tar.Writer, fpath string) error { return w.WriteHeader(&tar.Header{ Name: fpath, Typeflag: tar.TypeDir, - Mode: 0777, + Mode: 0o777, ModTime: time.Now().Truncate(time.Second), // TODO: set mode, dates, etc. when added to unixFS }) @@ -121,7 +119,7 @@ func writeFileHeader(w *tar.Writer, fpath string, size uint64) error { Name: fpath, Size: int64(size), Typeflag: tar.TypeReg, - Mode: 0644, + Mode: 0o644, ModTime: time.Now().Truncate(time.Second), // TODO: set mode, dates, etc. when added to unixFS }) @@ -131,7 +129,7 @@ func writeSymlinkHeader(w *tar.Writer, target, fpath string) error { return w.WriteHeader(&tar.Header{ Name: fpath, Linkname: target, - Mode: 0777, + Mode: 0o777, Typeflag: tar.TypeSymlink, }) } diff --git a/files/webfile.go b/files/webfile.go index 594b81c82..4586eab63 100644 --- a/files/webfile.go +++ b/files/webfile.go @@ -85,5 +85,7 @@ func (wf *WebFile) Stat() os.FileInfo { return nil } -var _ File = &WebFile{} -var _ FileInfo = &WebFile{} +var ( + _ File = &WebFile{} + _ FileInfo = &WebFile{} +) diff --git a/filestore/filestore.go b/filestore/filestore.go index feb5b0291..90a61549f 100644 --- a/filestore/filestore.go +++ b/filestore/filestore.go @@ -22,8 +22,10 @@ import ( var logger = logging.Logger("filestore") -var ErrFilestoreNotEnabled = errors.New("filestore is not enabled, see https://git.io/vNItf") -var ErrUrlstoreNotEnabled = errors.New("urlstore is not enabled") +var ( + ErrFilestoreNotEnabled = errors.New("filestore is not enabled, see https://git.io/vNItf") + ErrUrlstoreNotEnabled = errors.New("urlstore is not enabled") +) // Filestore implements a Blockstore by combining a standard Blockstore // to store regular blocks and a special Blockstore called diff --git a/filestore/fsrefstore.go b/filestore/fsrefstore.go index 585b6446c..158eadf7a 100644 --- a/filestore/fsrefstore.go +++ b/filestore/fsrefstore.go @@ -205,8 +205,10 @@ func (f *FileManager) readFileDataObj(m mh.Multihash, d *pb.DataObj) ([]byte, er } if !origCid.Equals(outcid) { - return nil, &CorruptReferenceError{StatusFileChanged, - fmt.Errorf("data in file did not match. %s offset %d", d.GetFilePath(), d.GetOffset())} + return nil, &CorruptReferenceError{ + StatusFileChanged, + fmt.Errorf("data in file did not match. %s offset %d", d.GetFilePath(), d.GetOffset()), + } } return outbuf, nil @@ -230,8 +232,10 @@ func (f *FileManager) readURLDataObj(ctx context.Context, m mh.Multihash, d *pb. return nil, &CorruptReferenceError{StatusFileError, err} } if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusPartialContent { - return nil, &CorruptReferenceError{StatusFileError, - fmt.Errorf("expected HTTP 200 or 206 got %d", res.StatusCode)} + return nil, &CorruptReferenceError{ + StatusFileError, + fmt.Errorf("expected HTTP 200 or 206 got %d", res.StatusCode), + } } outbuf := make([]byte, d.GetSize_()) @@ -252,8 +256,10 @@ func (f *FileManager) readURLDataObj(ctx context.Context, m mh.Multihash, d *pb. } if !origCid.Equals(outcid) { - return nil, &CorruptReferenceError{StatusFileChanged, - fmt.Errorf("data in file did not match. %s offset %d", d.GetFilePath(), d.GetOffset())} + return nil, &CorruptReferenceError{ + StatusFileChanged, + fmt.Errorf("data in file did not match. %s offset %d", d.GetFilePath(), d.GetOffset()), + } } return outbuf, nil diff --git a/filestore/pb/dataobj.pb.go b/filestore/pb/dataobj.pb.go index d342cabe5..d47d1931e 100644 --- a/filestore/pb/dataobj.pb.go +++ b/filestore/pb/dataobj.pb.go @@ -13,9 +13,11 @@ import ( ) // Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf +var ( + _ = proto.Marshal + _ = fmt.Errorf + _ = math.Inf +) // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. @@ -35,9 +37,11 @@ func (*DataObj) ProtoMessage() {} func (*DataObj) Descriptor() ([]byte, []int) { return fileDescriptor_a76cb282d869d683, []int{0} } + func (m *DataObj) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } + func (m *DataObj) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { return xxx_messageInfo_DataObj.Marshal(b, m, deterministic) @@ -50,12 +54,15 @@ func (m *DataObj) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return b[:n], nil } } + func (m *DataObj) XXX_Merge(src proto.Message) { xxx_messageInfo_DataObj.Merge(m, src) } + func (m *DataObj) XXX_Size() int { return m.Size() } + func (m *DataObj) XXX_DiscardUnknown() { xxx_messageInfo_DataObj.DiscardUnknown(m) } @@ -148,6 +155,7 @@ func encodeVarintDataobj(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } + func (m *DataObj) Size() (n int) { if m == nil { return 0 @@ -164,9 +172,11 @@ func (m *DataObj) Size() (n int) { func sovDataobj(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } + func sozDataobj(x uint64) (n int) { return sovDataobj(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } + func (m *DataObj) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -290,6 +300,7 @@ func (m *DataObj) Unmarshal(dAtA []byte) error { } return nil } + func skipDataobj(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/gateway/assets/assets.go b/gateway/assets/assets.go index f411a47e0..3c0265f0c 100644 --- a/gateway/assets/assets.go +++ b/gateway/assets/assets.go @@ -2,12 +2,11 @@ package assets import ( "embed" + "html/template" "io" "io/fs" "net" "strconv" - - "html/template" "strings" "github.com/cespare/xxhash/v2" diff --git a/gateway/blocks_backend.go b/gateway/blocks_backend.go index 82e7e1a3b..208c92062 100644 --- a/gateway/blocks_backend.go +++ b/gateway/blocks_backend.go @@ -816,5 +816,7 @@ func blockOpener(ctx context.Context, ng format.NodeGetter) ipld.BlockReadOpener } } -var _ fetcher.Fetcher = (*nodeGetterFetcherSingleUseFactory)(nil) -var _ fetcher.Factory = (*nodeGetterFetcherSingleUseFactory)(nil) +var ( + _ fetcher.Fetcher = (*nodeGetterFetcherSingleUseFactory)(nil) + _ fetcher.Factory = (*nodeGetterFetcherSingleUseFactory)(nil) +) diff --git a/gateway/gateway_test.go b/gateway/gateway_test.go index 1c988ac9c..98996acb3 100644 --- a/gateway/gateway_test.go +++ b/gateway/gateway_test.go @@ -392,7 +392,6 @@ func TestHeaders(t *testing.T) { // Expect OPTIONS response to have implicit default Allow-Methods // set by boxo/gateway library assert.Equal(t, expectedACAM, res.Header[headerACAM]) - } cid := root.String() diff --git a/gateway/handler_car.go b/gateway/handler_car.go index 553519988..000e0dc9c 100644 --- a/gateway/handler_car.go +++ b/gateway/handler_car.go @@ -178,7 +178,6 @@ func buildCarParams(r *http.Request, contentTypeParams map[string]string) (CarPa // not break legacy clients, and responses to requests made via ?format=car // should benefit from block deduplication params.Duplicates = DuplicateBlocksExcluded - } return params, nil diff --git a/gateway/hostname.go b/gateway/hostname.go index 4df23d22c..0bf6b4d72 100644 --- a/gateway/hostname.go +++ b/gateway/hostname.go @@ -201,7 +201,6 @@ func NewHostnameHandler(c Config, backend IPFSBackend, next http.Handler) http.H // else, treat it as an old school gateway, I guess. next.ServeHTTP(w, r) - }) } diff --git a/ipld/merkledag/coding.go b/ipld/merkledag/coding.go index 7c4bfb7e6..ad9440404 100644 --- a/ipld/merkledag/coding.go +++ b/ipld/merkledag/coding.go @@ -75,6 +75,7 @@ func fromImmutableNode(encoded *immutableProtoNode) *ProtoNode { // serialized form needs to be stable, until we start mutating the ProtoNode return n } + func (n *ProtoNode) marshalImmutable() (*immutableProtoNode, error) { links := n.Links() nd, err := qp.BuildMap(dagpb.Type.PBNode, 2, func(ma ipld.MapAssembler) { diff --git a/ipld/merkledag/dagutils/diffenum.go b/ipld/merkledag/dagutils/diffenum.go index 75f86b952..d2d57a8ec 100644 --- a/ipld/merkledag/dagutils/diffenum.go +++ b/ipld/merkledag/dagutils/diffenum.go @@ -72,7 +72,7 @@ func getLinkDiff(a, b ipld.Node) []diffpair { inb[l.Cid.KeyString()] = l } for _, l := range a.Links() { - var key = l.Cid.KeyString() + key := l.Cid.KeyString() ina[key] = l if inb[key] == nil { aonly = append(aonly, l.Cid) diff --git a/ipld/merkledag/dagutils/diffenum_test.go b/ipld/merkledag/dagutils/diffenum_test.go index b96e6f759..41fbfc669 100644 --- a/ipld/merkledag/dagutils/diffenum_test.go +++ b/ipld/merkledag/dagutils/diffenum_test.go @@ -219,7 +219,6 @@ func TestDiffEnumFail(t *testing.T) { if err != nil { t.Fatal(err) } - } func TestDiffEnumRecurse(t *testing.T) { diff --git a/ipld/merkledag/merkledag.go b/ipld/merkledag/merkledag.go index fce59a995..7d830ad2e 100644 --- a/ipld/merkledag/merkledag.go +++ b/ipld/merkledag/merkledag.go @@ -140,7 +140,6 @@ type sesGetter struct { // Get gets a single node from the DAG. func (sg *sesGetter) Get(ctx context.Context, c cid.Cid) (format.Node, error) { blk, err := sg.bs.GetBlock(ctx, c) - if err != nil { return nil, err } @@ -583,7 +582,9 @@ func parallelWalkDepth(ctx context.Context, getLinks GetLinks, root cid.Cid, vis } } -var _ format.LinkGetter = &dagService{} -var _ format.NodeGetter = &dagService{} -var _ format.NodeGetter = &sesGetter{} -var _ format.DAGService = &dagService{} +var ( + _ format.LinkGetter = &dagService{} + _ format.NodeGetter = &dagService{} + _ format.NodeGetter = &sesGetter{} + _ format.DAGService = &dagService{} +) diff --git a/ipld/merkledag/merkledag_test.go b/ipld/merkledag/merkledag_test.go index 6c9af68d7..785159aff 100644 --- a/ipld/merkledag/merkledag_test.go +++ b/ipld/merkledag/merkledag_test.go @@ -263,7 +263,6 @@ func TestLinkChecking(t *testing.T) { } func TestNode(t *testing.T) { - n1 := NodeWithData([]byte("beep")) n2 := NodeWithData([]byte("boop")) n3 := NodeWithData([]byte("beep boop")) @@ -572,7 +571,6 @@ func TestFetchGraphWithDepthLimit(t *testing.T) { return true } return false - } err = WalkDepth(context.Background(), offlineDS.GetLinks, root.Cid(), visitF) @@ -756,7 +754,6 @@ func TestGetRawNodes(t *testing.T) { } func TestProtoNodeResolve(t *testing.T) { - nd := new(ProtoNode) nd.SetLinks([]*ipld.Link{{Name: "foo", Cid: someCid}}) diff --git a/ipld/merkledag/node.go b/ipld/merkledag/node.go index c0f5f02f7..70acbc73e 100644 --- a/ipld/merkledag/node.go +++ b/ipld/merkledag/node.go @@ -29,8 +29,10 @@ var ( var log = logging.Logger("merkledag") // for testing custom CidBuilders -var zeros [256]byte -var zeroCid = mustZeroCid() +var ( + zeros [256]byte + zeroCid = mustZeroCid() +) type immutableProtoNode struct { encoded []byte diff --git a/ipld/merkledag/pb/compat_test.go b/ipld/merkledag/pb/compat_test.go index 529cee0ca..6282356fd 100644 --- a/ipld/merkledag/pb/compat_test.go +++ b/ipld/merkledag/pb/compat_test.go @@ -8,14 +8,16 @@ import ( "testing" ) -var dataZero []byte = make([]byte, 0) -var dataSome []byte = []byte{0, 1, 2, 3, 4} -var cidBytes []byte = []byte{1, 85, 0, 5, 0, 1, 2, 3, 4} -var zeroName string = "" -var someName string = "some name" -var zeroTsize uint64 = 0 -var someTsize uint64 = 1010 -var largeTsize uint64 = 9007199254740991 // JavaScript Number.MAX_SAFE_INTEGER +var ( + dataZero []byte = make([]byte, 0) + dataSome []byte = []byte{0, 1, 2, 3, 4} + cidBytes []byte = []byte{1, 85, 0, 5, 0, 1, 2, 3, 4} + zeroName string = "" + someName string = "some name" + zeroTsize uint64 = 0 + someTsize uint64 = 1010 + largeTsize uint64 = 9007199254740991 // JavaScript Number.MAX_SAFE_INTEGER +) type testCase struct { name string diff --git a/ipld/merkledag/pb/merkledag.pb.go b/ipld/merkledag/pb/merkledag.pb.go index 4646b7325..428459527 100644 --- a/ipld/merkledag/pb/merkledag.pb.go +++ b/ipld/merkledag/pb/merkledag.pb.go @@ -26,9 +26,11 @@ Do *not regenerate this file. ` // Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf +var ( + _ = proto.Marshal + _ = fmt.Errorf + _ = math.Inf +) // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. @@ -54,9 +56,11 @@ func (*PBLink) ProtoMessage() {} func (*PBLink) Descriptor() ([]byte, []int) { return fileDescriptor_10837cc3557cec00, []int{0} } + func (m *PBLink) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } + func (m *PBLink) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { return xxx_messageInfo_PBLink.Marshal(b, m, deterministic) @@ -69,12 +73,15 @@ func (m *PBLink) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return b[:n], nil } } + func (m *PBLink) XXX_Merge(src proto.Message) { xxx_messageInfo_PBLink.Merge(m, src) } + func (m *PBLink) XXX_Size() int { return m.Size() } + func (m *PBLink) XXX_DiscardUnknown() { xxx_messageInfo_PBLink.DiscardUnknown(m) } @@ -118,9 +125,11 @@ func (*PBNode) ProtoMessage() {} func (*PBNode) Descriptor() ([]byte, []int) { return fileDescriptor_10837cc3557cec00, []int{1} } + func (m *PBNode) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } + func (m *PBNode) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { return xxx_messageInfo_PBNode.Marshal(b, m, deterministic) @@ -133,12 +142,15 @@ func (m *PBNode) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return b[:n], nil } } + func (m *PBNode) XXX_Merge(src proto.Message) { xxx_messageInfo_PBNode.Merge(m, src) } + func (m *PBNode) XXX_Size() int { return m.Size() } + func (m *PBNode) XXX_DiscardUnknown() { xxx_messageInfo_PBNode.DiscardUnknown(m) } @@ -236,6 +248,7 @@ func (pbLink *PBLink) VerboseEqual(that interface{}) error { } return nil } + func (pbLink *PBLink) Equal(that interface{}) bool { if that == nil { return pbLink == nil @@ -281,6 +294,7 @@ func (pbLink *PBLink) Equal(that interface{}) bool { } return true } + func (pbLink *PBNode) VerboseEqual(that interface{}) error { if that == nil { if pbLink == nil { @@ -358,6 +372,7 @@ func (pbNode *PBNode) Equal(that interface{}) bool { } return true } + func (pbLink *PBLink) GoString() string { if pbLink == nil { return "nil" @@ -379,6 +394,7 @@ func (pbLink *PBLink) GoString() string { s = append(s, "}") return strings.Join(s, "") } + func (pbNode *PBNode) GoString() string { if pbNode == nil { return "nil" @@ -397,6 +413,7 @@ func (pbNode *PBNode) GoString() string { s = append(s, "}") return strings.Join(s, "") } + func valueToGoStringMerkledag(v interface{}, typ string) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -405,6 +422,7 @@ func valueToGoStringMerkledag(v interface{}, typ string) string { pv := reflect.Indirect(rv).Interface() return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv) } + func (m *PBLink) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -510,6 +528,7 @@ func encodeVarintMerkledag(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } + func NewPopulatedPBLink(r randyMerkledag, easy bool) *PBLink { this := &PBLink{} if r.Intn(5) != 0 { @@ -573,6 +592,7 @@ func randUTF8RuneMerkledag(r randyMerkledag) rune { } return rune(ru + 61) } + func randStringMerkledag(r randyMerkledag) string { v6 := r.Intn(100) tmps := make([]rune, v6) @@ -581,6 +601,7 @@ func randStringMerkledag(r randyMerkledag) string { } return string(tmps) } + func randUnrecognizedMerkledag(r randyMerkledag, maxFieldNumber int) (dAtA []byte) { l := r.Intn(5) for i := 0; i < l; i++ { @@ -593,6 +614,7 @@ func randUnrecognizedMerkledag(r randyMerkledag, maxFieldNumber int) (dAtA []byt } return dAtA } + func randFieldMerkledag(dAtA []byte, r randyMerkledag, fieldNumber int, wire int) []byte { key := uint32(fieldNumber)<<3 | uint32(wire) switch wire { @@ -619,6 +641,7 @@ func randFieldMerkledag(dAtA []byte, r randyMerkledag, fieldNumber int, wire int } return dAtA } + func encodeVarintPopulateMerkledag(dAtA []byte, v uint64) []byte { for v >= 1<<7 { dAtA = append(dAtA, uint8(uint64(v)&0x7f|0x80)) @@ -627,6 +650,7 @@ func encodeVarintPopulateMerkledag(dAtA []byte, v uint64) []byte { dAtA = append(dAtA, uint8(v)) return dAtA } + func (m *PBLink) Size() (n int) { if m == nil { return 0 @@ -675,11 +699,13 @@ func (m *PBNode) Size() (n int) { func sovMerkledag(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } + func (pbLink *PBLink) String() string { if pbLink == nil { return "nil" } - s := strings.Join([]string{`&PBLink{`, + s := strings.Join([]string{ + `&PBLink{`, `Hash:` + valueToStringMerkledag(pbLink.Hash) + `,`, `Name:` + valueToStringMerkledag(pbLink.Name) + `,`, `Tsize:` + valueToStringMerkledag(pbLink.Tsize) + `,`, @@ -688,6 +714,7 @@ func (pbLink *PBLink) String() string { }, "") return s } + func (pbNode *PBNode) String() string { if pbNode == nil { return "nil" @@ -697,7 +724,8 @@ func (pbNode *PBNode) String() string { repeatedStringForLinks += strings.Replace(f.String(), "PBLink", "PBLink", 1) + "," } repeatedStringForLinks += "}" - s := strings.Join([]string{`&PBNode{`, + s := strings.Join([]string{ + `&PBNode{`, `Data:` + valueToStringMerkledag(pbNode.Data) + `,`, `Links:` + repeatedStringForLinks + `,`, `XXX_unrecognized:` + fmt.Sprintf("%v", pbNode.XXX_unrecognized) + `,`, @@ -705,6 +733,7 @@ func (pbNode *PBNode) String() string { }, "") return s } + func valueToStringMerkledag(v interface{}) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -713,6 +742,7 @@ func valueToStringMerkledag(v interface{}) string { pv := reflect.Indirect(rv).Interface() return fmt.Sprintf("*%v", pv) } + func (m *PBLink) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -854,6 +884,7 @@ func (m *PBLink) Unmarshal(dAtA []byte) error { } return nil } + func (m *PBNode) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -976,6 +1007,7 @@ func (m *PBNode) Unmarshal(dAtA []byte) error { } return nil } + func skipMerkledag(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/ipld/merkledag/pb/merkledagpb_test.go b/ipld/merkledag/pb/merkledagpb_test.go index f72b306da..da757b6b2 100644 --- a/ipld/merkledag/pb/merkledagpb_test.go +++ b/ipld/merkledag/pb/merkledagpb_test.go @@ -18,9 +18,11 @@ import ( ) // Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf +var ( + _ = proto.Marshal + _ = fmt.Errorf + _ = math.Inf +) func TestPBLinkProto(t *testing.T) { seed := time.Now().UnixNano() @@ -247,6 +249,7 @@ func TestPBLinkJSON(t *testing.T) { t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } + func TestPBNodeJSON(t *testing.T) { seed := time.Now().UnixNano() popr := math_rand.New(math_rand.NewSource(seed)) @@ -268,6 +271,7 @@ func TestPBNodeJSON(t *testing.T) { t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } + func TestPBLinkProtoText(t *testing.T) { seed := time.Now().UnixNano() popr := math_rand.New(math_rand.NewSource(seed)) @@ -351,6 +355,7 @@ func TestPBLinkVerboseEqual(t *testing.T) { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } + func TestPBNodeVerboseEqual(t *testing.T) { popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedPBNode(popr, false) @@ -366,6 +371,7 @@ func TestPBNodeVerboseEqual(t *testing.T) { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } + func TestPBLinkGoString(t *testing.T) { popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedPBLink(popr, false) @@ -379,6 +385,7 @@ func TestPBLinkGoString(t *testing.T) { t.Fatal(err) } } + func TestPBNodeGoString(t *testing.T) { popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedPBNode(popr, false) @@ -392,6 +399,7 @@ func TestPBNodeGoString(t *testing.T) { t.Fatal(err) } } + func TestPBLinkSize(t *testing.T) { seed := time.Now().UnixNano() popr := math_rand.New(math_rand.NewSource(seed)) @@ -473,6 +481,7 @@ func TestPBLinkStringer(t *testing.T) { t.Fatalf("String want %v got %v", s1, s2) } } + func TestPBNodeStringer(t *testing.T) { popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedPBNode(popr, false) @@ -483,4 +492,4 @@ func TestPBNodeStringer(t *testing.T) { } } -//These tests are generated by github.com/gogo/protobuf/plugin/testgen +// These tests are generated by github.com/gogo/protobuf/plugin/testgen diff --git a/ipld/merkledag/pb/stability_test.go b/ipld/merkledag/pb/stability_test.go index 5da833713..245296a80 100644 --- a/ipld/merkledag/pb/stability_test.go +++ b/ipld/merkledag/pb/stability_test.go @@ -20,5 +20,4 @@ func TestStability(t *testing.T) { t.Logf("%q", d) t.Fatal("protobuf not stable") } - } diff --git a/ipld/merkledag/traverse/traverse.go b/ipld/merkledag/traverse/traverse.go index dbc426fa9..a3836e385 100644 --- a/ipld/merkledag/traverse/traverse.go +++ b/ipld/merkledag/traverse/traverse.go @@ -63,7 +63,6 @@ func (t *traversal) callFunc(next State) error { // // the error handling is a little complicated. func (t *traversal) getNode(link *ipld.Link) (ipld.Node, error) { - getNode := func(l *ipld.Link) (ipld.Node, error) { next, err := l.GetNode(context.TODO(), t.opts.DAG) if err != nil { @@ -164,7 +163,6 @@ func dfsDescend(df dfsFunc, curr State, t *traversal) error { } func bfsTraverse(root State, t *traversal) error { - if skip, err := t.shouldSkip(root.Node); skip || err != nil { return err } diff --git a/ipld/unixfs/file/unixfile.go b/ipld/unixfs/file/unixfile.go index 4eae1bf07..5ef968d1b 100644 --- a/ipld/unixfs/file/unixfile.go +++ b/ipld/unixfs/file/unixfile.go @@ -179,5 +179,7 @@ func NewUnixfsFile(ctx context.Context, dserv ipld.DAGService, nd ipld.Node) (fi }, nil } -var _ files.Directory = &ufsDirectory{} -var _ files.File = &ufsFile{} +var ( + _ files.Directory = &ufsDirectory{} + _ files.File = &ufsFile{} +) diff --git a/ipld/unixfs/hamt/hamt_test.go b/ipld/unixfs/hamt/hamt_test.go index e6892919e..6d7c56d9f 100644 --- a/ipld/unixfs/hamt/hamt_test.go +++ b/ipld/unixfs/hamt/hamt_test.go @@ -79,7 +79,6 @@ func assertLink(s *Shard, name string, found bool) error { } func assertLinksEqual(linksA []*ipld.Link, linksB []*ipld.Link) error { - if len(linksA) != len(linksB) { return fmt.Errorf("links arrays are different sizes") } @@ -164,7 +163,7 @@ func TestDirBuilding(t *testing.T) { t.Fatal(err) } - //printDag(ds, nd, 0) + // printDag(ds, nd, 0) k := nd.Cid() diff --git a/ipld/unixfs/importer/balanced/balanced_test.go b/ipld/unixfs/importer/balanced/balanced_test.go index 0c2d7a29f..17afbb232 100644 --- a/ipld/unixfs/importer/balanced/balanced_test.go +++ b/ipld/unixfs/importer/balanced/balanced_test.go @@ -298,7 +298,6 @@ func TestSeekingStress(t *testing.T) { t.Fatal(err) } } - } func TestSeekingConsistency(t *testing.T) { diff --git a/ipld/unixfs/importer/helpers/dagbuilder.go b/ipld/unixfs/importer/helpers/dagbuilder.go index 6d6014311..25514d795 100644 --- a/ipld/unixfs/importer/helpers/dagbuilder.go +++ b/ipld/unixfs/importer/helpers/dagbuilder.go @@ -177,7 +177,6 @@ func (db *DagBuilderHelper) NewLeafNode(data []byte, fsNodeType pb.Data_DataType // NOTE: This function creates raw data nodes so it only works // for the `trickle.Layout`. func (db *DagBuilderHelper) FillNodeLayer(node *FSNodeOverDag) error { - // while we have room AND we're not done for node.NumChildren() < db.maxlinks && !db.Done() { child, childFileSize, err := db.NewLeafDataNode(ft.TRaw) diff --git a/ipld/unixfs/importer/helpers/helpers.go b/ipld/unixfs/importer/helpers/helpers.go index 20cb598e6..0a199d2b6 100644 --- a/ipld/unixfs/importer/helpers/helpers.go +++ b/ipld/unixfs/importer/helpers/helpers.go @@ -8,8 +8,10 @@ import ( var BlockSizeLimit = 1048576 // 1 MB // rough estimates on expected sizes -var roughLinkBlockSize = 1 << 13 // 8KB -var roughLinkSize = 34 + 8 + 5 // sha256 multihash + size + no name + protobuf framing +var ( + roughLinkBlockSize = 1 << 13 // 8KB + roughLinkSize = 34 + 8 + 5 // sha256 multihash + size + no name + protobuf framing +) // DefaultLinksPerBlock governs how the importer decides how many links there // will be per block. This calculation is based on expected distributions of: diff --git a/ipld/unixfs/importer/trickle/trickle_test.go b/ipld/unixfs/importer/trickle/trickle_test.go index 59231f49c..70bc2dd13 100644 --- a/ipld/unixfs/importer/trickle/trickle_test.go +++ b/ipld/unixfs/importer/trickle/trickle_test.go @@ -431,7 +431,6 @@ func testSeekingStress(t *testing.T, rawLeaves UseRawLeaves) { t.Fatal(err) } } - } func TestSeekingConsistency(t *testing.T) { diff --git a/ipld/unixfs/io/dagreader.go b/ipld/unixfs/io/dagreader.go index 83d33af6c..77dc8d921 100644 --- a/ipld/unixfs/io/dagreader.go +++ b/ipld/unixfs/io/dagreader.go @@ -100,7 +100,6 @@ func NewDagReader(ctx context.Context, n ipld.Node, serv ipld.NodeGetter) (DagRe // dagReader provides a way to easily read the data contained in a dag. type dagReader struct { - // Structure to perform the DAG iteration and search, the reader // just needs to add logic to the `Visitor` callback passed to // `Iterate` and `Seek`. @@ -227,7 +226,6 @@ func (dr *dagReader) saveNodeData(node ipld.Node) error { // any errors as it's always reading from a `bytes.Reader` and asking only // the available data in it. func (dr *dagReader) readNodeDataBuffer(out []byte) int { - n, _ := dr.currentNodeData.Read(out) // Ignore the error as the EOF may not be returned in the first // `Read` call, explicitly ask for an empty buffer below to check @@ -253,7 +251,6 @@ func (dr *dagReader) readNodeDataBuffer(out []byte) int { // TODO: Check what part of the logic between the two functions // can be extracted away. func (dr *dagReader) writeNodeDataBuffer(w io.Writer) (int64, error) { - n, err := dr.currentNodeData.WriteTo(w) if err != nil { return n, err @@ -450,7 +447,6 @@ func (dr *dagReader) Seek(offset int64, whence int) (int64, error) { // In the leaf node case the search will stop here. } }) - if err != nil { return 0, err } diff --git a/ipld/unixfs/io/dagreader_test.go b/ipld/unixfs/io/dagreader_test.go index 9787c4281..1f9f93558 100644 --- a/ipld/unixfs/io/dagreader_test.go +++ b/ipld/unixfs/io/dagreader_test.go @@ -186,7 +186,6 @@ func TestRelativeSeek(t *testing.T) { } reader.Seek(-5, io.SeekCurrent) // seek 4 bytes but we read one byte every time so 5 bytes } - } func TestTypeFailures(t *testing.T) { @@ -283,7 +282,6 @@ func TestWriteTo(t *testing.T) { if err != nil { t.Fatal(err) } - } func TestReaderSzie(t *testing.T) { diff --git a/ipld/unixfs/io/directory.go b/ipld/unixfs/io/directory.go index a3638676c..9de460e38 100644 --- a/ipld/unixfs/io/directory.go +++ b/ipld/unixfs/io/directory.go @@ -38,7 +38,6 @@ var DefaultShardWidth = 256 // directory trees is out of its scope, they are managed by the MFS layer // (which is the main consumer of this interface). type Directory interface { - // SetCidBuilder sets the CID Builder of the root node. SetCidBuilder(cid.Builder) diff --git a/ipld/unixfs/mod/dagmodifier_test.go b/ipld/unixfs/mod/dagmodifier_test.go index 14adeca35..fab7a125b 100644 --- a/ipld/unixfs/mod/dagmodifier_test.go +++ b/ipld/unixfs/mod/dagmodifier_test.go @@ -83,6 +83,7 @@ func runAllSubtests(t *testing.T, tfunc func(*testing.T, testu.NodeOpts)) { func TestDagModifierBasic(t *testing.T) { runAllSubtests(t, testDagModifierBasic) } + func testDagModifierBasic(t *testing.T, opts testu.NodeOpts) { dserv := testu.GetDAGServ() b, n := testu.GetRandomNode(t, dserv, 50000, opts) @@ -143,6 +144,7 @@ func testDagModifierBasic(t *testing.T, opts testu.NodeOpts) { func TestMultiWrite(t *testing.T) { runAllSubtests(t, testMultiWrite) } + func testMultiWrite(t *testing.T, opts testu.NodeOpts) { dserv := testu.GetDAGServ() n := testu.GetEmptyNode(t, dserv, opts) @@ -186,6 +188,7 @@ func testMultiWrite(t *testing.T, opts testu.NodeOpts) { func TestMultiWriteAndFlush(t *testing.T) { runAllSubtests(t, testMultiWriteAndFlush) } + func testMultiWriteAndFlush(t *testing.T, opts testu.NodeOpts) { dserv := testu.GetDAGServ() n := testu.GetEmptyNode(t, dserv, opts) @@ -224,6 +227,7 @@ func testMultiWriteAndFlush(t *testing.T, opts testu.NodeOpts) { func TestWriteNewFile(t *testing.T) { runAllSubtests(t, testWriteNewFile) } + func testWriteNewFile(t *testing.T, opts testu.NodeOpts) { dserv := testu.GetDAGServ() n := testu.GetEmptyNode(t, dserv, opts) @@ -256,6 +260,7 @@ func testWriteNewFile(t *testing.T, opts testu.NodeOpts) { func TestMultiWriteCoal(t *testing.T) { runAllSubtests(t, testMultiWriteCoal) } + func testMultiWriteCoal(t *testing.T, opts testu.NodeOpts) { dserv := testu.GetDAGServ() n := testu.GetEmptyNode(t, dserv, opts) @@ -292,6 +297,7 @@ func testMultiWriteCoal(t *testing.T, opts testu.NodeOpts) { func TestLargeWriteChunks(t *testing.T) { runAllSubtests(t, testLargeWriteChunks) } + func testLargeWriteChunks(t *testing.T, opts testu.NodeOpts) { dserv := testu.GetDAGServ() n := testu.GetEmptyNode(t, dserv, opts) @@ -341,6 +347,7 @@ func testLargeWriteChunks(t *testing.T, opts testu.NodeOpts) { func TestDagTruncate(t *testing.T) { runAllSubtests(t, testDagTruncate) } + func testDagTruncate(t *testing.T, opts testu.NodeOpts) { dserv := testu.GetDAGServ() b, n := testu.GetRandomNode(t, dserv, 50000, opts) @@ -473,6 +480,7 @@ func TestDagSync(t *testing.T) { func TestDagTruncateSameSize(t *testing.T) { runAllSubtests(t, testDagTruncateSameSize) } + func testDagTruncateSameSize(t *testing.T, opts testu.NodeOpts) { dserv := testu.GetDAGServ() _, n := testu.GetRandomNode(t, dserv, 50000, opts) @@ -508,6 +516,7 @@ func testDagTruncateSameSize(t *testing.T, opts testu.NodeOpts) { func TestSparseWrite(t *testing.T) { runAllSubtests(t, testSparseWrite) } + func testSparseWrite(t *testing.T, opts testu.NodeOpts) { dserv := testu.GetDAGServ() n := testu.GetEmptyNode(t, dserv, opts) @@ -552,6 +561,7 @@ func testSparseWrite(t *testing.T, opts testu.NodeOpts) { func TestSeekPastEndWrite(t *testing.T) { runAllSubtests(t, testSeekPastEndWrite) } + func testSeekPastEndWrite(t *testing.T, opts testu.NodeOpts) { dserv := testu.GetDAGServ() n := testu.GetEmptyNode(t, dserv, opts) @@ -605,6 +615,7 @@ func testSeekPastEndWrite(t *testing.T, opts testu.NodeOpts) { func TestRelativeSeek(t *testing.T) { runAllSubtests(t, testRelativeSeek) } + func testRelativeSeek(t *testing.T, opts testu.NodeOpts) { dserv := testu.GetDAGServ() n := testu.GetEmptyNode(t, dserv, opts) @@ -641,6 +652,7 @@ func testRelativeSeek(t *testing.T, opts testu.NodeOpts) { func TestInvalidSeek(t *testing.T) { runAllSubtests(t, testInvalidSeek) } + func testInvalidSeek(t *testing.T, opts testu.NodeOpts) { dserv := testu.GetDAGServ() n := testu.GetEmptyNode(t, dserv, opts) @@ -665,6 +677,7 @@ func testInvalidSeek(t *testing.T, opts testu.NodeOpts) { func TestEndSeek(t *testing.T) { runAllSubtests(t, testEndSeek) } + func testEndSeek(t *testing.T, opts testu.NodeOpts) { dserv := testu.GetDAGServ() @@ -713,6 +726,7 @@ func testEndSeek(t *testing.T, opts testu.NodeOpts) { func TestReadAndSeek(t *testing.T) { runAllSubtests(t, testReadAndSeek) } + func testReadAndSeek(t *testing.T, opts testu.NodeOpts) { dserv := testu.GetDAGServ() @@ -765,7 +779,7 @@ func testReadAndSeek(t *testing.T, opts testu.NodeOpts) { t.Fatalf("error: %s, offset %d, reader offset %d", err, dagmod.curWrOff, getOffset(dagmod.read)) } - //read 5,6,7 + // read 5,6,7 readBuf = make([]byte, 3) c, err = dagmod.Read(readBuf) if err != nil { @@ -779,14 +793,13 @@ func testReadAndSeek(t *testing.T, opts testu.NodeOpts) { if readBuf[i] != i+5 { t.Fatalf("wrong value %d [at index %d]", readBuf[i], i) } - } - } func TestCtxRead(t *testing.T) { runAllSubtests(t, testCtxRead) } + func testCtxRead(t *testing.T, opts testu.NodeOpts) { dserv := testu.GetDAGServ() diff --git a/ipld/unixfs/pb/unixfs.pb.go b/ipld/unixfs/pb/unixfs.pb.go index 2f7cb44ab..805c11289 100644 --- a/ipld/unixfs/pb/unixfs.pb.go +++ b/ipld/unixfs/pb/unixfs.pb.go @@ -5,14 +5,17 @@ package unixfs_pb import ( fmt "fmt" - proto "github.com/gogo/protobuf/proto" math "math" + + proto "github.com/gogo/protobuf/proto" ) // Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf +var ( + _ = proto.Marshal + _ = fmt.Errorf + _ = math.Inf +) // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. @@ -90,18 +93,23 @@ func (*Data) ProtoMessage() {} func (*Data) Descriptor() ([]byte, []int) { return fileDescriptor_e2fd76cc44dfc7c3, []int{0} } + func (m *Data) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Data.Unmarshal(m, b) } + func (m *Data) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Data.Marshal(b, m, deterministic) } + func (m *Data) XXX_Merge(src proto.Message) { xxx_messageInfo_Data.Merge(m, src) } + func (m *Data) XXX_Size() int { return xxx_messageInfo_Data.Size(m) } + func (m *Data) XXX_DiscardUnknown() { xxx_messageInfo_Data.DiscardUnknown(m) } @@ -163,18 +171,23 @@ func (*Metadata) ProtoMessage() {} func (*Metadata) Descriptor() ([]byte, []int) { return fileDescriptor_e2fd76cc44dfc7c3, []int{1} } + func (m *Metadata) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Metadata.Unmarshal(m, b) } + func (m *Metadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Metadata.Marshal(b, m, deterministic) } + func (m *Metadata) XXX_Merge(src proto.Message) { xxx_messageInfo_Metadata.Merge(m, src) } + func (m *Metadata) XXX_Size() int { return xxx_messageInfo_Metadata.Size(m) } + func (m *Metadata) XXX_DiscardUnknown() { xxx_messageInfo_Metadata.DiscardUnknown(m) } diff --git a/ipld/unixfs/unixfs.go b/ipld/unixfs/unixfs.go index ebb334e5a..4131df837 100644 --- a/ipld/unixfs/unixfs.go +++ b/ipld/unixfs/unixfs.go @@ -77,7 +77,7 @@ func FolderPBData() []byte { data, err := proto.Marshal(pbfile) if err != nil { - //this really shouldnt happen, i promise + // this really shouldnt happen, i promise panic(err) } return data @@ -174,7 +174,6 @@ func size(pbdata *pb.Data) (uint64, error) { // to guarantee that the required (`Type` and `Filesize`) fields in the `format` // structure are initialized before marshaling (in `GetBytes()`). type FSNode struct { - // UnixFS format defined as a protocol buffers message. format pb.Data } diff --git a/ipld/unixfs/unixfs_test.go b/ipld/unixfs/unixfs_test.go index d06ababe2..b785be8ad 100644 --- a/ipld/unixfs/unixfs_test.go +++ b/ipld/unixfs/unixfs_test.go @@ -165,7 +165,6 @@ func TestMetadata(t *testing.T) { if !mimeAiff { t.Fatal("Metadata does not Marshal and Unmarshal properly!") } - } func TestIsDir(t *testing.T) { diff --git a/ipns/pb/record.pb.go b/ipns/pb/record.pb.go index fe6950929..1f0effbd8 100644 --- a/ipns/pb/record.pb.go +++ b/ipns/pb/record.pb.go @@ -7,10 +7,11 @@ package pb import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( @@ -226,12 +227,15 @@ func file_record_proto_rawDescGZIP() []byte { return file_record_proto_rawDescData } -var file_record_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_record_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_record_proto_goTypes = []interface{}{ - (IpnsRecord_ValidityType)(0), // 0: github.com.boxo.ipns.pb.IpnsRecord.ValidityType - (*IpnsRecord)(nil), // 1: github.com.boxo.ipns.pb.IpnsRecord -} +var ( + file_record_proto_enumTypes = make([]protoimpl.EnumInfo, 1) + file_record_proto_msgTypes = make([]protoimpl.MessageInfo, 1) + file_record_proto_goTypes = []interface{}{ + (IpnsRecord_ValidityType)(0), // 0: github.com.boxo.ipns.pb.IpnsRecord.ValidityType + (*IpnsRecord)(nil), // 1: github.com.boxo.ipns.pb.IpnsRecord + } +) + var file_record_proto_depIdxs = []int32{ 0, // 0: github.com.boxo.ipns.pb.IpnsRecord.validityType:type_name -> github.com.boxo.ipns.pb.IpnsRecord.ValidityType 1, // [1:1] is the sub-list for method output_type diff --git a/keystore/keystore.go b/keystore/keystore.go index b762686e4..4f6b250d1 100644 --- a/keystore/keystore.go +++ b/keystore/keystore.go @@ -1,13 +1,12 @@ package keystore import ( + "encoding/base32" "fmt" "os" "path/filepath" "strings" - "encoding/base32" - logging "github.com/ipfs/go-log/v2" ci "github.com/libp2p/go-libp2p/core/crypto" ) @@ -46,7 +45,7 @@ type FSKeystore struct { // NewFSKeystore returns a new filesystem-backed keystore. func NewFSKeystore(dir string) (*FSKeystore, error) { - err := os.Mkdir(dir, 0700) + err := os.Mkdir(dir, 0o700) switch { case os.IsExist(err): case err == nil: @@ -87,7 +86,7 @@ func (ks *FSKeystore) Put(name string, k ci.PrivKey) error { kp := filepath.Join(ks.dir, name) - fi, err := os.OpenFile(kp, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0400) + fi, err := os.OpenFile(kp, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0o400) if err != nil { if os.IsExist(err) { err = ErrKeyExists diff --git a/keystore/keystore_test.go b/keystore/keystore_test.go index 29e1cf849..fbd16a0e0 100644 --- a/keystore/keystore_test.go +++ b/keystore/keystore_test.go @@ -140,7 +140,6 @@ func TestKeystoreBasics(t *testing.T) { func TestInvalidKeyFiles(t *testing.T) { tdir, err := os.MkdirTemp("", "keystore-test") - if err != nil { t.Fatal(err) } @@ -164,12 +163,12 @@ func TestInvalidKeyFiles(t *testing.T) { t.Fatal(err) } - err = os.WriteFile(filepath.Join(ks.dir, encodedName), bytes, 0644) + err = os.WriteFile(filepath.Join(ks.dir, encodedName), bytes, 0o644) if err != nil { t.Fatal(err) } - err = os.WriteFile(filepath.Join(ks.dir, "z.invalid"), bytes, 0644) + err = os.WriteFile(filepath.Join(ks.dir, "z.invalid"), bytes, 0o644) if err != nil { t.Fatal(err) } diff --git a/mfs/dir.go b/mfs/dir.go index 27e012da9..ab9812754 100644 --- a/mfs/dir.go +++ b/mfs/dir.go @@ -17,9 +17,11 @@ import ( ipld "github.com/ipfs/go-ipld-format" ) -var ErrNotYetImplemented = errors.New("not yet implemented") -var ErrInvalidChild = errors.New("invalid child node") -var ErrDirExists = errors.New("directory already has entry by that name") +var ( + ErrNotYetImplemented = errors.New("not yet implemented") + ErrInvalidChild = errors.New("invalid child node") + ErrDirExists = errors.New("directory already has entry by that name") +) // TODO: There's too much functionality associated with this structure, // let's organize it (and if possible extract part of it elsewhere) diff --git a/mfs/mfs_test.go b/mfs/mfs_test.go index e57404b82..9ecdbffd5 100644 --- a/mfs/mfs_test.go +++ b/mfs/mfs_test.go @@ -213,7 +213,6 @@ func setupRoot(ctx context.Context, t testing.TB) (ipld.DAGService, *Root) { fmt.Println("PUBLISHED: ", c) return nil }) - if err != nil { t.Fatal(err) } @@ -644,7 +643,6 @@ func TestMfsDirListNames(t *testing.T) { } list, err := rootdir.ListNames(ctx) - if err != nil { t.Fatal(err) } @@ -1488,7 +1486,6 @@ func getFileHandle(r *Root, path string, create bool, builder cid.Builder) (*Fil } func FuzzMkdirAndWriteConcurrently(f *testing.F) { - testCases := []struct { flush bool mkparents bool @@ -1567,5 +1564,4 @@ func FuzzMkdirAndWriteConcurrently(f *testing.F) { t.Logf("error writting to file from filepath %s: %s", filepath, err) } }) - } diff --git a/mfs/root.go b/mfs/root.go index d807da3bd..c08d2d053 100644 --- a/mfs/root.go +++ b/mfs/root.go @@ -17,8 +17,10 @@ import ( ) // TODO: Remove if not used. -var ErrNotExist = errors.New("no such rootfs") -var ErrClosed = errors.New("file closed") +var ( + ErrNotExist = errors.New("no such rootfs") + ErrClosed = errors.New("file closed") +) var log = logging.Logger("mfs") @@ -85,7 +87,6 @@ func IsFile(fsn FSNode) bool { // Root represents the root of a filesystem tree. type Root struct { - // Root directory of the MFS layout. dir *Directory @@ -94,7 +95,6 @@ type Root struct { // NewRoot creates a new Root and starts up a republisher routine for it. func NewRoot(parent context.Context, ds ipld.DAGService, node *dag.ProtoNode, pf PubFunc) (*Root, error) { - var repub *Republisher if pf != nil { repub = NewRepublisher(parent, pf, time.Millisecond*300, time.Second*3) diff --git a/namesys/interface.go b/namesys/interface.go index 655be179d..5d50936ee 100644 --- a/namesys/interface.go +++ b/namesys/interface.go @@ -30,9 +30,8 @@ For command-line bindings to this functionality, see: package namesys import ( - "errors" - "context" + "errors" opts "github.com/ipfs/boxo/coreiface/options/namesys" "github.com/ipfs/boxo/path" @@ -69,7 +68,6 @@ type Result struct { // Resolver is an object capable of resolving names. type Resolver interface { - // Resolve performs a recursive lookup, returning the dereferenced // path. For example, if ipfs.io has a DNS TXT record pointing to // /ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy diff --git a/namesys/namesys.go b/namesys/namesys.go index de74f1488..df4403570 100644 --- a/namesys/namesys.go +++ b/namesys/namesys.go @@ -198,7 +198,6 @@ func (ns *mpns) resolveOnceAsync(ctx context.Context, name string, options opts. var res resolver ipnsKey, err := peer.Decode(key) - // CIDs in IPNS are expected to have libp2p-key multicodec // We ease the transition by returning a more meaningful error with a valid CID if err != nil { diff --git a/path/path.go b/path/path.go index 6d53ade04..a9b36c3ce 100644 --- a/path/path.go +++ b/path/path.go @@ -60,7 +60,6 @@ func (p Path) IsJustAKey() bool { // segment, separately. If there is no more to pop (the path is just a key), // the original path is returned. func (p Path) PopLastSegment() (Path, string, error) { - if p.IsJustAKey() { return p, "", nil } @@ -107,7 +106,7 @@ func ParsePath(txt string) (Path, error) { return "", &ErrInvalidPath{error: fmt.Errorf("invalid ipfs path"), path: txt} } - //TODO: make this smarter + // TODO: make this smarter switch parts[1] { case "ipfs", "ipld": if parts[2] == "" { diff --git a/path/resolver/resolver_test.go b/path/resolver/resolver_test.go index c91d950f1..c20f9306d 100644 --- a/path/resolver/resolver_test.go +++ b/path/resolver/resolver_test.go @@ -132,6 +132,7 @@ func TestRecurivePathResolution(t *testing.T) { p.String(), rCid.String(), cKey.String())) } } + func TestResolveToLastNode_ErrNoLink(t *testing.T) { ctx := context.Background() bsrv := dagmock.Bserv() diff --git a/pinning/remote/client/client.go b/pinning/remote/client/client.go index 6c869d40f..e1da64ffb 100644 --- a/pinning/remote/client/client.go +++ b/pinning/remote/client/client.go @@ -114,8 +114,10 @@ func (pinLsOpts) FilterAfter(t time.Time) LsOption { } } -const recordLimit = 1000 -const defaultLimit = 10 +const ( + recordLimit = 1000 + defaultLimit = 10 +) func (pinLsOpts) Limit(limit int) LsOption { return func(options *lsSettings) error { diff --git a/pinning/remote/client/openapi/client.go b/pinning/remote/client/openapi/client.go index b3cea998b..84ceeaafb 100644 --- a/pinning/remote/client/openapi/client.go +++ b/pinning/remote/client/openapi/client.go @@ -168,8 +168,8 @@ func (c *APIClient) prepareRequest( formParams url.Values, formFileName string, fileName string, - fileBytes []byte) (localVarRequest *http.Request, err error) { - + fileBytes []byte, +) (localVarRequest *http.Request, err error) { var body *bytes.Buffer // Detect postBody type and post. diff --git a/pinning/remote/client/openapi/response.go b/pinning/remote/client/openapi/response.go index 8f9fb0b08..822455243 100644 --- a/pinning/remote/client/openapi/response.go +++ b/pinning/remote/client/openapi/response.go @@ -33,14 +33,12 @@ type APIResponse struct { // NewAPIResponse returns a new APIResonse object. func NewAPIResponse(r *http.Response) *APIResponse { - response := &APIResponse{Response: r} return response } // NewAPIResponseWithError returns a new APIResponse object with the provided error message. func NewAPIResponseWithError(errorMessage string) *APIResponse { - response := &APIResponse{Message: errorMessage} return response } diff --git a/provider/internal/queue/queue.go b/provider/internal/queue/queue.go index 800d3be4e..2fc32baf5 100644 --- a/provider/internal/queue/queue.go +++ b/provider/internal/queue/queue.go @@ -130,7 +130,6 @@ func (q *Queue) worker() { } case dequeue <- c: err := q.ds.Delete(q.ctx, k) - if err != nil { log.Errorf("Failed to delete queued cid %s with key %s: %s", c, k, err) continue diff --git a/provider/provider.go b/provider/provider.go index a3eff2f04..6fb021695 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -64,7 +64,6 @@ func NewPinnedProvider(onlyRoots bool, pinning pin.Pinner, fetchConfig fetcher.F case outCh <- c: } } - }() return outCh, nil diff --git a/provider/reprovider.go b/provider/reprovider.go index e95227ee0..f9d1b4203 100644 --- a/provider/reprovider.go +++ b/provider/reprovider.go @@ -91,8 +91,10 @@ type Ready interface { // BatchProvidingSystem instances type Option func(system *reprovider) error -var lastReprovideKey = datastore.NewKey("/reprovide/lastreprovide") -var DefaultKeyPrefix = datastore.NewKey("/provider") +var ( + lastReprovideKey = datastore.NewKey("/reprovide/lastreprovide") + DefaultKeyPrefix = datastore.NewKey("/provider") +) // New creates a new [System]. By default it is offline, that means it will // enqueue tasks in ds. diff --git a/routing/http/client/client_test.go b/routing/http/client/client_test.go index 880fa33e1..06ad1d6b4 100644 --- a/routing/http/client/client_test.go +++ b/routing/http/client/client_test.go @@ -31,6 +31,7 @@ func (m *mockContentRouter) FindProviders(ctx context.Context, key cid.Cid, limi args := m.Called(ctx, key, limit) return args.Get(0).(iter.ResultIter[types.ProviderResponse]), args.Error(1) } + func (m *mockContentRouter) ProvideBitswap(ctx context.Context, req *server.BitswapWriteProvideRequest) (time.Duration, error) { args := m.Called(ctx, req) return args.Get(0).(time.Duration), args.Error(1) diff --git a/routing/http/client/transport_test.go b/routing/http/client/transport_test.go index 7da545062..82567bb47 100644 --- a/routing/http/client/transport_test.go +++ b/routing/http/client/transport_test.go @@ -71,7 +71,6 @@ func TestResponseBodyLimitedTransport(t *testing.T) { } else { assert.Contains(t, err.Error(), c.expErr) } - }) } } diff --git a/routing/http/contentrouter/contentrouter_test.go b/routing/http/contentrouter/contentrouter_test.go index 4ca620c5d..3830482e2 100644 --- a/routing/http/contentrouter/contentrouter_test.go +++ b/routing/http/contentrouter/contentrouter_test.go @@ -27,10 +27,12 @@ func (m *mockClient) FindProviders(ctx context.Context, key cid.Cid) (iter.Resul args := m.Called(ctx, key) return args.Get(0).(iter.ResultIter[types.ProviderResponse]), args.Error(1) } + func (m *mockClient) Ready(ctx context.Context) (bool, error) { args := m.Called(ctx) return args.Bool(0), args.Error(1) } + func makeCID() cid.Cid { buf := make([]byte, 63) _, err := rand.Read(buf) @@ -78,7 +80,6 @@ func TestProvide(t *testing.T) { if c.expNotProvided { client.AssertNumberOfCalls(t, "ProvideBitswap", 0) } - }) } } diff --git a/routing/http/server/server.go b/routing/http/server/server.go index 47c075f0a..dc0026fbf 100644 --- a/routing/http/server/server.go +++ b/routing/http/server/server.go @@ -35,8 +35,10 @@ const ( var logger = logging.Logger("service/server/delegatedrouting") -const ProvidePath = "/routing/v1/providers/" -const FindProvidersPath = "/routing/v1/providers/{cid}" +const ( + ProvidePath = "/routing/v1/providers/" + FindProvidersPath = "/routing/v1/providers/{cid}" +) type FindProvidersAsyncResponse struct { ProviderResponse types.ProviderResponse @@ -139,7 +141,6 @@ func (s *server) provide(w http.ResponseWriter, httpReq *http.Request) { keys := make([]cid.Cid, len(v.Payload.Keys)) for i, k := range v.Payload.Keys { keys[i] = k.Cid - } addrs := make([]multiaddr.Multiaddr, len(v.Payload.Addrs)) for i, a := range v.Payload.Addrs { diff --git a/routing/http/server/server_test.go b/routing/http/server/server_test.go index 69db7d556..db607aba6 100644 --- a/routing/http/server/server_test.go +++ b/routing/http/server/server_test.go @@ -26,7 +26,8 @@ func TestHeaders(t *testing.T) { {Val: &types.ReadBitswapProviderRecord{ Protocol: "transport-bitswap", Schema: types.SchemaBitswap, - }}}, + }}, + }, ) c := "baeabep4vu3ceru7nerjjbk37sxb7wmftteve4hcosmyolsbsiubw2vr6pqzj6mw7kv6tbn6nqkkldnklbjgm5tzbi4hkpkled4xlcr7xz4bq" @@ -78,7 +79,8 @@ func TestResponse(t *testing.T) { Schema: types.SchemaBitswap, ID: &pid2, Addrs: []types.Multiaddr{}, - }}}, + }}, + }, ) router := &mockContentRouter{} @@ -123,6 +125,7 @@ func (m *mockContentRouter) FindProviders(ctx context.Context, key cid.Cid, limi args := m.Called(ctx, key, limit) return args.Get(0).(iter.ResultIter[types.ProviderResponse]), args.Error(1) } + func (m *mockContentRouter) ProvideBitswap(ctx context.Context, req *BitswapWriteProvideRequest) (time.Duration, error) { args := m.Called(ctx, req) return args.Get(0).(time.Duration), args.Error(1) diff --git a/routing/http/types/iter/json_test.go b/routing/http/types/iter/json_test.go index 99c3bde07..f3e5a3341 100644 --- a/routing/http/types/iter/json_test.go +++ b/routing/http/types/iter/json_test.go @@ -69,5 +69,4 @@ func TestJSONIter(t *testing.T) { } }) } - } diff --git a/routing/http/types/provider_bitswap.go b/routing/http/types/provider_bitswap.go index 66243dd5d..f0b5056e4 100644 --- a/routing/http/types/provider_bitswap.go +++ b/routing/http/types/provider_bitswap.go @@ -162,8 +162,10 @@ func (wbprr *WriteBitswapProviderRecordResponse) GetSchema() string { return wbprr.Schema } -var _ ReadProviderRecord = &ReadBitswapProviderRecord{} -var _ ProviderResponse = &ReadBitswapProviderRecord{} +var ( + _ ReadProviderRecord = &ReadBitswapProviderRecord{} + _ ProviderResponse = &ReadBitswapProviderRecord{} +) // ReadBitswapProviderRecord is a provider result with parameters for bitswap providers type ReadBitswapProviderRecord struct { diff --git a/routing/http/types/provider_unknown.go b/routing/http/types/provider_unknown.go index 3dadc0e9b..915cac481 100644 --- a/routing/http/types/provider_unknown.go +++ b/routing/http/types/provider_unknown.go @@ -6,9 +6,11 @@ import ( "github.com/ipfs/boxo/routing/http/internal/drjson" ) -var _ ReadProviderRecord = &UnknownProviderRecord{} -var _ WriteProviderRecord = &UnknownProviderRecord{} -var _ ProviderResponse = &UnknownProviderRecord{} +var ( + _ ReadProviderRecord = &UnknownProviderRecord{} + _ WriteProviderRecord = &UnknownProviderRecord{} + _ ProviderResponse = &UnknownProviderRecord{} +) // UnknownProviderRecord is used when we cannot parse the provider record using `GetProtocol` type UnknownProviderRecord struct { diff --git a/routing/http/types/time.go b/routing/http/types/time.go index 1d938807e..4b08f9bed 100644 --- a/routing/http/types/time.go +++ b/routing/http/types/time.go @@ -12,6 +12,7 @@ type Time struct{ time.Time } func (t *Time) MarshalJSON() ([]byte, error) { return drjson.MarshalJSONBytes(t.Time.UnixMilli()) } + func (t *Time) UnmarshalJSON(b []byte) error { var timestamp int64 err := json.Unmarshal(b, ×tamp) diff --git a/routing/mock/centralized_test.go b/routing/mock/centralized_test.go index 403e21350..983d6a23b 100644 --- a/routing/mock/centralized_test.go +++ b/routing/mock/centralized_test.go @@ -13,10 +13,9 @@ import ( ) func TestKeyNotFound(t *testing.T) { - - var pi = tnet.RandIdentityOrFatal(t) - var key = cid.NewCidV0(u.Hash([]byte("mock key"))) - var ctx = context.Background() + pi := tnet.RandIdentityOrFatal(t) + key := cid.NewCidV0(u.Hash([]byte("mock key"))) + ctx := context.Background() rs := NewServer() providers := rs.Client(pi).FindProvidersAsync(ctx, key, 10) diff --git a/routing/none/none_client.go b/routing/none/none_client.go index 6f400b54a..c8bcc1a3c 100644 --- a/routing/none/none_client.go +++ b/routing/none/none_client.go @@ -13,8 +13,7 @@ import ( "github.com/libp2p/go-libp2p/core/routing" ) -type nilclient struct { -} +type nilclient struct{} func (c *nilclient) PutValue(_ context.Context, _ string, _ []byte, _ ...routing.Option) error { return nil diff --git a/tar/extractor.go b/tar/extractor.go index b5377ddca..8b13b06db 100644 --- a/tar/extractor.go +++ b/tar/extractor.go @@ -10,9 +10,11 @@ import ( "strings" ) -var errTraverseSymlink = errors.New("cannot traverse symlinks") -var errInvalidRoot = errors.New("tar has invalid root") -var errInvalidRootMultipleRoots = fmt.Errorf("contains more than one root or the root directory is not the first entry : %w", errInvalidRoot) +var ( + errTraverseSymlink = errors.New("cannot traverse symlinks") + errInvalidRoot = errors.New("tar has invalid root") + errInvalidRootMultipleRoots = fmt.Errorf("contains more than one root or the root directory is not the first entry : %w", errInvalidRoot) +) // Extractor is used for extracting tar files to a filesystem. // @@ -252,7 +254,7 @@ func (te *Extractor) outputPath(basePlatformPath, relativeTarPath string) (strin var errExtractedDirToSymlink = errors.New("cannot extract to symlink") func (te *Extractor) extractDir(path string) error { - err := os.MkdirAll(path, 0755) + err := os.MkdirAll(path, 0o755) if err != nil { return err } diff --git a/tar/extractor_test.go b/tar/extractor_test.go index 717c65d19..d2b4e00fc 100644 --- a/tar/extractor_test.go +++ b/tar/extractor_test.go @@ -15,8 +15,10 @@ import ( "github.com/stretchr/testify/assert" ) -var symlinksEnabled bool -var symlinksEnabledErr error +var ( + symlinksEnabled bool + symlinksEnabledErr error +) func init() { // check if the platform supports symlinks @@ -320,7 +322,7 @@ func testTarExtraction(t *testing.T, setup func(t *testing.T, rootDir string), t rootDir, err := os.MkdirTemp("", "tar-extraction-test") assert.NoError(t, err) extractDir := fp.Join(rootDir, tarOutRoot) - err = os.MkdirAll(extractDir, 0755) + err = os.MkdirAll(extractDir, 0o755) assert.NoError(t, err) // Generated TAR file. @@ -376,9 +378,11 @@ type tarEntry interface { write(tw *tar.Writer) error } -var _ tarEntry = (*fileTarEntry)(nil) -var _ tarEntry = (*dirTarEntry)(nil) -var _ tarEntry = (*symlinkTarEntry)(nil) +var ( + _ tarEntry = (*fileTarEntry)(nil) + _ tarEntry = (*dirTarEntry)(nil) + _ tarEntry = (*symlinkTarEntry)(nil) +) type fileTarEntry struct { path string @@ -397,12 +401,13 @@ func (e *fileTarEntry) write(tw *tar.Writer) error { tw.Flush() return nil } + func writeFileHeader(w *tar.Writer, fpath string, size uint64) error { return w.WriteHeader(&tar.Header{ Name: fpath, Size: int64(size), Typeflag: tar.TypeReg, - Mode: 0644, + Mode: 0o644, ModTime: time.Now(), // TODO: set mode, dates, etc. when added to unixFS }) @@ -416,7 +421,7 @@ func (e *dirTarEntry) write(tw *tar.Writer) error { return tw.WriteHeader(&tar.Header{ Name: e.path, Typeflag: tar.TypeDir, - Mode: 0777, + Mode: 0o777, ModTime: time.Now(), // TODO: set mode, dates, etc. when added to unixFS }) @@ -431,7 +436,7 @@ func (e *symlinkTarEntry) write(w *tar.Writer) error { return w.WriteHeader(&tar.Header{ Name: e.path, Linkname: e.target, - Mode: 0777, + Mode: 0o777, Typeflag: tar.TypeSymlink, }) } diff --git a/tar/sanitize_windows.go b/tar/sanitize_windows.go index 4a788a484..a88a7055f 100644 --- a/tar/sanitize_windows.go +++ b/tar/sanitize_windows.go @@ -9,7 +9,7 @@ import ( // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx var reservedNames = [...]string{"CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"} -const reservedCharsStr = `[<>:"\|?*]` + "\x00" //NOTE: `/` is not included as it is our standard path separator +const reservedCharsStr = `[<>:"\|?*]` + "\x00" // NOTE: `/` is not included as it is our standard path separator func isNullDevice(path string) bool { // This is a case insensitive comparison to NUL @@ -30,7 +30,7 @@ func isNullDevice(path string) bool { // validatePathComponent returns an error if the given path component is not allowed on the platform func validatePathComponent(c string) error { - //MSDN: Do not end a file or directory name with a space or a period + // MSDN: Do not end a file or directory name with a space or a period if strings.HasSuffix(c, ".") { return fmt.Errorf("invalid platform path: path components cannot end with '.' : %q", c) } diff --git a/tracing/file_exporter.go b/tracing/file_exporter.go index 32ca20ee2..e7fdfa99c 100644 --- a/tracing/file_exporter.go +++ b/tracing/file_exporter.go @@ -16,7 +16,7 @@ type fileExporter struct { } func newFileExporter(file string) (*fileExporter, error) { - f, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + f, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o666) if err != nil { return nil, fmt.Errorf("opening '%s' for OpenTelemetry file exporter: %w", file, err) } diff --git a/verifcid/cid.go b/verifcid/cid.go index 334da2671..df8db8ddf 100644 --- a/verifcid/cid.go +++ b/verifcid/cid.go @@ -7,12 +7,16 @@ import ( mh "github.com/multiformats/go-multihash" ) -var ErrPossiblyInsecureHashFunction = fmt.Errorf("potentially insecure hash functions not allowed") -var ErrBelowMinimumHashLength = fmt.Errorf("hashes must be at least %d bytes long", minimumHashLength) -var ErrAboveMaximumHashLength = fmt.Errorf("hashes must be at most %d bytes long", maximumHashLength) +var ( + ErrPossiblyInsecureHashFunction = fmt.Errorf("potentially insecure hash functions not allowed") + ErrBelowMinimumHashLength = fmt.Errorf("hashes must be at least %d bytes long", minimumHashLength) + ErrAboveMaximumHashLength = fmt.Errorf("hashes must be at most %d bytes long", maximumHashLength) +) -const minimumHashLength = 20 -const maximumHashLength = 128 +const ( + minimumHashLength = 20 + maximumHashLength = 128 +) // ValidateCid validates multihash allowance behind given CID. func ValidateCid(allowlist Allowlist, c cid.Cid) error { From 26688863894bc158846baa36f68929778d08fc72 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Mon, 21 Aug 2023 10:08:11 +0200 Subject: [PATCH 022/312] style: remove some commented out code Commented out just clutters everything, we have the git history if needed. --- bitswap/server/internal/decision/engine_test.go | 3 +-- ipld/unixfs/hamt/hamt_test.go | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/bitswap/server/internal/decision/engine_test.go b/bitswap/server/internal/decision/engine_test.go index 1391f4f70..922836042 100644 --- a/bitswap/server/internal/decision/engine_test.go +++ b/bitswap/server/internal/decision/engine_test.go @@ -104,8 +104,7 @@ func newTestEngineWithSampling(ctx context.Context, idStr string, peerSampleInte e := newEngineForTesting(ctx, bs, fpt, "localhost", 0, append(opts[:len(opts):len(opts)], WithScoreLedger(NewTestScoreLedger(peerSampleInterval, sampleCh, clock)), WithBlockstoreWorkerCount(4))...) e.StartWorkers(ctx, process.WithTeardown(func() error { return nil })) return engineSet{ - Peer: peer.ID(idStr), - // Strategy: New(true), + Peer: peer.ID(idStr), PeerTagger: fpt, Blockstore: bs, Engine: e, diff --git a/ipld/unixfs/hamt/hamt_test.go b/ipld/unixfs/hamt/hamt_test.go index 6d7c56d9f..2defc0d3e 100644 --- a/ipld/unixfs/hamt/hamt_test.go +++ b/ipld/unixfs/hamt/hamt_test.go @@ -163,8 +163,6 @@ func TestDirBuilding(t *testing.T) { t.Fatal(err) } - // printDag(ds, nd, 0) - k := nd.Cid() if k.String() != "QmY89TkSEVHykWMHDmyejSWFj9CYNtvzw4UwnT9xbc4Zjc" { From 1a89522a12987716a77e7882215f69e0c934b45a Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Mon, 21 Aug 2023 12:50:47 +0200 Subject: [PATCH 023/312] ci: upload conformance logs Upload the JSON logs as an artifact that the dashboard generation scripts can retrieve and process. Support for https://github.com/ipfs/gateway-conformance/pull/146 --- .github/workflows/gateway-conformance.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index 281cfe951..61471c015 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -61,3 +61,9 @@ jobs: with: name: gateway-conformance.html path: output.html + - name: Upload JSON report + if: failure() || success() + uses: actions/upload-artifact@v3 + with: + name: gateway-conformance.json + path: output.json From 7f075b1c578e0f4a8f4323c9362dd79373bc9101 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Mon, 21 Aug 2023 16:10:35 +0200 Subject: [PATCH 024/312] Revert "feat(connecteventmanager): block Connected() until accepted (#435)" and tests This reverts commit 7ec68c5e5adfb13e52f93c20e7c5aadf4860a871. This reverts commit 59a2bca3f0924d5a9cc61bbb6c33dbd483f4a0f4. This reverts commit 1d2f5e511e9fb0e1ff4c2b93aea421fc2091e3f5. --- CHANGELOG.md | 1 - bitswap/network/connecteventmanager.go | 102 +++++++------------- bitswap/network/connecteventmanager_test.go | 76 ++++----------- 3 files changed, 52 insertions(+), 127 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c47ac1f10..28cafa33c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,7 +31,6 @@ The following emojis are used to highlight certain changes: ### Fixed -- Address a Bitswap findpeers / connect race condition that can prevent peer communication ([#435](https://github.com/ipfs/boxo/issues/435)) - HTTP Gateway API: Not having a block will result in a 5xx error rather than 404 - HTTP Gateway API: CAR requests will return 200s and a CAR file proving a requested path does not exist rather than returning an error diff --git a/bitswap/network/connecteventmanager.go b/bitswap/network/connecteventmanager.go index e38598812..88337fce3 100644 --- a/bitswap/network/connecteventmanager.go +++ b/bitswap/network/connecteventmanager.go @@ -25,25 +25,16 @@ type connectEventManager struct { cond sync.Cond peers map[peer.ID]*peerState - changeQueue []change + changeQueue []peer.ID stop bool done chan struct{} } -type change struct { - pid peer.ID - handled chan struct{} -} - type peerState struct { newState, curState state pending bool } -type waitFn func() - -func waitNoop() {} - func newConnectEventManager(connListeners ...ConnectionListener) *connectEventManager { evtManager := &connectEventManager{ connListeners: connListeners, @@ -75,16 +66,7 @@ func (c *connectEventManager) getState(p peer.ID) state { } } -func (c *connectEventManager) makeWaitFunc(handled chan struct{}) waitFn { - return func() { - select { - case <-handled: - case <-c.done: - } - } -} - -func (c *connectEventManager) setState(p peer.ID, newState state) waitFn { +func (c *connectEventManager) setState(p peer.ID, newState state) { state, ok := c.peers[p] if !ok { state = new(peerState) @@ -93,20 +75,9 @@ func (c *connectEventManager) setState(p peer.ID, newState state) waitFn { state.newState = newState if !state.pending && state.newState != state.curState { state.pending = true - change := change{p, make(chan struct{})} - c.changeQueue = append(c.changeQueue, change) + c.changeQueue = append(c.changeQueue, p) c.cond.Broadcast() - return c.makeWaitFunc(change.handled) - } else if state.pending { - // Find the change in the queue and return a wait function for it - for _, change := range c.changeQueue { - if change.pid == p { - return c.makeWaitFunc(change.handled) - } - } - log.Error("a peer was marked as change pending but not found in the change queue") } - return waitNoop } // Waits for a change to be enqueued, or for the event manager to be stopped. Returns false if the @@ -124,70 +95,67 @@ func (c *connectEventManager) worker() { defer close(c.done) for c.waitChange() { - pch := c.changeQueue[0] - c.changeQueue[0] = change{} // free the resources (slicing won't do that) + pid := c.changeQueue[0] + c.changeQueue[0] = peer.ID("") // free the peer ID (slicing won't do that) c.changeQueue = c.changeQueue[1:] - state, ok := c.peers[pch.pid] + state, ok := c.peers[pid] // If we've disconnected and forgotten, continue. if !ok { // This shouldn't be possible because _this_ thread is responsible for // removing peers from this map, and we shouldn't get duplicate entries in // the change queue. log.Error("a change was enqueued for a peer we're not tracking") - close(pch.handled) continue } - // Is there anything to do? - if state.curState != state.newState { - // Record the state update, then apply it. - oldState := state.curState - state.curState = state.newState - - switch state.newState { - case stateDisconnected: - delete(c.peers, pch.pid) - fallthrough - case stateUnresponsive: - // Only trigger a disconnect event if the peer was responsive. - // We could be transitioning from unresponsive to disconnected. - if oldState == stateResponsive { - c.lk.Unlock() - for _, v := range c.connListeners { - v.PeerDisconnected(pch.pid) - } - c.lk.Lock() - } - case stateResponsive: + // Record the fact that this "state" is no longer in the queue. + state.pending = false + + // Then, if there's nothing to do, continue. + if state.curState == state.newState { + continue + } + + // Or record the state update, then apply it. + oldState := state.curState + state.curState = state.newState + + switch state.newState { + case stateDisconnected: + delete(c.peers, pid) + fallthrough + case stateUnresponsive: + // Only trigger a disconnect event if the peer was responsive. + // We could be transitioning from unresponsive to disconnected. + if oldState == stateResponsive { c.lk.Unlock() for _, v := range c.connListeners { - v.PeerConnected(pch.pid) + v.PeerDisconnected(pid) } c.lk.Lock() } + case stateResponsive: + c.lk.Unlock() + for _, v := range c.connListeners { + v.PeerConnected(pid) + } + c.lk.Lock() } - - // Record the fact that this "state" is no longer in the queue. - state.pending = false - // Signal that we've handled the state change - close(pch.handled) } } // Called whenever we receive a new connection. May be called many times. func (c *connectEventManager) Connected(p peer.ID) { c.lk.Lock() + defer c.lk.Unlock() // !responsive -> responsive if c.getState(p) == stateResponsive { - c.lk.Unlock() return } - wait := c.setState(p, stateResponsive) - c.lk.Unlock() - wait() + c.setState(p, stateResponsive) } // Called when we drop the final connection to a peer. diff --git a/bitswap/network/connecteventmanager_test.go b/bitswap/network/connecteventmanager_test.go index c961a5a97..e3904ee55 100644 --- a/bitswap/network/connecteventmanager_test.go +++ b/bitswap/network/connecteventmanager_test.go @@ -6,6 +6,7 @@ import ( "time" "github.com/ipfs/boxo/bitswap/internal/testutil" + "github.com/ipfs/boxo/internal/test" "github.com/libp2p/go-libp2p/core/peer" "github.com/stretchr/testify/require" ) @@ -17,8 +18,7 @@ type mockConnEvent struct { type mockConnListener struct { sync.Mutex - events []mockConnEvent - peerConnectedCb func(p peer.ID) + events []mockConnEvent } func newMockConnListener() *mockConnListener { @@ -29,9 +29,6 @@ func (cl *mockConnListener) PeerConnected(p peer.ID) { cl.Lock() defer cl.Unlock() cl.events = append(cl.events, mockConnEvent{connected: true, peer: p}) - if cl.peerConnectedCb != nil { - cl.peerConnectedCb(p) - } } func (cl *mockConnListener) PeerDisconnected(p peer.ID) { @@ -49,6 +46,8 @@ func wait(t *testing.T, c *connectEventManager) { } func TestConnectEventManagerConnectDisconnect(t *testing.T) { + test.Flaky(t) + connListener := newMockConnListener() peers := testutil.GeneratePeers(2) cem := newConnectEventManager(connListener) @@ -65,26 +64,31 @@ func TestConnectEventManagerConnectDisconnect(t *testing.T) { connected: true, }) + // Flush the event queue. + wait(t, cem) require.Equal(t, expectedEvents, connListener.events) + // Block up the event loop. + connListener.Lock() cem.Connected(peers[1]) expectedEvents = append(expectedEvents, mockConnEvent{ peer: peers[1], connected: true, }) - require.Equal(t, expectedEvents, connListener.events) + // We don't expect this to show up. cem.Disconnected(peers[0]) - expectedEvents = append(expectedEvents, mockConnEvent{ - peer: peers[0], - connected: false, - }) - // Flush the event queue. + cem.Connected(peers[0]) + + connListener.Unlock() + wait(t, cem) require.Equal(t, expectedEvents, connListener.events) } func TestConnectEventManagerMarkUnresponsive(t *testing.T) { + test.Flaky(t) + connListener := newMockConnListener() p := testutil.GeneratePeers(1)[0] cem := newConnectEventManager(connListener) @@ -134,6 +138,8 @@ func TestConnectEventManagerMarkUnresponsive(t *testing.T) { } func TestConnectEventManagerDisconnectAfterMarkUnresponsive(t *testing.T) { + test.Flaky(t) + connListener := newMockConnListener() p := testutil.GeneratePeers(1)[0] cem := newConnectEventManager(connListener) @@ -167,51 +173,3 @@ func TestConnectEventManagerDisconnectAfterMarkUnresponsive(t *testing.T) { require.Empty(t, cem.peers) // all disconnected require.Equal(t, expectedEvents, connListener.events) } - -func TestConnectEventManagerConnectFlowSynchronous(t *testing.T) { - connListener := newMockConnListener() - actionsCh := make(chan string) - connListener.peerConnectedCb = func(p peer.ID) { - actionsCh <- "PeerConnected:" + p.String() - time.Sleep(time.Millisecond * 50) - } - - peers := testutil.GeneratePeers(2) - cem := newConnectEventManager(connListener) - cem.Start() - t.Cleanup(cem.Stop) - - go func() { - actionsCh <- "Connected:" + peers[0].String() - cem.Connected(peers[0]) - actionsCh <- "Done:" + peers[0].String() - actionsCh <- "Connected:" + peers[1].String() - cem.Connected(peers[1]) - actionsCh <- "Done:" + peers[1].String() - close(actionsCh) - }() - - // We expect Done to be sent _after_ PeerConnected, which demonstrates the - // call to Connected() blocks until PeerConnected() returns. - gotActions := make([]string, 0, 3) - for event := range actionsCh { - gotActions = append(gotActions, event) - } - expectedActions := []string{ - "Connected:" + peers[0].String(), - "PeerConnected:" + peers[0].String(), - "Done:" + peers[0].String(), - "Connected:" + peers[1].String(), - "PeerConnected:" + peers[1].String(), - "Done:" + peers[1].String(), - } - require.Equal(t, expectedActions, gotActions) - - // Flush the event queue. - wait(t, cem) - expectedEvents := []mockConnEvent{ - {peer: peers[0], connected: true}, - {peer: peers[1], connected: true}, - } - require.Equal(t, expectedEvents, connListener.events) -} From aa7add0838415f742220499ec2218673dbebe9dd Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 21 Aug 2023 18:06:37 +0200 Subject: [PATCH 025/312] fix!: add escaped abspath header (#434) --- CHANGELOG.md | 6 ++ files/multifilereader.go | 26 +++-- files/multifilereader_binary_go119_test.go | 10 ++ files/multifilereader_binary_go120_test.go | 13 +++ files/multifilereader_test.go | 117 +++++++++++++++------ files/multipartfile.go | 12 ++- 6 files changed, 141 insertions(+), 43 deletions(-) create mode 100644 files/multifilereader_binary_go119_test.go create mode 100644 files/multifilereader_binary_go120_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 28cafa33c..2c1f16447 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,12 @@ The following emojis are used to highlight certain changes: - HTTP Gateway API: Not having a block will result in a 5xx error rather than 404 - HTTP Gateway API: CAR requests will return 200s and a CAR file proving a requested path does not exist rather than returning an error +- 🛠 `MultiFileReader` has been updated with a new header with the encoded file name instead of the plain filename, due to a regression found in [`net/textproto`](https://github.com/golang/go/issues/60674). This only affects files with binary characters in their name. By keeping the old header, we maximize backwards compatibility. + | | New Client | Old Client | + |------------|------------|-------------| + | New Server | ✅ | 🟡* | + | Old Server | ✅ | ✅ | + *Old clients can only send Unicode file paths to the server. ### Security diff --git a/files/multifilereader.go b/files/multifilereader.go index af708dc7f..1a5d4ac1a 100644 --- a/files/multifilereader.go +++ b/files/multifilereader.go @@ -29,19 +29,26 @@ type MultiFileReader struct { // if true, the content disposition will be "form-data" // if false, the content disposition will be "attachment" form bool + + // if true, 'abspath' header will be sent with raw (potentially binary) file + // name. This must only be used for legacy purposes to talk with old servers. + // if false, 'abspath-encoded' header will be sent with %-encoded filename + rawAbsPath bool } // NewMultiFileReader constructs a MultiFileReader. `file` can be any `commands.Directory`. // If `form` is set to true, the Content-Disposition will be "form-data". -// Otherwise, it will be "attachment". -func NewMultiFileReader(file Directory, form bool) *MultiFileReader { +// Otherwise, it will be "attachment". If `rawAbsPath` is set to true, the +// "abspath" header will be sent. Otherwise, the "abspath-encoded" header will be sent. +func NewMultiFileReader(file Directory, form, rawAbsPath bool) *MultiFileReader { it := file.Entries() mfr := &MultiFileReader{ - files: []DirIterator{it}, - path: []string{""}, - form: form, - mutex: &sync.Mutex{}, + files: []DirIterator{it}, + path: []string{""}, + form: form, + rawAbsPath: rawAbsPath, + mutex: &sync.Mutex{}, } mfr.mpWriter = multipart.NewWriter(&mfr.buf) @@ -114,7 +121,12 @@ func (mfr *MultiFileReader) Read(buf []byte) (written int, err error) { header.Set("Content-Type", contentType) if rf, ok := entry.Node().(FileInfo); ok { - header.Set("abspath", rf.AbsPath()) + if mfr.rawAbsPath { + // Legacy compatibility with old servers. + header.Set("abspath", rf.AbsPath()) + } else { + header.Set("abspath-encoded", url.QueryEscape(rf.AbsPath())) + } } _, err := mfr.mpWriter.CreatePart(header) diff --git a/files/multifilereader_binary_go119_test.go b/files/multifilereader_binary_go119_test.go new file mode 100644 index 000000000..c71514b61 --- /dev/null +++ b/files/multifilereader_binary_go119_test.go @@ -0,0 +1,10 @@ +//go:build !go1.20 + +package files + +import "testing" + +func TestAbspathHeaderWithBinaryFilenameSucceeds(t *testing.T) { + // Simulates old client talking to old server (< Go 1.20). + runMultiFileReaderToMultiFileTest(t, true, true, false) +} diff --git a/files/multifilereader_binary_go120_test.go b/files/multifilereader_binary_go120_test.go new file mode 100644 index 000000000..bc3cf097d --- /dev/null +++ b/files/multifilereader_binary_go120_test.go @@ -0,0 +1,13 @@ +//go:build go1.20 + +package files + +import ( + "testing" +) + +func TestAbspathHeaderWithBinaryFilenameFails(t *testing.T) { + // Simulates old client talking to new server (>= Go 1.20). Old client will + // send the binary filename in the regular headers and the new server will error. + runMultiFileReaderToMultiFileTest(t, true, true, true) +} diff --git a/files/multifilereader_test.go b/files/multifilereader_test.go index e36788a91..b39217037 100644 --- a/files/multifilereader_test.go +++ b/files/multifilereader_test.go @@ -1,29 +1,48 @@ package files import ( + "bytes" "io" "mime/multipart" "testing" + + "github.com/stretchr/testify/require" ) var text = "Some text! :)" -func getTestMultiFileReader(t *testing.T) *MultiFileReader { +func newBytesFileWithPath(abspath string, b []byte) File { + return &ReaderFile{abspath, bytesReaderCloser{bytes.NewReader(b)}, nil, int64(len(b))} +} + +func makeMultiFileReader(t *testing.T, binaryFileName, rawAbsPath bool) (string, *MultiFileReader) { + var ( + filename string + file File + ) + + if binaryFileName { + filename = "bad\x7fname.txt" + file = newBytesFileWithPath("/my/path/boop/bad\x7fname.txt", []byte("bloop")) + } else { + filename = "résumé🥳.txt" + file = newBytesFileWithPath("/my/path/boop/résumé🥳.txt", []byte("bloop")) + } + sf := NewMapDirectory(map[string]Node{ - "file.txt": NewBytesFile([]byte(text)), + "file.txt": newBytesFileWithPath("/my/path/file.txt", []byte(text)), "boop": NewMapDirectory(map[string]Node{ - "a.txt": NewBytesFile([]byte("bleep")), - "b.txt": NewBytesFile([]byte("bloop")), + "a.txt": newBytesFileWithPath("/my/path/boop/a.txt", []byte("bleep")), + filename: file, }), - "beep.txt": NewBytesFile([]byte("beep")), + "beep.txt": newBytesFileWithPath("/my/path/beep.txt", []byte("beep")), }) - // testing output by reading it with the go stdlib "mime/multipart" Reader - return NewMultiFileReader(sf, true) + return filename, NewMultiFileReader(sf, true, rawAbsPath) } -func TestMultiFileReaderToMultiFile(t *testing.T) { - mfr := getTestMultiFileReader(t) +func runMultiFileReaderToMultiFileTest(t *testing.T, binaryFileName, rawAbsPath, expectFailure bool) { + filename, mfr := makeMultiFileReader(t, binaryFileName, rawAbsPath) mpReader := multipart.NewReader(mfr, mfr.Boundary()) mf, err := NewFileFromPartReader(mpReader, multipartFormdataType) if err != nil { @@ -32,40 +51,68 @@ func TestMultiFileReaderToMultiFile(t *testing.T) { it := mf.Entries() - if !it.Next() || it.Name() != "beep.txt" { - t.Fatal("iterator didn't work as expected") - } - - if !it.Next() || it.Name() != "boop" || DirFromEntry(it) == nil { - t.Fatal("iterator didn't work as expected") - } + require.True(t, it.Next()) + require.Equal(t, "beep.txt", it.Name()) + require.True(t, it.Next()) + require.Equal(t, "boop", it.Name()) + require.NotNil(t, DirFromEntry(it)) subIt := DirFromEntry(it).Entries() + require.True(t, subIt.Next(), subIt.Err()) + require.Equal(t, "a.txt", subIt.Name()) + require.Nil(t, DirFromEntry(subIt)) - if !subIt.Next() || subIt.Name() != "a.txt" || DirFromEntry(subIt) != nil { - t.Fatal("iterator didn't work as expected") - } + if expectFailure { + require.False(t, subIt.Next()) + require.Error(t, subIt.Err()) + } else { + require.True(t, subIt.Next(), subIt.Err()) + require.Equal(t, filename, subIt.Name()) + require.Nil(t, DirFromEntry(subIt)) - if !subIt.Next() || subIt.Name() != "b.txt" || DirFromEntry(subIt) != nil { - t.Fatal("iterator didn't work as expected") - } + require.False(t, subIt.Next()) + require.Nil(t, it.Err()) - if subIt.Next() || it.Err() != nil { - t.Fatal("iterator didn't work as expected") - } + // try to break internal state + require.False(t, subIt.Next()) + require.Nil(t, it.Err()) - // try to break internal state - if subIt.Next() || it.Err() != nil { - t.Fatal("iterator didn't work as expected") - } + require.True(t, it.Next()) + require.Equal(t, "file.txt", it.Name()) + require.Nil(t, DirFromEntry(it)) + require.Nil(t, it.Err()) - if !it.Next() || it.Name() != "file.txt" || DirFromEntry(it) != nil || it.Err() != nil { - t.Fatal("iterator didn't work as expected") + require.False(t, it.Next()) + require.Nil(t, it.Err()) } +} - if it.Next() || it.Err() != nil { - t.Fatal("iterator didn't work as expected") - } +func TestMultiFileReaderToMultiFile(t *testing.T) { + t.Run("Header 'abspath' with unicode filename succeeds", func(t *testing.T) { + runMultiFileReaderToMultiFileTest(t, false, true, false) + }) + + t.Run("Header 'abspath-encoded' with unicode filename succeeds", func(t *testing.T) { + runMultiFileReaderToMultiFileTest(t, false, false, false) + }) + + t.Run("Header 'abspath-encoded' with binary filename succeeds", func(t *testing.T) { + runMultiFileReaderToMultiFileTest(t, true, false, false) + }) +} + +func getTestMultiFileReader(t *testing.T) *MultiFileReader { + sf := NewMapDirectory(map[string]Node{ + "file.txt": NewBytesFile([]byte(text)), + "boop": NewMapDirectory(map[string]Node{ + "a.txt": NewBytesFile([]byte("bleep")), + "b.txt": NewBytesFile([]byte("bloop")), + }), + "beep.txt": NewBytesFile([]byte("beep")), + }) + + // testing output by reading it with the go stdlib "mime/multipart" Reader + return NewMultiFileReader(sf, true, false) } func TestMultiFileReaderToMultiFileSkip(t *testing.T) { @@ -164,7 +211,7 @@ func TestCommonPrefix(t *testing.T) { "aaa": NewBytesFile([]byte("bleep")), }), }) - mfr := NewMultiFileReader(sf, true) + mfr := NewMultiFileReader(sf, true, false) reader, err := NewFileFromPartReader(multipart.NewReader(mfr, mfr.Boundary()), multipartFormdataType) if err != nil { t.Fatal(err) diff --git a/files/multipartfile.go b/files/multipartfile.go index 27653982c..b5aab9620 100644 --- a/files/multipartfile.go +++ b/files/multipartfile.go @@ -100,9 +100,19 @@ func (w *multipartWalker) nextFile() (Node, error) { return NewLinkFile(string(out), nil), nil default: + var absPath string + if absPathEncoded := part.Header.Get("abspath-encoded"); absPathEncoded != "" { + absPath, err = url.QueryUnescape(absPathEncoded) + if err != nil { + return nil, err + } + } else { + absPath = part.Header.Get("abspath") + } + return &ReaderFile{ reader: part, - abspath: part.Header.Get("abspath"), + abspath: absPath, }, nil } } From f061418c466b4a4883efaaf4d3591b53d9b1c5a3 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 22 Aug 2023 07:37:19 +0200 Subject: [PATCH 026/312] feat(routing/http): delegated IPNS server and client, IPIP 379 (#333) --- CHANGELOG.md | 2 + examples/go.mod | 2 +- examples/go.sum | 8 +- go.mod | 2 +- go.sum | 8 +- routing/http/client/client.go | 71 +++++++++++++- routing/http/client/client_test.go | 112 ++++++++++++++++++++++ routing/http/server/server.go | 113 +++++++++++++++++++++- routing/http/server/server_test.go | 148 +++++++++++++++++++++++++++++ 9 files changed, 451 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c1f16447..9ade2c65c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ The following emojis are used to highlight certain changes: ### Added +* The `routing/http` client and server now support Delegated IPNS at `/routing/v1` + as per [IPIP-379](https://specs.ipfs.tech/ipips/ipip-0379/). * The `verifycid` package has been updated with the new Allowlist interface as part of reducing globals efforts. Still, existing global accessor funcs are kept for backwards-compatibility. diff --git a/examples/go.mod b/examples/go.mod index c03a48670..e68a08ebd 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -8,7 +8,7 @@ require ( github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-datastore v0.6.0 github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 - github.com/ipld/go-ipld-prime v0.20.0 + github.com/ipld/go-ipld-prime v0.21.0 github.com/libp2p/go-libp2p v0.26.3 github.com/libp2p/go-libp2p-routing-helpers v0.7.0 github.com/multiformats/go-multiaddr v0.8.0 diff --git a/examples/go.sum b/examples/go.sum index 82c8b4c63..0c23da44d 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -122,7 +122,7 @@ github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkFtf/dnN7Q= github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M= @@ -332,8 +332,8 @@ github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 h1:0OZwzSYWIuiKE github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33/go.mod h1:sQEkXVM3csejlb1kCCb+vQ/pWBKX9QtvsrysMQjOgOg= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= -github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= -github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= +github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= +github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= @@ -625,7 +625,7 @@ github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -github.com/warpfork/go-testmark v0.11.0 h1:J6LnV8KpceDvo7spaNU4+DauH2n1x+6RaO2rJrmpQ9U= +github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= diff --git a/go.mod b/go.mod index baa78701e..0fdb8067e 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/ipfs/go-unixfsnode v1.7.1 github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 github.com/ipld/go-codec-dagpb v1.6.0 - github.com/ipld/go-ipld-prime v0.20.0 + github.com/ipld/go-ipld-prime v0.21.0 github.com/jbenet/goprocess v0.1.4 github.com/libp2p/go-buffer-pool v0.1.0 github.com/libp2p/go-doh-resolver v0.4.0 diff --git a/go.sum b/go.sum index fa2a3628e..d6583aa5a 100644 --- a/go.sum +++ b/go.sum @@ -120,7 +120,7 @@ github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkFtf/dnN7Q= github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M= @@ -338,8 +338,8 @@ github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 h1:0OZwzSYWIuiKE github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33/go.mod h1:sQEkXVM3csejlb1kCCb+vQ/pWBKX9QtvsrysMQjOgOg= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= -github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= -github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= +github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= +github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= @@ -635,7 +635,7 @@ github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -github.com/warpfork/go-testmark v0.11.0 h1:J6LnV8KpceDvo7spaNU4+DauH2n1x+6RaO2rJrmpQ9U= +github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= diff --git a/routing/http/client/client.go b/routing/http/client/client.go index b3a74150c..c504a0315 100644 --- a/routing/http/client/client.go +++ b/routing/http/client/client.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "io" "mime" "net/http" "strings" @@ -41,8 +42,9 @@ var ( ) const ( - mediaTypeJSON = "application/json" - mediaTypeNDJSON = "application/x-ndjson" + mediaTypeJSON = "application/json" + mediaTypeNDJSON = "application/x-ndjson" + mediaTypeIPNSRecord = "application/vnd.ipfs.ipns-record" ) type client struct { @@ -324,3 +326,68 @@ func (c *client) provideSignedBitswapRecord(ctx context.Context, bswp *types.Wri return 0, nil } + +func (c *client) FindIPNSRecord(ctx context.Context, name ipns.Name) (*ipns.Record, error) { + url := c.baseURL + "/routing/v1/ipns/" + name.String() + + httpReq, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return nil, err + } + httpReq.Header.Set("Accept", mediaTypeIPNSRecord) + + resp, err := c.httpClient.Do(httpReq) + if err != nil { + return nil, fmt.Errorf("making HTTP req to get IPNS record: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, httpError(resp.StatusCode, resp.Body) + } + + // Limit the reader to the maximum record size. + rawRecord, err := io.ReadAll(io.LimitReader(resp.Body, int64(ipns.MaxRecordSize))) + if err != nil { + return nil, fmt.Errorf("making HTTP req to get IPNS record: %w", err) + } + + record, err := ipns.UnmarshalRecord(rawRecord) + if err != nil { + return nil, fmt.Errorf("IPNS record from remote endpoint is not valid: %w", err) + } + + err = ipns.ValidateWithName(record, name) + if err != nil { + return nil, fmt.Errorf("IPNS record from remote endpoint is not valid: %w", err) + } + + return record, nil +} + +func (c *client) ProvideIPNSRecord(ctx context.Context, name ipns.Name, record *ipns.Record) error { + url := c.baseURL + "/routing/v1/ipns/" + name.String() + + rawRecord, err := ipns.MarshalRecord(record) + if err != nil { + return err + } + + httpReq, err := http.NewRequestWithContext(ctx, http.MethodPut, url, bytes.NewReader(rawRecord)) + if err != nil { + return err + } + httpReq.Header.Set("Content-Type", mediaTypeIPNSRecord) + + resp, err := c.httpClient.Do(httpReq) + if err != nil { + return fmt.Errorf("making HTTP req to get IPNS record: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return httpError(resp.StatusCode, resp.Body) + } + + return nil +} diff --git a/routing/http/client/client_test.go b/routing/http/client/client_test.go index 06ad1d6b4..c1690b3f2 100644 --- a/routing/http/client/client_test.go +++ b/routing/http/client/client_test.go @@ -3,6 +3,7 @@ package client import ( "context" "crypto/rand" + "errors" "net/http" "net/http/httptest" "runtime" @@ -10,6 +11,9 @@ import ( "time" "github.com/benbjohnson/clock" + "github.com/ipfs/boxo/coreiface/path" + ipns "github.com/ipfs/boxo/ipns" + ipfspath "github.com/ipfs/boxo/path" "github.com/ipfs/boxo/routing/http/server" "github.com/ipfs/boxo/routing/http/types" "github.com/ipfs/boxo/routing/http/types/iter" @@ -42,6 +46,16 @@ func (m *mockContentRouter) Provide(ctx context.Context, req *server.WriteProvid return args.Get(0).(types.ProviderResponse), args.Error(1) } +func (m *mockContentRouter) FindIPNSRecord(ctx context.Context, name ipns.Name) (*ipns.Record, error) { + args := m.Called(ctx, name) + return args.Get(0).(*ipns.Record), args.Error(1) +} + +func (m *mockContentRouter) ProvideIPNSRecord(ctx context.Context, name ipns.Name, record *ipns.Record) error { + args := m.Called(ctx, name, record) + return args.Error(0) +} + type testDeps struct { // recordingHandler records requests received on the server side recordingHandler *recordingHandler @@ -442,3 +456,101 @@ func TestClient_Provide(t *testing.T) { }) } } + +func makeName(t *testing.T) (crypto.PrivKey, ipns.Name) { + sk, _, err := crypto.GenerateEd25519Key(rand.Reader) + require.NoError(t, err) + + pid, err := peer.IDFromPrivateKey(sk) + require.NoError(t, err) + + return sk, ipns.NameFromPeer(pid) +} + +func makeIPNSRecord(t *testing.T, sk crypto.PrivKey, opts ...ipns.Option) (*ipns.Record, []byte) { + cid, err := cid.Decode("bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4") + require.NoError(t, err) + + path := path.IpfsPath(cid) + eol := time.Now().Add(time.Hour * 48) + ttl := time.Second * 20 + + record, err := ipns.NewRecord(sk, ipfspath.FromString(path.String()), 1, eol, ttl, opts...) + require.NoError(t, err) + + rawRecord, err := ipns.MarshalRecord(record) + require.NoError(t, err) + + return record, rawRecord +} + +func TestClient_IPNS(t *testing.T) { + t.Run("Find IPNS Record returns error if server errors", func(t *testing.T) { + _, name := makeName(t) + + deps := makeTestDeps(t, nil, nil) + client := deps.client + router := deps.router + + router.On("FindIPNSRecord", mock.Anything, name).Return(nil, errors.New("something wrong happened")) + + receivedRecord, err := client.FindIPNSRecord(context.Background(), name) + require.Error(t, err) + require.Nil(t, receivedRecord) + }) + + runWithRecordOptions := func(t *testing.T, opts ...ipns.Option) { + t.Run("Find IPNS Record", func(t *testing.T) { + sk, name := makeName(t) + record, _ := makeIPNSRecord(t, sk, opts...) + + deps := makeTestDeps(t, nil, nil) + client := deps.client + router := deps.router + + router.On("FindIPNSRecord", mock.Anything, name).Return(record, nil) + + receivedRecord, err := client.FindIPNSRecord(context.Background(), name) + require.NoError(t, err) + require.Equal(t, record, receivedRecord) + }) + + t.Run("Find IPNS Record returns error if server sends bad data", func(t *testing.T) { + sk, _ := makeName(t) + record, _ := makeIPNSRecord(t, sk, opts...) + _, name2 := makeName(t) + + deps := makeTestDeps(t, nil, nil) + client := deps.client + router := deps.router + + router.On("FindIPNSRecord", mock.Anything, name2).Return(record, nil) + + receivedRecord, err := client.FindIPNSRecord(context.Background(), name2) + require.Error(t, err) + require.Nil(t, receivedRecord) + }) + + t.Run("Provide IPNS Record", func(t *testing.T) { + sk, name := makeName(t) + record, _ := makeIPNSRecord(t, sk, opts...) + + deps := makeTestDeps(t, nil, nil) + client := deps.client + router := deps.router + + router.On("ProvideIPNSRecord", mock.Anything, name, record).Return(nil) + + err := client.ProvideIPNSRecord(context.Background(), name, record) + require.NoError(t, err) + }) + } + + t.Run("V1+V2 IPNS Records", func(t *testing.T) { + runWithRecordOptions(t, ipns.WithV1Compatibility(true)) + }) + + t.Run("V2 IPNS Records", func(t *testing.T) { + runWithRecordOptions(t, ipns.WithV1Compatibility(false)) + }) +} diff --git a/routing/http/server/server.go b/routing/http/server/server.go index dc0026fbf..835262990 100644 --- a/routing/http/server/server.go +++ b/routing/http/server/server.go @@ -9,10 +9,13 @@ import ( "io" "mime" "net/http" + "strconv" "strings" "time" + "github.com/cespare/xxhash/v2" "github.com/gorilla/mux" + "github.com/ipfs/boxo/ipns" "github.com/ipfs/boxo/routing/http/internal/drjson" "github.com/ipfs/boxo/routing/http/types" "github.com/ipfs/boxo/routing/http/types/iter" @@ -25,9 +28,10 @@ import ( ) const ( - mediaTypeJSON = "application/json" - mediaTypeNDJSON = "application/x-ndjson" - mediaTypeWildcard = "*/*" + mediaTypeJSON = "application/json" + mediaTypeNDJSON = "application/x-ndjson" + mediaTypeWildcard = "*/*" + mediaTypeIPNSRecord = "application/vnd.ipfs.ipns-record" DefaultRecordsLimit = 20 DefaultStreamingRecordsLimit = 0 @@ -38,6 +42,7 @@ var logger = logging.Logger("service/server/delegatedrouting") const ( ProvidePath = "/routing/v1/providers/" FindProvidersPath = "/routing/v1/providers/{cid}" + IPNSPath = "/routing/v1/ipns/{cid}" ) type FindProvidersAsyncResponse struct { @@ -51,6 +56,13 @@ type ContentRouter interface { FindProviders(ctx context.Context, key cid.Cid, limit int) (iter.ResultIter[types.ProviderResponse], error) ProvideBitswap(ctx context.Context, req *BitswapWriteProvideRequest) (time.Duration, error) Provide(ctx context.Context, req *WriteProvideRequest) (types.ProviderResponse, error) + + // FindIPNSRecord searches for an [ipns.Record] for the given [ipns.Name]. + FindIPNSRecord(ctx context.Context, name ipns.Name) (*ipns.Record, error) + + // ProvideIPNSRecord stores the provided [ipns.Record] for the given [ipns.Name]. It is + // guaranteed that the record matches the provided name. + ProvideIPNSRecord(ctx context.Context, name ipns.Name, record *ipns.Record) error } type BitswapWriteProvideRequest struct { @@ -107,6 +119,9 @@ func Handler(svc ContentRouter, opts ...Option) http.Handler { r.HandleFunc(ProvidePath, server.provide).Methods(http.MethodPut) r.HandleFunc(FindProvidersPath, server.findProviders).Methods(http.MethodGet) + r.HandleFunc(IPNSPath, server.getIPNSRecord).Methods(http.MethodGet) + r.HandleFunc(IPNSPath, server.putIPNSRecord).Methods(http.MethodPut) + return r } @@ -297,6 +312,98 @@ func (s *server) findProvidersNDJSON(w http.ResponseWriter, provIter iter.Result } } +func (s *server) getIPNSRecord(w http.ResponseWriter, r *http.Request) { + if !strings.Contains(r.Header.Get("Accept"), mediaTypeIPNSRecord) { + writeErr(w, "GetIPNSRecord", http.StatusNotAcceptable, errors.New("content type in 'Accept' header is missing or not supported")) + return + } + + vars := mux.Vars(r) + cidStr := vars["cid"] + cid, err := cid.Decode(cidStr) + if err != nil { + writeErr(w, "GetIPNSRecord", http.StatusBadRequest, fmt.Errorf("unable to parse CID: %w", err)) + return + } + + name, err := ipns.NameFromCid(cid) + if err != nil { + writeErr(w, "GetIPNSRecord", http.StatusBadRequest, fmt.Errorf("peer ID CID is not valid: %w", err)) + return + } + + record, err := s.svc.FindIPNSRecord(r.Context(), name) + if err != nil { + writeErr(w, "GetIPNSRecord", http.StatusInternalServerError, fmt.Errorf("delegate error: %w", err)) + return + } + + rawRecord, err := ipns.MarshalRecord(record) + if err != nil { + writeErr(w, "GetIPNSRecord", http.StatusInternalServerError, err) + return + } + + if ttl, err := record.TTL(); err == nil { + w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%d", int(ttl.Seconds()))) + } else { + w.Header().Set("Cache-Control", "max-age=60") + } + + recordEtag := strconv.FormatUint(xxhash.Sum64(rawRecord), 32) + w.Header().Set("Etag", recordEtag) + w.Header().Set("Content-Type", mediaTypeIPNSRecord) + w.Write(rawRecord) +} + +func (s *server) putIPNSRecord(w http.ResponseWriter, r *http.Request) { + if !strings.Contains(r.Header.Get("Content-Type"), mediaTypeIPNSRecord) { + writeErr(w, "PutIPNSRecord", http.StatusNotAcceptable, errors.New("content type in 'Content-Type' header is missing or not supported")) + return + } + + vars := mux.Vars(r) + cidStr := vars["cid"] + cid, err := cid.Decode(cidStr) + if err != nil { + writeErr(w, "PutIPNSRecord", http.StatusBadRequest, fmt.Errorf("unable to parse CID: %w", err)) + return + } + + name, err := ipns.NameFromCid(cid) + if err != nil { + writeErr(w, "PutIPNSRecord", http.StatusBadRequest, fmt.Errorf("peer ID CID is not valid: %w", err)) + return + } + + // Limit the reader to the maximum record size. + rawRecord, err := io.ReadAll(io.LimitReader(r.Body, int64(ipns.MaxRecordSize))) + if err != nil { + writeErr(w, "PutIPNSRecord", http.StatusBadRequest, fmt.Errorf("provided record is too long: %w", err)) + return + } + + record, err := ipns.UnmarshalRecord(rawRecord) + if err != nil { + writeErr(w, "PutIPNSRecord", http.StatusBadRequest, fmt.Errorf("provided record is invalid: %w", err)) + return + } + + err = ipns.ValidateWithName(record, name) + if err != nil { + writeErr(w, "PutIPNSRecord", http.StatusBadRequest, fmt.Errorf("provided record is invalid: %w", err)) + return + } + + err = s.svc.ProvideIPNSRecord(r.Context(), name, record) + if err != nil { + writeErr(w, "PutIPNSRecord", http.StatusInternalServerError, fmt.Errorf("delegate error: %w", err)) + return + } + + w.WriteHeader(http.StatusOK) +} + func writeJSONResult(w http.ResponseWriter, method string, val any) { w.Header().Add("Content-Type", mediaTypeJSON) diff --git a/routing/http/server/server_test.go b/routing/http/server/server_test.go index db607aba6..dfe38f0da 100644 --- a/routing/http/server/server_test.go +++ b/routing/http/server/server_test.go @@ -1,16 +1,22 @@ package server import ( + "bytes" "context" + "crypto/rand" "io" "net/http" "net/http/httptest" "testing" "time" + "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/ipns" + ipfspath "github.com/ipfs/boxo/path" "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/crypto" "github.com/libp2p/go-libp2p/core/peer" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -119,6 +125,138 @@ func TestResponse(t *testing.T) { }) } +func makeName(t *testing.T) (crypto.PrivKey, ipns.Name) { + sk, _, err := crypto.GenerateEd25519Key(rand.Reader) + require.NoError(t, err) + + pid, err := peer.IDFromPrivateKey(sk) + require.NoError(t, err) + + return sk, ipns.NameFromPeer(pid) +} + +func makeIPNSRecord(t *testing.T, cid cid.Cid, sk crypto.PrivKey, opts ...ipns.Option) (*ipns.Record, []byte) { + path := path.IpfsPath(cid) + eol := time.Now().Add(time.Hour * 48) + ttl := time.Second * 20 + + record, err := ipns.NewRecord(sk, ipfspath.FromString(path.String()), 1, eol, ttl, opts...) + require.NoError(t, err) + + rawRecord, err := ipns.MarshalRecord(record) + require.NoError(t, err) + + return record, rawRecord +} + +func TestIPNS(t *testing.T) { + cid1, err := cid.Decode("bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4") + require.NoError(t, err) + + makeRequest := func(t *testing.T, router *mockContentRouter, path string) *http.Response { + server := httptest.NewServer(Handler(router)) + t.Cleanup(server.Close) + serverAddr := "http://" + server.Listener.Addr().String() + urlStr := serverAddr + path + req, err := http.NewRequest(http.MethodGet, urlStr, nil) + require.NoError(t, err) + req.Header.Set("Accept", mediaTypeIPNSRecord) + resp, err := http.DefaultClient.Do(req) + require.NoError(t, err) + return resp + } + + runWithRecordOptions := func(t *testing.T, opts ...ipns.Option) { + sk, name1 := makeName(t) + record1, rawRecord1 := makeIPNSRecord(t, cid1, sk) + + _, name2 := makeName(t) + + t.Run("GET /routing/v1/ipns/{cid-peer-id} returns 200", func(t *testing.T) { + t.Parallel() + + rec, err := ipns.UnmarshalRecord(rawRecord1) + require.NoError(t, err) + + router := &mockContentRouter{} + router.On("FindIPNSRecord", mock.Anything, name1).Return(rec, nil) + + resp := makeRequest(t, router, "/routing/v1/ipns/"+name1.String()) + require.Equal(t, 200, resp.StatusCode) + require.Equal(t, mediaTypeIPNSRecord, resp.Header.Get("Content-Type")) + require.NotEmpty(t, resp.Header.Get("Etag")) + require.Equal(t, "max-age=20", resp.Header.Get("Cache-Control")) + + body, err := io.ReadAll(resp.Body) + require.NoError(t, err) + require.Equal(t, body, rawRecord1) + }) + + t.Run("GET /routing/v1/ipns/{non-peer-cid} returns 400", func(t *testing.T) { + t.Parallel() + + router := &mockContentRouter{} + resp := makeRequest(t, router, "/routing/v1/ipns/"+cid1.String()) + require.Equal(t, 400, resp.StatusCode) + }) + + t.Run("GET /routing/v1/ipns/{peer-id} returns 400", func(t *testing.T) { + t.Parallel() + + router := &mockContentRouter{} + resp := makeRequest(t, router, "/routing/v1/ipns/"+name1.Peer().String()) + require.Equal(t, 400, resp.StatusCode) + }) + + t.Run("PUT /routing/v1/ipns/{cid-peer-id} returns 200", func(t *testing.T) { + t.Parallel() + + router := &mockContentRouter{} + router.On("ProvideIPNSRecord", mock.Anything, name1, record1).Return(nil) + + server := httptest.NewServer(Handler(router)) + t.Cleanup(server.Close) + serverAddr := "http://" + server.Listener.Addr().String() + urlStr := serverAddr + "/routing/v1/ipns/" + name1.String() + + req, err := http.NewRequest(http.MethodPut, urlStr, bytes.NewReader(rawRecord1)) + require.NoError(t, err) + req.Header.Set("Content-Type", mediaTypeIPNSRecord) + + resp, err := http.DefaultClient.Do(req) + require.NoError(t, err) + require.Equal(t, 200, resp.StatusCode) + }) + + t.Run("PUT /routing/v1/ipns/{cid-peer-id} returns 400 for wrong record", func(t *testing.T) { + t.Parallel() + + router := &mockContentRouter{} + + server := httptest.NewServer(Handler(router)) + t.Cleanup(server.Close) + serverAddr := "http://" + server.Listener.Addr().String() + urlStr := serverAddr + "/routing/v1/ipns/" + name2.String() + + req, err := http.NewRequest(http.MethodPut, urlStr, bytes.NewReader(rawRecord1)) + require.NoError(t, err) + req.Header.Set("Content-Type", mediaTypeIPNSRecord) + + resp, err := http.DefaultClient.Do(req) + require.NoError(t, err) + require.Equal(t, 400, resp.StatusCode) + }) + } + + t.Run("V1+V2 IPNS Records", func(t *testing.T) { + runWithRecordOptions(t, ipns.WithV1Compatibility(true)) + }) + + t.Run("V2 IPNS Records", func(t *testing.T) { + runWithRecordOptions(t, ipns.WithV1Compatibility(false)) + }) +} + type mockContentRouter struct{ mock.Mock } func (m *mockContentRouter) FindProviders(ctx context.Context, key cid.Cid, limit int) (iter.ResultIter[types.ProviderResponse], error) { @@ -135,3 +273,13 @@ func (m *mockContentRouter) Provide(ctx context.Context, req *WriteProvideReques args := m.Called(ctx, req) return args.Get(0).(types.ProviderResponse), args.Error(1) } + +func (m *mockContentRouter) FindIPNSRecord(ctx context.Context, name ipns.Name) (*ipns.Record, error) { + args := m.Called(ctx, name) + return args.Get(0).(*ipns.Record), args.Error(1) +} + +func (m *mockContentRouter) ProvideIPNSRecord(ctx context.Context, name ipns.Name, record *ipns.Record) error { + args := m.Called(ctx, name, record) + return args.Error(0) +} From 9e804b4ff2e43c29aabef9f9ea488d19ffc8a180 Mon Sep 17 00:00:00 2001 From: web3-bot Date: Tue, 22 Aug 2023 12:08:37 +0200 Subject: [PATCH 027/312] ci: uci/copy-templates (#431) --- .../internet_latency_delay_generator.go | 2 +- cmd/boxo-migrate/go.mod | 2 +- cmd/deprecator/go.mod | 2 +- examples/go.mod | 96 +++--- examples/go.sum | 318 ++++++----------- examples/unixfs-file-cid/main.go | 2 +- fetcher/helpers/block_visitor_test.go | 2 +- go.mod | 98 +++--- go.sum | 322 ++++++------------ 9 files changed, 296 insertions(+), 548 deletions(-) diff --git a/bitswap/testnet/internet_latency_delay_generator.go b/bitswap/testnet/internet_latency_delay_generator.go index d133ae4cb..4ad758130 100644 --- a/bitswap/testnet/internet_latency_delay_generator.go +++ b/bitswap/testnet/internet_latency_delay_generator.go @@ -4,7 +4,7 @@ import ( "math/rand" "time" - "github.com/ipfs/go-ipfs-delay" + delay "github.com/ipfs/go-ipfs-delay" ) var sharedRNG = rand.New(rand.NewSource(time.Now().UnixNano())) diff --git a/cmd/boxo-migrate/go.mod b/cmd/boxo-migrate/go.mod index 0d6a9cfa4..71f42ac9c 100644 --- a/cmd/boxo-migrate/go.mod +++ b/cmd/boxo-migrate/go.mod @@ -1,6 +1,6 @@ module github.com/ipfs/boxo/cmd/boxo-migrate -go 1.19 +go 1.20 require github.com/urfave/cli/v2 v2.25.1 diff --git a/cmd/deprecator/go.mod b/cmd/deprecator/go.mod index bfc031612..c68dd5412 100644 --- a/cmd/deprecator/go.mod +++ b/cmd/deprecator/go.mod @@ -1,6 +1,6 @@ module github.com/ipfs/boxo/cmd/deprecator -go 1.19 +go 1.20 require ( github.com/dave/dst v0.27.2 diff --git a/examples/go.mod b/examples/go.mod index e68a08ebd..495c2455a 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -1,6 +1,6 @@ module github.com/ipfs/boxo/examples -go 1.19 +go 1.20 require ( github.com/ipfs/boxo v0.8.0 @@ -9,11 +9,11 @@ require ( github.com/ipfs/go-datastore v0.6.0 github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 github.com/ipld/go-ipld-prime v0.21.0 - github.com/libp2p/go-libp2p v0.26.3 + github.com/libp2p/go-libp2p v0.30.0 github.com/libp2p/go-libp2p-routing-helpers v0.7.0 - github.com/multiformats/go-multiaddr v0.8.0 + github.com/multiformats/go-multiaddr v0.11.0 github.com/multiformats/go-multicodec v0.9.0 - github.com/prometheus/client_golang v1.14.0 + github.com/prometheus/client_golang v1.16.0 github.com/stretchr/testify v1.8.4 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.40.0 go.opentelemetry.io/contrib/propagators/autoprop v0.40.0 @@ -22,18 +22,18 @@ require ( ) require ( - github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect - github.com/benbjohnson/clock v1.3.0 // indirect + github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect + github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v4 v4.2.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/containerd/cgroups v1.0.4 // indirect + github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect github.com/cskr/pubsub v1.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/elastic/gosigar v0.14.2 // indirect @@ -41,22 +41,23 @@ require ( github.com/flynn/noise v1.0.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/gabriel-vasile/mimetype v1.4.1 // indirect - github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/mock v1.6.0 // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20221203041831-ce31453925ec // indirect + github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/hashicorp/golang-lru/v2 v2.0.1 // indirect - github.com/huin/goupnp v1.0.3 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect + github.com/huin/goupnp v1.2.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect @@ -75,29 +76,29 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/klauspost/compress v1.15.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.3 // indirect - github.com/koron/go-ssdp v0.0.3 // indirect + github.com/klauspost/compress v1.16.7 // indirect + github.com/klauspost/cpuid/v2 v2.2.5 // indirect + github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-doh-resolver v0.4.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect - github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect + github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect github.com/libp2p/go-libp2p-kad-dht v0.23.0 // indirect github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect - github.com/libp2p/go-nat v0.1.0 // indirect + github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/libp2p/go-reuseport v0.2.0 // indirect - github.com/libp2p/go-yamux/v4 v4.0.0 // indirect + github.com/libp2p/go-reuseport v0.4.0 // indirect + github.com/libp2p/go-yamux/v4 v4.0.1 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/miekg/dns v1.1.50 // indirect + github.com/miekg/dns v1.1.55 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect - github.com/minio/sha256-simd v1.0.0 // indirect + github.com/minio/sha256-simd v1.0.1 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect @@ -107,8 +108,8 @@ require ( github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.5.1 // indirect - github.com/opencontainers/runtime-spec v1.0.2 // indirect + github.com/onsi/ginkgo/v2 v2.11.0 // indirect + github.com/opencontainers/runtime-spec v1.1.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect @@ -116,14 +117,13 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.37.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect + github.com/prometheus/client_model v0.4.0 // indirect + github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/procfs v0.11.1 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-19 v0.2.1 // indirect - github.com/quic-go/qtls-go1-20 v0.1.1 // indirect - github.com/quic-go/quic-go v0.33.0 // indirect - github.com/quic-go/webtransport-go v0.5.2 // indirect + github.com/quic-go/qtls-go1-20 v0.3.2 // indirect + github.com/quic-go/quic-go v0.38.0 // indirect + github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect @@ -147,27 +147,25 @@ require ( go.opentelemetry.io/otel/metric v0.37.0 // indirect go.opentelemetry.io/otel/trace v1.14.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect - go.uber.org/atomic v1.10.0 // indirect - go.uber.org/dig v1.15.0 // indirect - go.uber.org/fx v1.18.2 // indirect - go.uber.org/multierr v1.9.0 // indirect - go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.6.0 // indirect - golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb // indirect - golang.org/x/mod v0.7.0 // indirect - golang.org/x/net v0.7.0 // indirect - golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/text v0.7.0 // indirect - golang.org/x/tools v0.3.0 // indirect + go.uber.org/dig v1.17.0 // indirect + go.uber.org/fx v1.20.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.25.0 // indirect + golang.org/x/crypto v0.12.0 // indirect + golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect + golang.org/x/mod v0.12.0 // indirect + golang.org/x/net v0.14.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect + golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.11.0 // indirect google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect google.golang.org/grpc v1.53.0 // indirect - google.golang.org/protobuf v1.30.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - lukechampine.com/blake3 v1.1.7 // indirect - nhooyr.io/websocket v1.8.7 // indirect + lukechampine.com/blake3 v1.2.1 // indirect ) replace github.com/ipfs/boxo => ../ diff --git a/examples/go.sum b/examples/go.sum index 0c23da44d..eaec6f954 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -41,20 +41,15 @@ git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGy github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a h1:E/8AP5dFtMhl5KPJz66Kt9G0n+7Sn41Fy1wv9/jHOrc= -github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= @@ -64,7 +59,6 @@ github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -80,8 +74,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= -github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA= -github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= +github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= +github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= @@ -97,9 +91,9 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -127,45 +121,19 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkFtf/dnN7Q= github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= @@ -206,8 +174,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/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= @@ -219,14 +188,11 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -238,8 +204,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20221203041831-ce31453925ec h1:fR20TYVVwhK4O7r7y+McjRYyaTH6/vjwJOajE+XhlzM= -github.com/google/pprof v0.0.0-20221203041831-ce31453925ec/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= +github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6osliIIpF9K4F5jvkULXa4daRDQ= +github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= @@ -250,8 +216,8 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= @@ -268,12 +234,10 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru/v2 v2.0.1 h1:5pv5N1lT1fjLg2VQ5KWc7kmucp2x/kvFOnxuVTqZ6x4= -github.com/hashicorp/golang-lru/v2 v2.0.1/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= -github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= -github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4= +github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= +github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= @@ -343,36 +307,21 @@ github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPw github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= -github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= -github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= -github.com/koron/go-ssdp v0.0.3 h1:JivLMY45N76b4p/vsWGOKewBQu6uf39y8l+AQ7sDKx8= -github.com/koron/go-ssdp v0.0.3/go.mod h1:b2MxI6yh02pKrsyNoQUsk4+YNikaGhe4894J+Q5lDvA= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= +github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= +github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -380,8 +329,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= @@ -390,10 +337,10 @@ github.com/libp2p/go-doh-resolver v0.4.0 h1:gUBa1f1XsPwtpE1du0O+nnZCUqtG7oYi7Bb+ github.com/libp2p/go-doh-resolver v0.4.0/go.mod h1:v1/jwsFusgsWIGX/c6vCRrnJ60x7bhTiq/fs2qt0cAg= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.26.3 h1:6g/psubqwdaBqNNoidbRKSTBEYgaOuKBhHl8Q5tO+PM= -github.com/libp2p/go-libp2p v0.26.3/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= -github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= -github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= +github.com/libp2p/go-libp2p v0.30.0 h1:9EZwFtJPFBcs/yJTnP90TpN1hgrT/EsFfM+OZuwV87U= +github.com/libp2p/go-libp2p v0.30.0/go.mod h1:nr2g5V7lfftwgiJ78/HrID+pwvayLyqKCEirT2Y3Byg= +github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= +github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-kad-dht v0.23.0 h1:sxE6LxLopp79eLeV695n7+c77V/Vn4AMF28AdM/XFqM= github.com/libp2p/go-libp2p-kad-dht v0.23.0/go.mod h1:oO5N308VT2msnQI6qi5M61wzPmJYg7Tr9e16m5n7uDU= github.com/libp2p/go-libp2p-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= @@ -405,31 +352,28 @@ github.com/libp2p/go-libp2p-routing-helpers v0.7.0/go.mod h1:R289GUxUMzRXIbWGSuU github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= -github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= -github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM= -github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= +github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= -github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= -github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= -github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= -github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= -github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= +github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= +github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= +github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= +github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= -github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= +github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -439,15 +383,10 @@ github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4S github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= -github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= +github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= @@ -461,8 +400,8 @@ github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9 github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= -github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= +github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10= +github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -486,15 +425,14 @@ github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw= -github.com/onsi/ginkgo/v2 v2.5.1/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= -github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= -github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= +github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= +github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= +github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= +github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= @@ -504,7 +442,6 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2D github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -514,49 +451,31 @@ github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXx github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= +github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-19 v0.2.1 h1:aJcKNMkH5ASEJB9FXNeZCyTEIHU1J7MmHyz1Q1TSG1A= -github.com/quic-go/qtls-go1-19 v0.2.1/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.1.1 h1:KbChDlg82d3IHqaj2bn6GfKRj84Per2VGf5XV3wSwQk= -github.com/quic-go/qtls-go1-20 v0.1.1/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= -github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= -github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= -github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/qtls-go1-20 v0.3.2 h1:rRgN3WfnKbyik4dBV8A6girlJVxGand/d+jVKbQq5GI= +github.com/quic-go/qtls-go1-20 v0.3.2/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.38.0 h1:T45lASr5q/TrVwt+jrVccmqHhPL2XuSyoCLVCpfOSLc= +github.com/quic-go/quic-go v0.38.0/go.mod h1:MPCuRq7KBK2hNcfKj/1iD1BGuN3eAYMeNxp3T42LRUg= +github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= +github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= @@ -583,9 +502,6 @@ github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go. github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= @@ -599,7 +515,6 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -607,6 +522,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -617,10 +533,6 @@ github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cb github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb h1:Ywfo8sUltxogBpFuMOFRrrSifO788kAFxmvVw31PtQQ= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb/go.mod h1:ikPs9bRWicNw3S7XpJ8sK/smGwU9WcSVU3dy9qahYBM= -github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= @@ -692,26 +604,24 @@ go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJP go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.15.0 h1:vq3YWr8zRj1eFGC7Gvf907hE0eRjPTZ1d3xHadD6liE= -go.uber.org/dig v1.15.0/go.mod h1:pKHs0wMynzL6brANhB2hLMro+zalv1osARTviTcqHLM= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= +go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= +go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ= +go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= -go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= +go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -723,8 +633,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -735,8 +645,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb h1:PaBZQdo+iSDyHT053FjUCgZQ/9uqVwPOcl7KSWhKn6w= -golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -759,15 +669,13 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -776,7 +684,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -799,13 +706,9 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -813,9 +716,7 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -826,24 +727,18 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -853,9 +748,7 @@ golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-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= @@ -869,26 +762,19 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -897,10 +783,9 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -955,9 +840,8 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= -golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= +golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1065,12 +949,10 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 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= @@ -1078,12 +960,8 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -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= @@ -1097,10 +975,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.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= -lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= -nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= -nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= +lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/examples/unixfs-file-cid/main.go b/examples/unixfs-file-cid/main.go index 55a753f21..e1adad350 100644 --- a/examples/unixfs-file-cid/main.go +++ b/examples/unixfs-file-cid/main.go @@ -32,7 +32,7 @@ import ( unixfile "github.com/ipfs/boxo/ipld/unixfs/file" "github.com/ipfs/boxo/ipld/unixfs/importer/balanced" uih "github.com/ipfs/boxo/ipld/unixfs/importer/helpers" - "github.com/libp2p/go-libp2p-routing-helpers" + routinghelpers "github.com/libp2p/go-libp2p-routing-helpers" bsclient "github.com/ipfs/boxo/bitswap/client" bsnet "github.com/ipfs/boxo/bitswap/network" diff --git a/fetcher/helpers/block_visitor_test.go b/fetcher/helpers/block_visitor_test.go index df2cd1cf9..57d3e11ad 100644 --- a/fetcher/helpers/block_visitor_test.go +++ b/fetcher/helpers/block_visitor_test.go @@ -12,7 +12,7 @@ import ( bsfetcher "github.com/ipfs/boxo/fetcher/impl/blockservice" "github.com/ipfs/boxo/fetcher/testutil" mockrouting "github.com/ipfs/boxo/routing/mock" - "github.com/ipfs/go-block-format" + blocks "github.com/ipfs/go-block-format" delay "github.com/ipfs/go-ipfs-delay" "github.com/ipld/go-ipld-prime" "github.com/ipld/go-ipld-prime/fluent" diff --git a/go.mod b/go.mod index 0fdb8067e..2f4d53569 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,10 @@ module github.com/ipfs/boxo -go 1.19 +go 1.20 require ( - github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a - github.com/benbjohnson/clock v1.3.0 + github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 + github.com/benbjohnson/clock v1.3.5 github.com/cespare/xxhash/v2 v2.2.0 github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 github.com/cskr/pubsub v1.0.2 @@ -13,7 +13,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/gorilla/mux v1.8.0 - github.com/hashicorp/golang-lru/v2 v2.0.1 + github.com/hashicorp/golang-lru/v2 v2.0.5 github.com/ipfs/bbloom v0.0.4 github.com/ipfs/go-bitfield v1.1.0 github.com/ipfs/go-block-format v0.1.2 @@ -37,16 +37,16 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/libp2p/go-buffer-pool v0.1.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.26.3 + github.com/libp2p/go-libp2p v0.30.0 github.com/libp2p/go-libp2p-kad-dht v0.23.0 github.com/libp2p/go-libp2p-record v0.2.0 github.com/libp2p/go-libp2p-routing-helpers v0.7.0 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-msgio v0.3.0 - github.com/miekg/dns v1.1.50 + github.com/miekg/dns v1.1.55 github.com/mr-tron/base58 v1.2.0 github.com/multiformats/go-base32 v0.1.0 - github.com/multiformats/go-multiaddr v0.8.0 + github.com/multiformats/go-multiaddr v0.11.0 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multicodec v0.9.0 @@ -54,7 +54,7 @@ require ( github.com/multiformats/go-multistream v0.4.1 github.com/pkg/errors v0.9.1 github.com/polydawn/refmt v0.89.0 - github.com/prometheus/client_golang v1.14.0 + github.com/prometheus/client_golang v1.16.0 github.com/samber/lo v1.36.0 github.com/spaolacci/murmur3 v1.1.0 github.com/stretchr/testify v1.8.4 @@ -69,82 +69,82 @@ require ( go.opentelemetry.io/otel/exporters/zipkin v1.14.0 go.opentelemetry.io/otel/sdk v1.14.0 go.opentelemetry.io/otel/trace v1.14.0 - go.uber.org/multierr v1.9.0 - go.uber.org/zap v1.24.0 - golang.org/x/oauth2 v0.4.0 - golang.org/x/sync v0.1.0 - golang.org/x/sys v0.6.0 - google.golang.org/protobuf v1.30.0 + go.uber.org/multierr v1.11.0 + go.uber.org/zap v1.25.0 + golang.org/x/oauth2 v0.8.0 + golang.org/x/sync v0.3.0 + golang.org/x/sys v0.11.0 + google.golang.org/protobuf v1.31.0 ) require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v4 v4.2.0 // indirect - github.com/containerd/cgroups v1.0.4 // indirect + github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/elastic/gosigar v0.14.2 // indirect github.com/flynn/noise v1.0.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect - github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/mock v1.6.0 // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20221203041831-ce31453925ec // indirect + github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c // indirect + github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/huin/goupnp v1.0.3 // indirect + github.com/huin/goupnp v1.2.0 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-util v0.0.2 // indirect github.com/ipfs/go-log v1.0.5 // indirect github.com/ipfs/go-unixfs v0.4.5 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect - github.com/klauspost/compress v1.15.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.3 // indirect - github.com/koron/go-ssdp v0.0.3 // indirect + github.com/klauspost/compress v1.16.7 // indirect + github.com/klauspost/cpuid/v2 v2.2.5 // indirect + github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect - github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect + github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect - github.com/libp2p/go-nat v0.1.0 // indirect + github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/libp2p/go-reuseport v0.2.0 // indirect - github.com/libp2p/go-yamux/v4 v4.0.0 // indirect + github.com/libp2p/go-reuseport v0.4.0 // indirect + github.com/libp2p/go-yamux/v4 v4.0.1 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect - github.com/minio/sha256-simd v1.0.0 // indirect + github.com/minio/sha256-simd v1.0.1 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.5.1 // indirect - github.com/opencontainers/runtime-spec v1.0.2 // indirect + github.com/onsi/ginkgo/v2 v2.11.0 // indirect + github.com/opencontainers/runtime-spec v1.1.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.37.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect + github.com/prometheus/client_model v0.4.0 // indirect + github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/procfs v0.11.1 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-19 v0.2.1 // indirect - github.com/quic-go/qtls-go1-20 v0.1.1 // indirect - github.com/quic-go/quic-go v0.33.0 // indirect - github.com/quic-go/webtransport-go v0.5.2 // indirect + github.com/quic-go/qtls-go1-20 v0.3.2 // indirect + github.com/quic-go/quic-go v0.38.0 // indirect + github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect @@ -154,21 +154,19 @@ require ( go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect - go.uber.org/atomic v1.10.0 // indirect - go.uber.org/dig v1.15.0 // indirect - go.uber.org/fx v1.18.2 // indirect - golang.org/x/crypto v0.6.0 // indirect - golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb // indirect - golang.org/x/mod v0.7.0 // indirect - golang.org/x/net v0.7.0 // indirect - golang.org/x/text v0.7.0 // indirect - golang.org/x/tools v0.3.0 // indirect + go.uber.org/dig v1.17.0 // indirect + go.uber.org/fx v1.20.0 // indirect + golang.org/x/crypto v0.12.0 // indirect + golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect + golang.org/x/mod v0.12.0 // indirect + golang.org/x/net v0.14.0 // indirect + golang.org/x/text v0.12.0 // indirect + golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.11.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect google.golang.org/grpc v1.53.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - lukechampine.com/blake3 v1.1.7 // indirect - nhooyr.io/websocket v1.8.7 // indirect + lukechampine.com/blake3 v1.2.1 // indirect ) diff --git a/go.sum b/go.sum index d6583aa5a..8beabe300 100644 --- a/go.sum +++ b/go.sum @@ -41,20 +41,15 @@ git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGy github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a h1:E/8AP5dFtMhl5KPJz66Kt9G0n+7Sn41Fy1wv9/jHOrc= -github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= @@ -64,7 +59,6 @@ github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -80,8 +74,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= -github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA= -github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= +github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= +github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= @@ -97,9 +91,9 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -125,45 +119,19 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkFtf/dnN7Q= github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= @@ -205,8 +173,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/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= @@ -218,14 +187,11 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -237,8 +203,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20221203041831-ce31453925ec h1:fR20TYVVwhK4O7r7y+McjRYyaTH6/vjwJOajE+XhlzM= -github.com/google/pprof v0.0.0-20221203041831-ce31453925ec/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= +github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6osliIIpF9K4F5jvkULXa4daRDQ= +github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= @@ -252,8 +218,8 @@ github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRid github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= @@ -270,12 +236,10 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru/v2 v2.0.1 h1:5pv5N1lT1fjLg2VQ5KWc7kmucp2x/kvFOnxuVTqZ6x4= -github.com/hashicorp/golang-lru/v2 v2.0.1/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= -github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= -github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4= +github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= +github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= @@ -349,36 +313,21 @@ github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPw github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= -github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= -github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= -github.com/koron/go-ssdp v0.0.3 h1:JivLMY45N76b4p/vsWGOKewBQu6uf39y8l+AQ7sDKx8= -github.com/koron/go-ssdp v0.0.3/go.mod h1:b2MxI6yh02pKrsyNoQUsk4+YNikaGhe4894J+Q5lDvA= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= +github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= +github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -386,8 +335,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= @@ -396,10 +343,10 @@ github.com/libp2p/go-doh-resolver v0.4.0 h1:gUBa1f1XsPwtpE1du0O+nnZCUqtG7oYi7Bb+ github.com/libp2p/go-doh-resolver v0.4.0/go.mod h1:v1/jwsFusgsWIGX/c6vCRrnJ60x7bhTiq/fs2qt0cAg= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.26.3 h1:6g/psubqwdaBqNNoidbRKSTBEYgaOuKBhHl8Q5tO+PM= -github.com/libp2p/go-libp2p v0.26.3/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= -github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= -github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= +github.com/libp2p/go-libp2p v0.30.0 h1:9EZwFtJPFBcs/yJTnP90TpN1hgrT/EsFfM+OZuwV87U= +github.com/libp2p/go-libp2p v0.30.0/go.mod h1:nr2g5V7lfftwgiJ78/HrID+pwvayLyqKCEirT2Y3Byg= +github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= +github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-kad-dht v0.23.0 h1:sxE6LxLopp79eLeV695n7+c77V/Vn4AMF28AdM/XFqM= github.com/libp2p/go-libp2p-kad-dht v0.23.0/go.mod h1:oO5N308VT2msnQI6qi5M61wzPmJYg7Tr9e16m5n7uDU= github.com/libp2p/go-libp2p-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= @@ -412,31 +359,28 @@ github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUI github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= -github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= -github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM= -github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= +github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= -github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= -github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= -github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= -github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= -github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= +github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= +github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= +github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= +github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= -github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= +github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -446,15 +390,10 @@ github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4S github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= -github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= +github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= @@ -468,8 +407,8 @@ github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9 github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= -github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= +github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10= +github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -493,15 +432,14 @@ github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw= -github.com/onsi/ginkgo/v2 v2.5.1/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= -github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= -github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= +github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= +github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= +github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= +github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= @@ -511,7 +449,6 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2D github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -521,49 +458,31 @@ github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXx github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= +github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-19 v0.2.1 h1:aJcKNMkH5ASEJB9FXNeZCyTEIHU1J7MmHyz1Q1TSG1A= -github.com/quic-go/qtls-go1-19 v0.2.1/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.1.1 h1:KbChDlg82d3IHqaj2bn6GfKRj84Per2VGf5XV3wSwQk= -github.com/quic-go/qtls-go1-20 v0.1.1/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= -github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= -github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= -github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/qtls-go1-20 v0.3.2 h1:rRgN3WfnKbyik4dBV8A6girlJVxGand/d+jVKbQq5GI= +github.com/quic-go/qtls-go1-20 v0.3.2/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.38.0 h1:T45lASr5q/TrVwt+jrVccmqHhPL2XuSyoCLVCpfOSLc= +github.com/quic-go/quic-go v0.38.0/go.mod h1:MPCuRq7KBK2hNcfKj/1iD1BGuN3eAYMeNxp3T42LRUg= +github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= +github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/samber/lo v1.36.0 h1:4LaOxH1mHnbDGhTVE0i1z8v/lWaQW8AIfOD3HU4mSaw= @@ -592,9 +511,6 @@ github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go. github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= @@ -608,7 +524,6 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -616,6 +531,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -627,10 +543,6 @@ github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb h1:Ywfo8sUltxogBpFuMOFRrrSifO788kAFxmvVw31PtQQ= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb/go.mod h1:ikPs9bRWicNw3S7XpJ8sK/smGwU9WcSVU3dy9qahYBM= -github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= @@ -688,26 +600,24 @@ go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJP go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.15.0 h1:vq3YWr8zRj1eFGC7Gvf907hE0eRjPTZ1d3xHadD6liE= -go.uber.org/dig v1.15.0/go.mod h1:pKHs0wMynzL6brANhB2hLMro+zalv1osARTviTcqHLM= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= +go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= +go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ= +go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= -go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= +go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -719,8 +629,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -731,8 +641,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb h1:PaBZQdo+iSDyHT053FjUCgZQ/9uqVwPOcl7KSWhKn6w= -golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -755,15 +665,13 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -772,7 +680,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -795,13 +702,9 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -809,11 +712,9 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M= -golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= +golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -824,24 +725,18 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -851,9 +746,7 @@ golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-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= @@ -867,26 +760,19 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -895,10 +781,9 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -953,9 +838,8 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= -golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= +golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1065,12 +949,10 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 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= @@ -1078,12 +960,8 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -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= @@ -1097,10 +975,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.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= -lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= -nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= -nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= +lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= From bc79f7e62be16bc9d56fb02f136d6613423f8365 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 22 Aug 2023 12:25:41 +0200 Subject: [PATCH 028/312] changelog: tidy up changelog for v0.12.0 --- CHANGELOG.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70c48746a..7afe79f54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,11 +16,22 @@ The following emojis are used to highlight certain changes: ### Added +### Changed + +### Removed + +### Fixed + +### Security + +## [v0.12.0] + +### Added + * The `routing/http` client and server now support Delegated IPNS at `/routing/v1` as per [IPIP-379](https://specs.ipfs.tech/ipips/ipip-0379/). -* The `verifycid` package has been updated with the new Allowlist interface as part of - reducing globals efforts. Still, existing global accessor funcs are kept for - backwards-compatibility. +* 🛠 The `verifycid` package has been updated with the new Allowlist interface as part of + reducing globals efforts. * The `blockservice` and `provider` packages has been updated to accommodate for changes in `verifycid`. From 2aa2c0f19d3760b411931f3865a1da5b2e3e6332 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 22 Aug 2023 12:26:19 +0200 Subject: [PATCH 029/312] chore: release v0.12.0 --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index ea22ea591..21e148a94 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "v0.11.0" + "version": "v0.12.0" } From 303595bcdba7c4ff1e4186a8089a550df6da9d28 Mon Sep 17 00:00:00 2001 From: Wondertan Date: Tue, 22 Aug 2023 14:05:58 +0200 Subject: [PATCH 030/312] blockservice/test: passthrough blockservice options --- blockservice/test/mock.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blockservice/test/mock.go b/blockservice/test/mock.go index fa6469fb6..e32b10b99 100644 --- a/blockservice/test/mock.go +++ b/blockservice/test/mock.go @@ -9,7 +9,7 @@ import ( ) // Mocks returns |n| connected mock Blockservices -func Mocks(n int) []blockservice.BlockService { +func Mocks(n int, opts ...blockservice.Option) []blockservice.BlockService { net := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(0)) sg := testinstance.NewTestInstanceGenerator(net, nil, nil) @@ -17,7 +17,7 @@ func Mocks(n int) []blockservice.BlockService { var servs []blockservice.BlockService for _, i := range instances { - servs = append(servs, blockservice.New(i.Blockstore(), i.Exchange)) + servs = append(servs, blockservice.New(i.Blockstore(), i.Exchange, opts...)) } return servs } From 38ecf0e69e8c8c63d8879e298e986799eaa4764b Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 3 Aug 2023 18:58:51 +0200 Subject: [PATCH 031/312] bitswap: reenable tests This only enable tests that weren't always failing on CI. --- bitswap/bitswap_test.go | 35 ------------------- bitswap/client/bitswap_with_sessions_test.go | 19 ---------- .../blockpresencemanager_test.go | 7 ---- .../messagequeue/donthavetimeoutmgr_test.go | 19 ---------- .../messagequeue/messagequeue_test.go | 22 ------------ .../notifications/notifications_test.go | 12 ------- .../internal/peermanager/peermanager_test.go | 13 ------- .../peermanager/peerwantmanager_test.go | 15 -------- .../providerquerymanager_test.go | 19 ---------- .../client/internal/session/session_test.go | 12 ------- .../internal/session/sessionwants_test.go | 9 ----- .../session/sessionwantsender_test.go | 29 --------------- .../sessioninterestmanager_test.go | 13 ------- .../sessionmanager/sessionmanager_test.go | 9 ----- .../sessionpeermanager_test.go | 19 ---------- bitswap/client/wantlist/wantlist_test.go | 21 ----------- bitswap/network/connecteventmanager_test.go | 7 ---- bitswap/network/ipfs_impl_test.go | 13 ------- bitswap/network/ipfs_impl_timeout_test.go | 3 -- .../decision/blockstoremanager_test.go | 13 ------- .../server/internal/decision/engine_test.go | 29 --------------- .../internal/decision/taskmerger_test.go | 9 ----- 22 files changed, 347 deletions(-) diff --git a/bitswap/bitswap_test.go b/bitswap/bitswap_test.go index 02bd57947..014f75a07 100644 --- a/bitswap/bitswap_test.go +++ b/bitswap/bitswap_test.go @@ -14,7 +14,6 @@ import ( "github.com/ipfs/boxo/bitswap/server" testinstance "github.com/ipfs/boxo/bitswap/testinstance" tn "github.com/ipfs/boxo/bitswap/testnet" - "github.com/ipfs/boxo/internal/test" mockrouting "github.com/ipfs/boxo/routing/mock" blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" @@ -49,8 +48,6 @@ func addBlock(t *testing.T, ctx context.Context, inst testinstance.Instance, blk const kNetworkDelay = 0 * time.Millisecond func TestClose(t *testing.T) { - test.Flaky(t) - vnet := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay)) ig := testinstance.NewTestInstanceGenerator(vnet, nil, nil) defer ig.Close() @@ -67,8 +64,6 @@ func TestClose(t *testing.T) { } func TestProviderForKeyButNetworkCannotFind(t *testing.T) { // TODO revisit this - test.Flaky(t) - rs := mockrouting.NewServer() net := tn.VirtualNetwork(rs, delay.Fixed(kNetworkDelay)) ig := testinstance.NewTestInstanceGenerator(net, nil, nil) @@ -94,8 +89,6 @@ func TestProviderForKeyButNetworkCannotFind(t *testing.T) { // TODO revisit this } func TestGetBlockFromPeerAfterPeerAnnounces(t *testing.T) { - test.Flaky(t) - net := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay)) block := blocks.NewBlock([]byte("block")) ig := testinstance.NewTestInstanceGenerator(net, nil, nil) @@ -124,8 +117,6 @@ func TestGetBlockFromPeerAfterPeerAnnounces(t *testing.T) { } func TestDoesNotProvideWhenConfiguredNotTo(t *testing.T) { - test.Flaky(t) - net := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay)) block := blocks.NewBlock([]byte("block")) bsOpts := []bitswap.Option{bitswap.ProvideEnabled(false), bitswap.ProviderSearchDelay(50 * time.Millisecond)} @@ -158,8 +149,6 @@ func TestDoesNotProvideWhenConfiguredNotTo(t *testing.T) { // Tests that a received block is not stored in the blockstore if the block was // not requested by the client func TestUnwantedBlockNotAdded(t *testing.T) { - test.Flaky(t) - net := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay)) block := blocks.NewBlock([]byte("block")) bsMessage := bsmsg.New(true) @@ -195,8 +184,6 @@ func TestUnwantedBlockNotAdded(t *testing.T) { // // (because the live request queue is full) func TestPendingBlockAdded(t *testing.T) { - test.Flaky(t) - ctx := context.Background() net := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay)) bg := blocksutil.NewBlockGenerator() @@ -245,8 +232,6 @@ func TestPendingBlockAdded(t *testing.T) { } func TestLargeSwarm(t *testing.T) { - test.Flaky(t) - if testing.Short() { t.SkipNow() } @@ -279,8 +264,6 @@ func TestLargeFile(t *testing.T) { } func TestLargeFileTwoPeers(t *testing.T) { - test.Flaky(t) - if testing.Short() { t.SkipNow() } @@ -290,8 +273,6 @@ func TestLargeFileTwoPeers(t *testing.T) { } func PerformDistributionTest(t *testing.T, numInstances, numBlocks int) { - test.Flaky(t) - ctx := context.Background() if testing.Short() { t.SkipNow() @@ -349,8 +330,6 @@ func PerformDistributionTest(t *testing.T, numInstances, numBlocks int) { // TODO simplify this test. get to the _essence_! func TestSendToWantingPeer(t *testing.T) { - test.Flaky(t) - if testing.Short() { t.SkipNow() } @@ -393,8 +372,6 @@ func TestSendToWantingPeer(t *testing.T) { } func TestEmptyKey(t *testing.T) { - test.Flaky(t) - net := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay)) ig := testinstance.NewTestInstanceGenerator(net, nil, nil) defer ig.Close() @@ -428,8 +405,6 @@ func assertStat(t *testing.T, st *bitswap.Stat, sblks, rblks, sdata, rdata uint6 } func TestBasicBitswap(t *testing.T) { - test.Flaky(t) - net := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay)) ig := testinstance.NewTestInstanceGenerator(net, nil, nil) defer ig.Close() @@ -502,8 +477,6 @@ func TestBasicBitswap(t *testing.T) { } func TestDoubleGet(t *testing.T) { - test.Flaky(t) - net := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay)) ig := testinstance.NewTestInstanceGenerator(net, nil, nil) defer ig.Close() @@ -569,8 +542,6 @@ func TestDoubleGet(t *testing.T) { } func TestWantlistCleanup(t *testing.T) { - test.Flaky(t) - net := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay)) ig := testinstance.NewTestInstanceGenerator(net, nil, nil) defer ig.Close() @@ -693,8 +664,6 @@ func newReceipt(sent, recv, exchanged uint64) *server.Receipt { } func TestBitswapLedgerOneWay(t *testing.T) { - test.Flaky(t) - net := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay)) ig := testinstance.NewTestInstanceGenerator(net, nil, nil) defer ig.Close() @@ -744,8 +713,6 @@ func TestBitswapLedgerOneWay(t *testing.T) { } func TestBitswapLedgerTwoWay(t *testing.T) { - test.Flaky(t) - net := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay)) ig := testinstance.NewTestInstanceGenerator(net, nil, nil) defer ig.Close() @@ -834,8 +801,6 @@ func (tsl *testingScoreLedger) Stop() { // Tests start and stop of a custom decision logic func TestWithScoreLedger(t *testing.T) { - test.Flaky(t) - tsl := newTestingScoreLedger() net := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay)) bsOpts := []bitswap.Option{bitswap.WithScoreLedger(tsl)} diff --git a/bitswap/client/bitswap_with_sessions_test.go b/bitswap/client/bitswap_with_sessions_test.go index 2191a5a90..54c320236 100644 --- a/bitswap/client/bitswap_with_sessions_test.go +++ b/bitswap/client/bitswap_with_sessions_test.go @@ -11,7 +11,6 @@ import ( "github.com/ipfs/boxo/bitswap/client/traceability" testinstance "github.com/ipfs/boxo/bitswap/testinstance" tn "github.com/ipfs/boxo/bitswap/testnet" - "github.com/ipfs/boxo/internal/test" mockrouting "github.com/ipfs/boxo/routing/mock" blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" @@ -40,8 +39,6 @@ func addBlock(t *testing.T, ctx context.Context, inst testinstance.Instance, blk } func TestBasicSessions(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -109,8 +106,6 @@ func assertBlockListsFrom(from peer.ID, got, exp []blocks.Block) error { } func TestSessionBetweenPeers(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -171,8 +166,6 @@ func TestSessionBetweenPeers(t *testing.T) { } func TestSessionSplitFetch(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -217,8 +210,6 @@ func TestSessionSplitFetch(t *testing.T) { } func TestFetchNotConnected(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() @@ -262,8 +253,6 @@ func TestFetchNotConnected(t *testing.T) { } func TestFetchAfterDisconnect(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() @@ -342,8 +331,6 @@ func TestFetchAfterDisconnect(t *testing.T) { } func TestInterestCacheOverflow(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -394,8 +381,6 @@ func TestInterestCacheOverflow(t *testing.T) { } func TestPutAfterSessionCacheEvict(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -434,8 +419,6 @@ func TestPutAfterSessionCacheEvict(t *testing.T) { } func TestMultipleSessions(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -477,8 +460,6 @@ func TestMultipleSessions(t *testing.T) { } func TestWantlistClearsOnCancel(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() diff --git a/bitswap/client/internal/blockpresencemanager/blockpresencemanager_test.go b/bitswap/client/internal/blockpresencemanager/blockpresencemanager_test.go index 5e30073a3..b0616e4e3 100644 --- a/bitswap/client/internal/blockpresencemanager/blockpresencemanager_test.go +++ b/bitswap/client/internal/blockpresencemanager/blockpresencemanager_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/ipfs/boxo/bitswap/internal/testutil" - "github.com/ipfs/boxo/internal/test" cid "github.com/ipfs/go-cid" peer "github.com/libp2p/go-libp2p/core/peer" ) @@ -17,8 +16,6 @@ const ( ) func TestBlockPresenceManager(t *testing.T) { - test.Flaky(t) - bpm := New() p := testutil.GeneratePeers(1)[0] @@ -99,8 +96,6 @@ func TestBlockPresenceManager(t *testing.T) { } func TestAddRemoveMulti(t *testing.T) { - test.Flaky(t) - bpm := New() peers := testutil.GeneratePeers(2) @@ -184,8 +179,6 @@ func TestAddRemoveMulti(t *testing.T) { } func TestAllPeersDoNotHaveBlock(t *testing.T) { - test.Flaky(t) - bpm := New() peers := testutil.GeneratePeers(3) diff --git a/bitswap/client/internal/messagequeue/donthavetimeoutmgr_test.go b/bitswap/client/internal/messagequeue/donthavetimeoutmgr_test.go index a6a28aab1..ee90ddde9 100644 --- a/bitswap/client/internal/messagequeue/donthavetimeoutmgr_test.go +++ b/bitswap/client/internal/messagequeue/donthavetimeoutmgr_test.go @@ -9,7 +9,6 @@ import ( "github.com/benbjohnson/clock" "github.com/ipfs/boxo/bitswap/internal/testutil" - "github.com/ipfs/boxo/internal/test" cid "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p/p2p/protocol/ping" ) @@ -74,8 +73,6 @@ func (tr *timeoutRecorder) clear() { } func TestDontHaveTimeoutMgrTimeout(t *testing.T) { - test.Flaky(t) - firstks := testutil.GenerateCids(2) secondks := append(firstks, testutil.GenerateCids(3)...) latency := time.Millisecond * 20 @@ -132,8 +129,6 @@ func TestDontHaveTimeoutMgrTimeout(t *testing.T) { } func TestDontHaveTimeoutMgrCancel(t *testing.T) { - test.Flaky(t) - ks := testutil.GenerateCids(3) latency := time.Millisecond * 10 latMultiplier := 1 @@ -170,8 +165,6 @@ func TestDontHaveTimeoutMgrCancel(t *testing.T) { } func TestDontHaveTimeoutWantCancelWant(t *testing.T) { - test.Flaky(t) - ks := testutil.GenerateCids(3) latency := time.Millisecond * 20 latMultiplier := 1 @@ -225,8 +218,6 @@ func TestDontHaveTimeoutWantCancelWant(t *testing.T) { } func TestDontHaveTimeoutRepeatedAddPending(t *testing.T) { - test.Flaky(t) - ks := testutil.GenerateCids(10) latency := time.Millisecond * 5 latMultiplier := 1 @@ -260,8 +251,6 @@ func TestDontHaveTimeoutRepeatedAddPending(t *testing.T) { } func TestDontHaveTimeoutMgrMessageLatency(t *testing.T) { - test.Flaky(t) - ks := testutil.GenerateCids(2) latency := time.Millisecond * 40 latMultiplier := 1 @@ -311,8 +300,6 @@ func TestDontHaveTimeoutMgrMessageLatency(t *testing.T) { } func TestDontHaveTimeoutMgrMessageLatencyMax(t *testing.T) { - test.Flaky(t) - ks := testutil.GenerateCids(2) clock := clock.NewMock() pinged := make(chan struct{}) @@ -346,8 +333,6 @@ func TestDontHaveTimeoutMgrMessageLatencyMax(t *testing.T) { } func TestDontHaveTimeoutMgrUsesDefaultTimeoutIfPingError(t *testing.T) { - test.Flaky(t) - ks := testutil.GenerateCids(2) latency := time.Millisecond * 1 latMultiplier := 2 @@ -389,8 +374,6 @@ func TestDontHaveTimeoutMgrUsesDefaultTimeoutIfPingError(t *testing.T) { } func TestDontHaveTimeoutMgrUsesDefaultTimeoutIfLatencyLonger(t *testing.T) { - test.Flaky(t) - ks := testutil.GenerateCids(2) latency := time.Millisecond * 200 latMultiplier := 1 @@ -431,8 +414,6 @@ func TestDontHaveTimeoutMgrUsesDefaultTimeoutIfLatencyLonger(t *testing.T) { } func TestDontHaveTimeoutNoTimeoutAfterShutdown(t *testing.T) { - test.Flaky(t) - ks := testutil.GenerateCids(2) latency := time.Millisecond * 10 latMultiplier := 1 diff --git a/bitswap/client/internal/messagequeue/messagequeue_test.go b/bitswap/client/internal/messagequeue/messagequeue_test.go index 886e60772..9abfa68b0 100644 --- a/bitswap/client/internal/messagequeue/messagequeue_test.go +++ b/bitswap/client/internal/messagequeue/messagequeue_test.go @@ -161,8 +161,6 @@ func expectEvent(t *testing.T, events <-chan messageEvent, expectedEvent message } func TestStartupAndShutdown(t *testing.T) { - test.Flaky(t) - ctx := context.Background() messagesSent := make(chan []bsmsg.Entry) resetChan := make(chan struct{}, 1) @@ -201,8 +199,6 @@ func TestStartupAndShutdown(t *testing.T) { } func TestSendingMessagesDeduped(t *testing.T) { - test.Flaky(t) - ctx := context.Background() messagesSent := make(chan []bsmsg.Entry) resetChan := make(chan struct{}, 1) @@ -316,8 +312,6 @@ func TestSendingMessagesPriority(t *testing.T) { } func TestCancelOverridesPendingWants(t *testing.T) { - test.Flaky(t) - ctx := context.Background() messagesSent := make(chan []bsmsg.Entry) resetChan := make(chan struct{}, 1) @@ -368,8 +362,6 @@ func TestCancelOverridesPendingWants(t *testing.T) { } func TestWantOverridesPendingCancels(t *testing.T) { - test.Flaky(t) - ctx := context.Background() messagesSent := make(chan []bsmsg.Entry) resetChan := make(chan struct{}, 1) @@ -416,8 +408,6 @@ func TestWantOverridesPendingCancels(t *testing.T) { } func TestWantlistRebroadcast(t *testing.T) { - test.Flaky(t) - ctx := context.Background() messagesSent := make(chan []bsmsg.Entry) resetChan := make(chan struct{}, 1) @@ -526,8 +516,6 @@ func TestWantlistRebroadcast(t *testing.T) { } func TestSendingLargeMessages(t *testing.T) { - test.Flaky(t) - ctx := context.Background() messagesSent := make(chan []bsmsg.Entry) resetChan := make(chan struct{}, 1) @@ -557,8 +545,6 @@ func TestSendingLargeMessages(t *testing.T) { } func TestSendToPeerThatDoesntSupportHave(t *testing.T) { - test.Flaky(t) - ctx := context.Background() messagesSent := make(chan []bsmsg.Entry) resetChan := make(chan struct{}, 1) @@ -613,8 +599,6 @@ func TestSendToPeerThatDoesntSupportHave(t *testing.T) { } func TestSendToPeerThatDoesntSupportHaveMonitorsTimeouts(t *testing.T) { - test.Flaky(t) - ctx := context.Background() messagesSent := make(chan []bsmsg.Entry) resetChan := make(chan struct{}, 1) @@ -646,8 +630,6 @@ func TestSendToPeerThatDoesntSupportHaveMonitorsTimeouts(t *testing.T) { } func TestResponseReceived(t *testing.T) { - test.Flaky(t) - ctx := context.Background() messagesSent := make(chan []bsmsg.Entry) resetChan := make(chan struct{}, 1) @@ -697,8 +679,6 @@ func TestResponseReceived(t *testing.T) { } func TestResponseReceivedAppliesForFirstResponseOnly(t *testing.T) { - test.Flaky(t) - ctx := context.Background() messagesSent := make(chan []bsmsg.Entry) resetChan := make(chan struct{}, 1) @@ -743,8 +723,6 @@ func TestResponseReceivedAppliesForFirstResponseOnly(t *testing.T) { } func TestResponseReceivedDiscardsOutliers(t *testing.T) { - test.Flaky(t) - ctx := context.Background() messagesSent := make(chan []bsmsg.Entry) resetChan := make(chan struct{}, 1) diff --git a/bitswap/client/internal/notifications/notifications_test.go b/bitswap/client/internal/notifications/notifications_test.go index b4b8ef55d..68b4da1ec 100644 --- a/bitswap/client/internal/notifications/notifications_test.go +++ b/bitswap/client/internal/notifications/notifications_test.go @@ -6,7 +6,6 @@ import ( "testing" "time" - "github.com/ipfs/boxo/internal/test" blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" blocksutil "github.com/ipfs/go-ipfs-blocksutil" @@ -14,7 +13,6 @@ import ( ) func TestDuplicates(t *testing.T) { - test.Flaky(t) var zero peer.ID // this test doesn't check the peer id b1 := blocks.NewBlock([]byte("1")) @@ -42,7 +40,6 @@ func TestDuplicates(t *testing.T) { } func TestPublishSubscribe(t *testing.T) { - test.Flaky(t) var zero peer.ID // this test doesn't check the peer id blockSent := blocks.NewBlock([]byte("Greetings from The Interval")) @@ -61,7 +58,6 @@ func TestPublishSubscribe(t *testing.T) { } func TestSubscribeMany(t *testing.T) { - test.Flaky(t) var zero peer.ID // this test doesn't check the peer id e1 := blocks.NewBlock([]byte("1")) @@ -89,7 +85,6 @@ func TestSubscribeMany(t *testing.T) { // TestDuplicateSubscribe tests a scenario where a given block // would be requested twice at the same time. func TestDuplicateSubscribe(t *testing.T) { - test.Flaky(t) var zero peer.ID // this test doesn't check the peer id e1 := blocks.NewBlock([]byte("1")) @@ -114,8 +109,6 @@ func TestDuplicateSubscribe(t *testing.T) { } func TestShutdownBeforeUnsubscribe(t *testing.T) { - test.Flaky(t) - e1 := blocks.NewBlock([]byte("1")) n := New() @@ -135,8 +128,6 @@ func TestShutdownBeforeUnsubscribe(t *testing.T) { } func TestSubscribeIsANoopWhenCalledWithNoKeys(t *testing.T) { - test.Flaky(t) - n := New() defer n.Shutdown() ch := n.Subscribe(context.Background()) // no keys provided @@ -146,8 +137,6 @@ func TestSubscribeIsANoopWhenCalledWithNoKeys(t *testing.T) { } func TestCarryOnWhenDeadlineExpires(t *testing.T) { - test.Flaky(t) - impossibleDeadline := time.Nanosecond fastExpiringCtx, cancel := context.WithTimeout(context.Background(), impossibleDeadline) defer cancel() @@ -161,7 +150,6 @@ func TestCarryOnWhenDeadlineExpires(t *testing.T) { } func TestDoesNotDeadLockIfContextCancelledBeforePublish(t *testing.T) { - test.Flaky(t) var zero peer.ID // this test doesn't check the peer id g := blocksutil.NewBlockGenerator() diff --git a/bitswap/client/internal/peermanager/peermanager_test.go b/bitswap/client/internal/peermanager/peermanager_test.go index a2569201f..d3c712704 100644 --- a/bitswap/client/internal/peermanager/peermanager_test.go +++ b/bitswap/client/internal/peermanager/peermanager_test.go @@ -7,7 +7,6 @@ import ( "time" "github.com/ipfs/boxo/bitswap/internal/testutil" - "github.com/ipfs/boxo/internal/test" cid "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p/core/peer" ) @@ -80,8 +79,6 @@ func makePeerQueueFactory(msgs chan msg) PeerQueueFactory { } func TestAddingAndRemovingPeers(t *testing.T) { - test.Flaky(t) - ctx := context.Background() msgs := make(chan msg, 16) peerQueueFactory := makePeerQueueFactory(msgs) @@ -125,8 +122,6 @@ func TestAddingAndRemovingPeers(t *testing.T) { } func TestBroadcastOnConnect(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() msgs := make(chan msg, 16) @@ -148,8 +143,6 @@ func TestBroadcastOnConnect(t *testing.T) { } func TestBroadcastWantHaves(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() msgs := make(chan msg, 16) @@ -191,8 +184,6 @@ func TestBroadcastWantHaves(t *testing.T) { } func TestSendWants(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() msgs := make(chan msg, 16) @@ -227,8 +218,6 @@ func TestSendWants(t *testing.T) { } func TestSendCancels(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() msgs := make(chan msg, 16) @@ -289,8 +278,6 @@ func newSess(id uint64) *sess { } func TestSessionRegistration(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() msgs := make(chan msg, 16) diff --git a/bitswap/client/internal/peermanager/peerwantmanager_test.go b/bitswap/client/internal/peermanager/peerwantmanager_test.go index b4c3d5029..505fbea1a 100644 --- a/bitswap/client/internal/peermanager/peerwantmanager_test.go +++ b/bitswap/client/internal/peermanager/peerwantmanager_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/ipfs/boxo/bitswap/internal/testutil" - "github.com/ipfs/boxo/internal/test" cid "github.com/ipfs/go-cid" peer "github.com/libp2p/go-libp2p/core/peer" ) @@ -61,8 +60,6 @@ func clearSent(pqs map[peer.ID]PeerQueue) { } func TestEmpty(t *testing.T) { - test.Flaky(t) - pwm := newPeerWantManager(&gauge{}, &gauge{}) if len(pwm.getWantBlocks()) > 0 { @@ -74,8 +71,6 @@ func TestEmpty(t *testing.T) { } func TestPWMBroadcastWantHaves(t *testing.T) { - test.Flaky(t) - pwm := newPeerWantManager(&gauge{}, &gauge{}) peers := testutil.GeneratePeers(3) @@ -188,8 +183,6 @@ func TestPWMBroadcastWantHaves(t *testing.T) { } func TestPWMSendWants(t *testing.T) { - test.Flaky(t) - pwm := newPeerWantManager(&gauge{}, &gauge{}) peers := testutil.GeneratePeers(2) @@ -270,8 +263,6 @@ func TestPWMSendWants(t *testing.T) { } func TestPWMSendCancels(t *testing.T) { - test.Flaky(t) - pwm := newPeerWantManager(&gauge{}, &gauge{}) peers := testutil.GeneratePeers(2) @@ -350,8 +341,6 @@ func TestPWMSendCancels(t *testing.T) { } func TestStats(t *testing.T) { - test.Flaky(t) - g := &gauge{} wbg := &gauge{} pwm := newPeerWantManager(g, wbg) @@ -453,8 +442,6 @@ func TestStats(t *testing.T) { } func TestStatsOverlappingWantBlockWantHave(t *testing.T) { - test.Flaky(t) - g := &gauge{} wbg := &gauge{} pwm := newPeerWantManager(g, wbg) @@ -494,8 +481,6 @@ func TestStatsOverlappingWantBlockWantHave(t *testing.T) { } func TestStatsRemovePeerOverlappingWantBlockWantHave(t *testing.T) { - test.Flaky(t) - g := &gauge{} wbg := &gauge{} pwm := newPeerWantManager(g, wbg) diff --git a/bitswap/client/internal/providerquerymanager/providerquerymanager_test.go b/bitswap/client/internal/providerquerymanager/providerquerymanager_test.go index 04b309286..afdd19595 100644 --- a/bitswap/client/internal/providerquerymanager/providerquerymanager_test.go +++ b/bitswap/client/internal/providerquerymanager/providerquerymanager_test.go @@ -9,7 +9,6 @@ import ( "time" "github.com/ipfs/boxo/bitswap/internal/testutil" - "github.com/ipfs/boxo/internal/test" cid "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p/core/peer" ) @@ -59,8 +58,6 @@ func (fpn *fakeProviderNetwork) FindProvidersAsync(ctx context.Context, k cid.Ci } func TestNormalSimultaneousFetch(t *testing.T) { - test.Flaky(t) - peers := testutil.GeneratePeers(10) fpn := &fakeProviderNetwork{ peersFound: peers, @@ -98,8 +95,6 @@ func TestNormalSimultaneousFetch(t *testing.T) { } func TestDedupingProviderRequests(t *testing.T) { - test.Flaky(t) - peers := testutil.GeneratePeers(10) fpn := &fakeProviderNetwork{ peersFound: peers, @@ -140,8 +135,6 @@ func TestDedupingProviderRequests(t *testing.T) { } func TestCancelOneRequestDoesNotTerminateAnother(t *testing.T) { - test.Flaky(t) - peers := testutil.GeneratePeers(10) fpn := &fakeProviderNetwork{ peersFound: peers, @@ -186,8 +179,6 @@ func TestCancelOneRequestDoesNotTerminateAnother(t *testing.T) { } func TestCancelManagerExitsGracefully(t *testing.T) { - test.Flaky(t) - peers := testutil.GeneratePeers(10) fpn := &fakeProviderNetwork{ peersFound: peers, @@ -223,8 +214,6 @@ func TestCancelManagerExitsGracefully(t *testing.T) { } func TestPeersWithConnectionErrorsNotAddedToPeerList(t *testing.T) { - test.Flaky(t) - peers := testutil.GeneratePeers(10) fpn := &fakeProviderNetwork{ peersFound: peers, @@ -258,8 +247,6 @@ func TestPeersWithConnectionErrorsNotAddedToPeerList(t *testing.T) { } func TestRateLimitingRequests(t *testing.T) { - test.Flaky(t) - peers := testutil.GeneratePeers(10) fpn := &fakeProviderNetwork{ peersFound: peers, @@ -299,8 +286,6 @@ func TestRateLimitingRequests(t *testing.T) { } func TestFindProviderTimeout(t *testing.T) { - test.Flaky(t) - peers := testutil.GeneratePeers(10) fpn := &fakeProviderNetwork{ peersFound: peers, @@ -325,8 +310,6 @@ func TestFindProviderTimeout(t *testing.T) { } func TestFindProviderPreCanceled(t *testing.T) { - test.Flaky(t) - peers := testutil.GeneratePeers(10) fpn := &fakeProviderNetwork{ peersFound: peers, @@ -352,8 +335,6 @@ func TestFindProviderPreCanceled(t *testing.T) { } func TestCancelFindProvidersAfterCompletion(t *testing.T) { - test.Flaky(t) - peers := testutil.GeneratePeers(2) fpn := &fakeProviderNetwork{ peersFound: peers, diff --git a/bitswap/client/internal/session/session_test.go b/bitswap/client/internal/session/session_test.go index cf6de1e5a..819a535c1 100644 --- a/bitswap/client/internal/session/session_test.go +++ b/bitswap/client/internal/session/session_test.go @@ -149,8 +149,6 @@ func (pm *fakePeerManager) BroadcastWantHaves(ctx context.Context, cids []cid.Ci func (pm *fakePeerManager) SendCancels(ctx context.Context, cancels []cid.Cid) {} func TestSessionGetBlocks(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) fpm := newFakePeerManager() fspm := newFakeSessionPeerManager() @@ -245,8 +243,6 @@ func TestSessionGetBlocks(t *testing.T) { } func TestSessionFindMorePeers(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithTimeout(context.Background(), 900*time.Millisecond) defer cancel() fpm := newFakePeerManager() @@ -321,8 +317,6 @@ func TestSessionFindMorePeers(t *testing.T) { } func TestSessionOnPeersExhausted(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) defer cancel() fpm := newFakePeerManager() @@ -485,8 +479,6 @@ func TestSessionFailingToGetFirstBlock(t *testing.T) { } func TestSessionCtxCancelClosesGetBlocksChannel(t *testing.T) { - test.Flaky(t) - fpm := newFakePeerManager() fspm := newFakeSessionPeerManager() fpf := newFakeProviderFinder() @@ -537,8 +529,6 @@ func TestSessionCtxCancelClosesGetBlocksChannel(t *testing.T) { } func TestSessionOnShutdownCalled(t *testing.T) { - test.Flaky(t) - fpm := newFakePeerManager() fspm := newFakeSessionPeerManager() fpf := newFakeProviderFinder() @@ -566,8 +556,6 @@ func TestSessionOnShutdownCalled(t *testing.T) { } func TestSessionReceiveMessageAfterCtxCancel(t *testing.T) { - test.Flaky(t) - ctx, cancelCtx := context.WithTimeout(context.Background(), 20*time.Millisecond) fpm := newFakePeerManager() fspm := newFakeSessionPeerManager() diff --git a/bitswap/client/internal/session/sessionwants_test.go b/bitswap/client/internal/session/sessionwants_test.go index bdb73ebd1..f940ac14f 100644 --- a/bitswap/client/internal/session/sessionwants_test.go +++ b/bitswap/client/internal/session/sessionwants_test.go @@ -4,13 +4,10 @@ import ( "testing" "github.com/ipfs/boxo/bitswap/internal/testutil" - "github.com/ipfs/boxo/internal/test" cid "github.com/ipfs/go-cid" ) func TestEmptySessionWants(t *testing.T) { - test.Flaky(t) - sw := newSessionWants(broadcastLiveWantsLimit) // Expect these functions to return nothing on a new sessionWants @@ -32,8 +29,6 @@ func TestEmptySessionWants(t *testing.T) { } func TestSessionWants(t *testing.T) { - test.Flaky(t) - sw := newSessionWants(5) cids := testutil.GenerateCids(10) others := testutil.GenerateCids(1) @@ -115,8 +110,6 @@ func TestSessionWants(t *testing.T) { } func TestPrepareBroadcast(t *testing.T) { - test.Flaky(t) - sw := newSessionWants(3) cids := testutil.GenerateCids(10) @@ -177,8 +170,6 @@ func TestPrepareBroadcast(t *testing.T) { // Test that even after GC broadcast returns correct wants func TestPrepareBroadcastAfterGC(t *testing.T) { - test.Flaky(t) - sw := newSessionWants(5) cids := testutil.GenerateCids(liveWantsOrderGCLimit * 2) diff --git a/bitswap/client/internal/session/sessionwantsender_test.go b/bitswap/client/internal/session/sessionwantsender_test.go index 476b13991..86a930f61 100644 --- a/bitswap/client/internal/session/sessionwantsender_test.go +++ b/bitswap/client/internal/session/sessionwantsender_test.go @@ -10,7 +10,6 @@ import ( bspm "github.com/ipfs/boxo/bitswap/client/internal/peermanager" bsspm "github.com/ipfs/boxo/bitswap/client/internal/sessionpeermanager" "github.com/ipfs/boxo/bitswap/internal/testutil" - "github.com/ipfs/boxo/internal/test" cid "github.com/ipfs/go-cid" peer "github.com/libp2p/go-libp2p/core/peer" ) @@ -142,8 +141,6 @@ func (ep *exhaustedPeers) exhausted() []cid.Cid { } func TestSendWants(t *testing.T) { - test.Flaky(t) - cids := testutil.GenerateCids(4) peers := testutil.GeneratePeers(1) peerA := peers[0] @@ -183,8 +180,6 @@ func TestSendWants(t *testing.T) { } func TestSendsWantBlockToOnePeerOnly(t *testing.T) { - test.Flaky(t) - cids := testutil.GenerateCids(4) peers := testutil.GeneratePeers(2) peerA := peers[0] @@ -245,8 +240,6 @@ func TestSendsWantBlockToOnePeerOnly(t *testing.T) { } func TestReceiveBlock(t *testing.T) { - test.Flaky(t) - cids := testutil.GenerateCids(2) peers := testutil.GeneratePeers(2) peerA := peers[0] @@ -309,8 +302,6 @@ func TestReceiveBlock(t *testing.T) { } func TestCancelWants(t *testing.T) { - test.Flaky(t) - cids := testutil.GenerateCids(4) sid := uint64(1) pm := newMockPeerManager() @@ -345,8 +336,6 @@ func TestCancelWants(t *testing.T) { } func TestRegisterSessionWithPeerManager(t *testing.T) { - test.Flaky(t) - cids := testutil.GenerateCids(2) peers := testutil.GeneratePeers(2) peerA := peers[0] @@ -387,8 +376,6 @@ func TestRegisterSessionWithPeerManager(t *testing.T) { } func TestProtectConnFirstPeerToSendWantedBlock(t *testing.T) { - test.Flaky(t) - cids := testutil.GenerateCids(2) peers := testutil.GeneratePeers(3) peerA := peers[0] @@ -445,8 +432,6 @@ func TestProtectConnFirstPeerToSendWantedBlock(t *testing.T) { } func TestPeerUnavailable(t *testing.T) { - test.Flaky(t) - cids := testutil.GenerateCids(2) peers := testutil.GeneratePeers(2) peerA := peers[0] @@ -514,8 +499,6 @@ func TestPeerUnavailable(t *testing.T) { } func TestPeersExhausted(t *testing.T) { - test.Flaky(t) - cids := testutil.GenerateCids(3) peers := testutil.GeneratePeers(2) peerA := peers[0] @@ -593,8 +576,6 @@ func TestPeersExhausted(t *testing.T) { // - the remaining peer becomes unavailable // onPeersExhausted should be sent for that CID func TestPeersExhaustedLastWaitingPeerUnavailable(t *testing.T) { - test.Flaky(t) - cids := testutil.GenerateCids(2) peers := testutil.GeneratePeers(2) peerA := peers[0] @@ -644,8 +625,6 @@ func TestPeersExhaustedLastWaitingPeerUnavailable(t *testing.T) { // Tests that when all the peers are removed from the session // onPeersExhausted should be called with all outstanding CIDs func TestPeersExhaustedAllPeersUnavailable(t *testing.T) { - test.Flaky(t) - cids := testutil.GenerateCids(3) peers := testutil.GeneratePeers(2) peerA := peers[0] @@ -688,8 +667,6 @@ func TestPeersExhaustedAllPeersUnavailable(t *testing.T) { } func TestConsecutiveDontHaveLimit(t *testing.T) { - test.Flaky(t) - cids := testutil.GenerateCids(peerDontHaveLimit + 10) p := testutil.GeneratePeers(1)[0] sid := uint64(1) @@ -748,8 +725,6 @@ func TestConsecutiveDontHaveLimit(t *testing.T) { } func TestConsecutiveDontHaveLimitInterrupted(t *testing.T) { - test.Flaky(t) - cids := testutil.GenerateCids(peerDontHaveLimit + 10) p := testutil.GeneratePeers(1)[0] sid := uint64(1) @@ -807,8 +782,6 @@ func TestConsecutiveDontHaveLimitInterrupted(t *testing.T) { } func TestConsecutiveDontHaveReinstateAfterRemoval(t *testing.T) { - test.Flaky(t) - cids := testutil.GenerateCids(peerDontHaveLimit + 10) p := testutil.GeneratePeers(1)[0] sid := uint64(1) @@ -895,8 +868,6 @@ func TestConsecutiveDontHaveReinstateAfterRemoval(t *testing.T) { } func TestConsecutiveDontHaveDontRemoveIfHasWantedBlock(t *testing.T) { - test.Flaky(t) - cids := testutil.GenerateCids(peerDontHaveLimit + 10) p := testutil.GeneratePeers(1)[0] sid := uint64(1) diff --git a/bitswap/client/internal/sessioninterestmanager/sessioninterestmanager_test.go b/bitswap/client/internal/sessioninterestmanager/sessioninterestmanager_test.go index 85857b9ba..f2b4d8aa0 100644 --- a/bitswap/client/internal/sessioninterestmanager/sessioninterestmanager_test.go +++ b/bitswap/client/internal/sessioninterestmanager/sessioninterestmanager_test.go @@ -4,13 +4,10 @@ import ( "testing" "github.com/ipfs/boxo/bitswap/internal/testutil" - "github.com/ipfs/boxo/internal/test" cid "github.com/ipfs/go-cid" ) func TestEmpty(t *testing.T) { - test.Flaky(t) - sim := New() ses := uint64(1) @@ -25,8 +22,6 @@ func TestEmpty(t *testing.T) { } func TestBasic(t *testing.T) { - test.Flaky(t) - sim := New() ses1 := uint64(1) @@ -62,8 +57,6 @@ func TestBasic(t *testing.T) { } func TestInterestedSessions(t *testing.T) { - test.Flaky(t) - sim := New() ses := uint64(1) @@ -91,8 +84,6 @@ func TestInterestedSessions(t *testing.T) { } func TestRemoveSession(t *testing.T) { - test.Flaky(t) - sim := New() ses1 := uint64(1) @@ -121,8 +112,6 @@ func TestRemoveSession(t *testing.T) { } func TestRemoveSessionInterested(t *testing.T) { - test.Flaky(t) - sim := New() ses1 := uint64(1) @@ -159,8 +148,6 @@ func TestRemoveSessionInterested(t *testing.T) { } func TestSplitWantedUnwanted(t *testing.T) { - test.Flaky(t) - blks := testutil.GenerateBlocksOfSize(3, 1024) sim := New() ses1 := uint64(1) diff --git a/bitswap/client/internal/sessionmanager/sessionmanager_test.go b/bitswap/client/internal/sessionmanager/sessionmanager_test.go index 5ecabfdb3..86f7f8df5 100644 --- a/bitswap/client/internal/sessionmanager/sessionmanager_test.go +++ b/bitswap/client/internal/sessionmanager/sessionmanager_test.go @@ -13,7 +13,6 @@ import ( bssession "github.com/ipfs/boxo/bitswap/client/internal/session" bssim "github.com/ipfs/boxo/bitswap/client/internal/sessioninterestmanager" "github.com/ipfs/boxo/bitswap/internal/testutil" - "github.com/ipfs/boxo/internal/test" blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" delay "github.com/ipfs/go-ipfs-delay" @@ -113,8 +112,6 @@ func peerManagerFactory(ctx context.Context, id uint64) bssession.SessionPeerMan } func TestReceiveFrom(t *testing.T) { - test.Flaky(t) - ctx := context.Background() ctx, cancel := context.WithCancel(ctx) defer cancel() @@ -162,8 +159,6 @@ func TestReceiveFrom(t *testing.T) { } func TestReceiveBlocksWhenManagerShutdown(t *testing.T) { - test.Flaky(t) - ctx := context.Background() ctx, cancel := context.WithCancel(ctx) defer cancel() @@ -199,8 +194,6 @@ func TestReceiveBlocksWhenManagerShutdown(t *testing.T) { } func TestReceiveBlocksWhenSessionContextCancelled(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithCancel(context.Background()) defer cancel() notif := notifications.New() @@ -236,8 +229,6 @@ func TestReceiveBlocksWhenSessionContextCancelled(t *testing.T) { } func TestShutdown(t *testing.T) { - test.Flaky(t) - ctx := context.Background() ctx, cancel := context.WithCancel(ctx) defer cancel() diff --git a/bitswap/client/internal/sessionpeermanager/sessionpeermanager_test.go b/bitswap/client/internal/sessionpeermanager/sessionpeermanager_test.go index fc1d7274d..0d9275579 100644 --- a/bitswap/client/internal/sessionpeermanager/sessionpeermanager_test.go +++ b/bitswap/client/internal/sessionpeermanager/sessionpeermanager_test.go @@ -5,7 +5,6 @@ import ( "testing" "github.com/ipfs/boxo/bitswap/internal/testutil" - "github.com/ipfs/boxo/internal/test" peer "github.com/libp2p/go-libp2p/core/peer" ) @@ -79,8 +78,6 @@ func (fpt *fakePeerTagger) isProtected(p peer.ID) bool { } func TestAddPeers(t *testing.T) { - test.Flaky(t) - peers := testutil.GeneratePeers(2) spm := New(1, &fakePeerTagger{}) @@ -101,8 +98,6 @@ func TestAddPeers(t *testing.T) { } func TestRemovePeers(t *testing.T) { - test.Flaky(t) - peers := testutil.GeneratePeers(2) spm := New(1, &fakePeerTagger{}) @@ -129,8 +124,6 @@ func TestRemovePeers(t *testing.T) { } func TestHasPeers(t *testing.T) { - test.Flaky(t) - peers := testutil.GeneratePeers(2) spm := New(1, &fakePeerTagger{}) @@ -160,8 +153,6 @@ func TestHasPeers(t *testing.T) { } func TestHasPeer(t *testing.T) { - test.Flaky(t) - peers := testutil.GeneratePeers(2) spm := New(1, &fakePeerTagger{}) @@ -190,8 +181,6 @@ func TestHasPeer(t *testing.T) { } func TestPeers(t *testing.T) { - test.Flaky(t) - peers := testutil.GeneratePeers(2) spm := New(1, &fakePeerTagger{}) @@ -216,8 +205,6 @@ func TestPeers(t *testing.T) { } func TestPeersDiscovered(t *testing.T) { - test.Flaky(t) - peers := testutil.GeneratePeers(2) spm := New(1, &fakePeerTagger{}) @@ -237,8 +224,6 @@ func TestPeersDiscovered(t *testing.T) { } func TestPeerTagging(t *testing.T) { - test.Flaky(t) - peers := testutil.GeneratePeers(2) fpt := &fakePeerTagger{} spm := New(1, fpt) @@ -265,8 +250,6 @@ func TestPeerTagging(t *testing.T) { } func TestProtectConnection(t *testing.T) { - test.Flaky(t) - peers := testutil.GeneratePeers(1) peerA := peers[0] fpt := newFakePeerTagger() @@ -293,8 +276,6 @@ func TestProtectConnection(t *testing.T) { } func TestShutdown(t *testing.T) { - test.Flaky(t) - peers := testutil.GeneratePeers(2) fpt := newFakePeerTagger() spm := New(1, fpt) diff --git a/bitswap/client/wantlist/wantlist_test.go b/bitswap/client/wantlist/wantlist_test.go index 035786ea3..07d4ce415 100644 --- a/bitswap/client/wantlist/wantlist_test.go +++ b/bitswap/client/wantlist/wantlist_test.go @@ -4,7 +4,6 @@ import ( "testing" pb "github.com/ipfs/boxo/bitswap/message/pb" - "github.com/ipfs/boxo/internal/test" cid "github.com/ipfs/go-cid" "github.com/stretchr/testify/require" ) @@ -41,8 +40,6 @@ func assertHasCid(t *testing.T, w wli, c cid.Cid) { } func TestBasicWantlist(t *testing.T) { - test.Flaky(t) - wl := New() if !wl.Add(testcids[0], 5, pb.Message_Wantlist_Block) { @@ -80,8 +77,6 @@ func TestBasicWantlist(t *testing.T) { } func TestAddHaveThenBlock(t *testing.T) { - test.Flaky(t) - wl := New() wl.Add(testcids[0], 5, pb.Message_Wantlist_Have) @@ -97,8 +92,6 @@ func TestAddHaveThenBlock(t *testing.T) { } func TestAddBlockThenHave(t *testing.T) { - test.Flaky(t) - wl := New() wl.Add(testcids[0], 5, pb.Message_Wantlist_Block) @@ -114,8 +107,6 @@ func TestAddBlockThenHave(t *testing.T) { } func TestAddHaveThenRemoveBlock(t *testing.T) { - test.Flaky(t) - wl := New() wl.Add(testcids[0], 5, pb.Message_Wantlist_Have) @@ -128,8 +119,6 @@ func TestAddHaveThenRemoveBlock(t *testing.T) { } func TestAddBlockThenRemoveHave(t *testing.T) { - test.Flaky(t) - wl := New() wl.Add(testcids[0], 5, pb.Message_Wantlist_Block) @@ -145,8 +134,6 @@ func TestAddBlockThenRemoveHave(t *testing.T) { } func TestAddHaveThenRemoveAny(t *testing.T) { - test.Flaky(t) - wl := New() wl.Add(testcids[0], 5, pb.Message_Wantlist_Have) @@ -159,8 +146,6 @@ func TestAddHaveThenRemoveAny(t *testing.T) { } func TestAddBlockThenRemoveAny(t *testing.T) { - test.Flaky(t) - wl := New() wl.Add(testcids[0], 5, pb.Message_Wantlist_Block) @@ -173,8 +158,6 @@ func TestAddBlockThenRemoveAny(t *testing.T) { } func TestAbsort(t *testing.T) { - test.Flaky(t) - wl := New() wl.Add(testcids[0], 5, pb.Message_Wantlist_Block) wl.Add(testcids[1], 4, pb.Message_Wantlist_Have) @@ -221,8 +204,6 @@ func TestAbsort(t *testing.T) { } func TestSortEntries(t *testing.T) { - test.Flaky(t) - wl := New() wl.Add(testcids[0], 3, pb.Message_Wantlist_Block) @@ -239,8 +220,6 @@ func TestSortEntries(t *testing.T) { // Test adding and removing interleaved with checking entries to make sure we clear the cache. func TestCache(t *testing.T) { - test.Flaky(t) - wl := New() wl.Add(testcids[0], 3, pb.Message_Wantlist_Block) diff --git a/bitswap/network/connecteventmanager_test.go b/bitswap/network/connecteventmanager_test.go index e3904ee55..bb3c52266 100644 --- a/bitswap/network/connecteventmanager_test.go +++ b/bitswap/network/connecteventmanager_test.go @@ -6,7 +6,6 @@ import ( "time" "github.com/ipfs/boxo/bitswap/internal/testutil" - "github.com/ipfs/boxo/internal/test" "github.com/libp2p/go-libp2p/core/peer" "github.com/stretchr/testify/require" ) @@ -46,8 +45,6 @@ func wait(t *testing.T, c *connectEventManager) { } func TestConnectEventManagerConnectDisconnect(t *testing.T) { - test.Flaky(t) - connListener := newMockConnListener() peers := testutil.GeneratePeers(2) cem := newConnectEventManager(connListener) @@ -87,8 +84,6 @@ func TestConnectEventManagerConnectDisconnect(t *testing.T) { } func TestConnectEventManagerMarkUnresponsive(t *testing.T) { - test.Flaky(t) - connListener := newMockConnListener() p := testutil.GeneratePeers(1)[0] cem := newConnectEventManager(connListener) @@ -138,8 +133,6 @@ func TestConnectEventManagerMarkUnresponsive(t *testing.T) { } func TestConnectEventManagerDisconnectAfterMarkUnresponsive(t *testing.T) { - test.Flaky(t) - connListener := newMockConnListener() p := testutil.GeneratePeers(1)[0] cem := newConnectEventManager(connListener) diff --git a/bitswap/network/ipfs_impl_test.go b/bitswap/network/ipfs_impl_test.go index 175957799..196fc7d55 100644 --- a/bitswap/network/ipfs_impl_test.go +++ b/bitswap/network/ipfs_impl_test.go @@ -12,7 +12,6 @@ import ( bsnet "github.com/ipfs/boxo/bitswap/network" "github.com/ipfs/boxo/bitswap/network/internal" tn "github.com/ipfs/boxo/bitswap/testnet" - "github.com/ipfs/boxo/internal/test" mockrouting "github.com/ipfs/boxo/routing/mock" ds "github.com/ipfs/go-datastore" blocksutil "github.com/ipfs/go-ipfs-blocksutil" @@ -164,8 +163,6 @@ func (eh *ErrHost) setTimeoutState(timingOut bool) { } func TestMessageSendAndReceive(t *testing.T) { - test.Flaky(t) - // create network ctx := context.Background() ctx, cancel := context.WithTimeout(ctx, 10*time.Second) @@ -334,8 +331,6 @@ func prepareNetwork(t *testing.T, ctx context.Context, p1 tnet.Identity, r1 *rec } func TestMessageResendAfterError(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() @@ -382,8 +377,6 @@ func TestMessageResendAfterError(t *testing.T) { } func TestMessageSendTimeout(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() @@ -425,8 +418,6 @@ func TestMessageSendTimeout(t *testing.T) { } func TestMessageSendNotSupportedResponse(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() @@ -459,8 +450,6 @@ func TestMessageSendNotSupportedResponse(t *testing.T) { } func TestSupportsHave(t *testing.T) { - test.Flaky(t) - ctx := context.Background() mn := mocknet.New() defer mn.Close() @@ -675,8 +664,6 @@ func testNetworkCounters(t *testing.T, n1 int, n2 int) { } func TestNetworkCounters(t *testing.T) { - test.Flaky(t) - for n := 0; n < 11; n++ { testNetworkCounters(t, 10-n, n) } diff --git a/bitswap/network/ipfs_impl_timeout_test.go b/bitswap/network/ipfs_impl_timeout_test.go index 178c2fb69..fdbe8e950 100644 --- a/bitswap/network/ipfs_impl_timeout_test.go +++ b/bitswap/network/ipfs_impl_timeout_test.go @@ -4,13 +4,10 @@ import ( "testing" "time" - "github.com/ipfs/boxo/internal/test" "github.com/stretchr/testify/require" ) func TestSendTimeout(t *testing.T) { - test.Flaky(t) - require.Equal(t, minSendTimeout, sendTimeout(0)) require.Equal(t, maxSendTimeout, sendTimeout(1<<30)) diff --git a/bitswap/server/internal/decision/blockstoremanager_test.go b/bitswap/server/internal/decision/blockstoremanager_test.go index 3d4a8ea37..1192873f3 100644 --- a/bitswap/server/internal/decision/blockstoremanager_test.go +++ b/bitswap/server/internal/decision/blockstoremanager_test.go @@ -9,7 +9,6 @@ import ( "github.com/ipfs/boxo/bitswap/internal/testutil" blockstore "github.com/ipfs/boxo/blockstore" - "github.com/ipfs/boxo/internal/test" blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" ds "github.com/ipfs/go-datastore" @@ -34,8 +33,6 @@ func newBlockstoreManagerForTesting( } func TestBlockstoreManagerNotFoundKey(t *testing.T) { - test.Flaky(t) - ctx := context.Background() bsdelay := delay.Fixed(3 * time.Millisecond) dstore := ds_sync.MutexWrap(delayed.New(ds.NewMapDatastore(), bsdelay)) @@ -74,8 +71,6 @@ func TestBlockstoreManagerNotFoundKey(t *testing.T) { } func TestBlockstoreManager(t *testing.T) { - test.Flaky(t) - ctx := context.Background() bsdelay := delay.Fixed(3 * time.Millisecond) dstore := ds_sync.MutexWrap(delayed.New(ds.NewMapDatastore(), bsdelay)) @@ -158,8 +153,6 @@ func TestBlockstoreManager(t *testing.T) { } func TestBlockstoreManagerConcurrency(t *testing.T) { - test.Flaky(t) - ctx := context.Background() bsdelay := delay.Fixed(3 * time.Millisecond) dstore := ds_sync.MutexWrap(delayed.New(ds.NewMapDatastore(), bsdelay)) @@ -201,8 +194,6 @@ func TestBlockstoreManagerConcurrency(t *testing.T) { } func TestBlockstoreManagerClose(t *testing.T) { - test.Flaky(t) - ctx := context.Background() delayTime := 20 * time.Millisecond bsdelay := delay.Fixed(delayTime) @@ -224,8 +215,6 @@ func TestBlockstoreManagerClose(t *testing.T) { bsm.stop() - time.Sleep(5 * time.Millisecond) - before := time.Now() _, err = bsm.getBlockSizes(ctx, ks) if err == nil { @@ -238,8 +227,6 @@ func TestBlockstoreManagerClose(t *testing.T) { } func TestBlockstoreManagerCtxDone(t *testing.T) { - test.Flaky(t) - delayTime := 20 * time.Millisecond bsdelay := delay.Fixed(delayTime) diff --git a/bitswap/server/internal/decision/engine_test.go b/bitswap/server/internal/decision/engine_test.go index 922836042..efc4408ff 100644 --- a/bitswap/server/internal/decision/engine_test.go +++ b/bitswap/server/internal/decision/engine_test.go @@ -17,7 +17,6 @@ import ( message "github.com/ipfs/boxo/bitswap/message" pb "github.com/ipfs/boxo/bitswap/message/pb" blockstore "github.com/ipfs/boxo/blockstore" - "github.com/ipfs/boxo/internal/test" blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" ds "github.com/ipfs/go-datastore" @@ -112,8 +111,6 @@ func newTestEngineWithSampling(ctx context.Context, idStr string, peerSampleInte } func TestConsistentAccounting(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithCancel(context.Background()) defer cancel() sender := newTestEngine(ctx, "Ernie") @@ -149,8 +146,6 @@ func TestConsistentAccounting(t *testing.T) { } func TestPeerIsAddedToPeersWhenMessageSent(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithCancel(context.Background()) defer cancel() sanfrancisco := newTestEngine(ctx, "sf") @@ -205,8 +200,6 @@ func newEngineForTesting( } func TestOutboxClosedWhenEngineClosed(t *testing.T) { - test.Flaky(t) - t.SkipNow() // TODO implement *Engine.Close ctx := context.Background() e := newEngineForTesting(ctx, blockstore.NewBlockstore(dssync.MutexWrap(ds.NewMapDatastore())), &fakePeerTagger{}, "localhost", 0, WithScoreLedger(NewTestScoreLedger(shortTerm, nil, clock.New())), WithBlockstoreWorkerCount(4)) @@ -227,8 +220,6 @@ func TestOutboxClosedWhenEngineClosed(t *testing.T) { } func TestPartnerWantHaveWantBlockNonActive(t *testing.T) { - test.Flaky(t) - alphabet := "abcdefghijklmnopqrstuvwxyz" vowels := "aeiou" @@ -569,8 +560,6 @@ func TestPartnerWantHaveWantBlockNonActive(t *testing.T) { } func TestPartnerWantHaveWantBlockActive(t *testing.T) { - test.Flaky(t) - alphabet := "abcdefghijklmnopqrstuvwxyz" bs := blockstore.NewBlockstore(dssync.MutexWrap(ds.NewMapDatastore())) @@ -843,8 +832,6 @@ func formatPresencesDiff(presences []message.BlockPresence, expHaves []string, e } func TestPartnerWantsThenCancels(t *testing.T) { - test.Flaky(t) - numRounds := 10 if testing.Short() { numRounds = 1 @@ -907,8 +894,6 @@ func TestPartnerWantsThenCancels(t *testing.T) { } func TestSendReceivedBlocksToPeersThatWantThem(t *testing.T) { - test.Flaky(t) - bs := blockstore.NewBlockstore(dssync.MutexWrap(ds.NewMapDatastore())) partner := libp2ptest.RandPeerIDFatal(t) otherPeer := libp2ptest.RandPeerIDFatal(t) @@ -955,8 +940,6 @@ func TestSendReceivedBlocksToPeersThatWantThem(t *testing.T) { } func TestSendDontHave(t *testing.T) { - test.Flaky(t) - bs := blockstore.NewBlockstore(dssync.MutexWrap(ds.NewMapDatastore())) partner := libp2ptest.RandPeerIDFatal(t) otherPeer := libp2ptest.RandPeerIDFatal(t) @@ -1023,8 +1006,6 @@ func TestSendDontHave(t *testing.T) { } func TestWantlistForPeer(t *testing.T) { - test.Flaky(t) - bs := blockstore.NewBlockstore(dssync.MutexWrap(ds.NewMapDatastore())) partner := libp2ptest.RandPeerIDFatal(t) otherPeer := libp2ptest.RandPeerIDFatal(t) @@ -1062,8 +1043,6 @@ func TestWantlistForPeer(t *testing.T) { } func TestTaskComparator(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() @@ -1118,8 +1097,6 @@ func TestTaskComparator(t *testing.T) { } func TestPeerBlockFilter(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() @@ -1279,8 +1256,6 @@ func TestPeerBlockFilter(t *testing.T) { } func TestPeerBlockFilterMutability(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() @@ -1450,8 +1425,6 @@ func TestPeerBlockFilterMutability(t *testing.T) { } func TestTaggingPeers(t *testing.T) { - test.Flaky(t) - ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() sanfrancisco := newTestEngine(ctx, "sf") @@ -1480,8 +1453,6 @@ func TestTaggingPeers(t *testing.T) { } func TestTaggingUseful(t *testing.T) { - test.Flaky(t) - peerSampleIntervalHalf := 10 * time.Millisecond ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) diff --git a/bitswap/server/internal/decision/taskmerger_test.go b/bitswap/server/internal/decision/taskmerger_test.go index e0ce46ed6..ae3b0384d 100644 --- a/bitswap/server/internal/decision/taskmerger_test.go +++ b/bitswap/server/internal/decision/taskmerger_test.go @@ -4,14 +4,11 @@ import ( "testing" "github.com/ipfs/boxo/bitswap/internal/testutil" - "github.com/ipfs/boxo/internal/test" "github.com/ipfs/go-peertaskqueue" "github.com/ipfs/go-peertaskqueue/peertask" ) func TestPushHaveVsBlock(t *testing.T) { - test.Flaky(t) - partner := testutil.GeneratePeers(1)[0] wantHave := peertask.Task{ @@ -64,8 +61,6 @@ func TestPushHaveVsBlock(t *testing.T) { } func TestPushSizeInfo(t *testing.T) { - test.Flaky(t) - partner := testutil.GeneratePeers(1)[0] wantBlockBlockSize := 10 @@ -178,8 +173,6 @@ func TestPushSizeInfo(t *testing.T) { } func TestPushHaveVsBlockActive(t *testing.T) { - test.Flaky(t) - partner := testutil.GeneratePeers(1)[0] wantBlock := peertask.Task{ @@ -234,8 +227,6 @@ func TestPushHaveVsBlockActive(t *testing.T) { } func TestPushSizeInfoActive(t *testing.T) { - test.Flaky(t) - partner := testutil.GeneratePeers(1)[0] wantBlock := peertask.Task{ From c135968f9621e8bde81d49fad118c07f8676af24 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 25 Aug 2023 13:09:20 +0200 Subject: [PATCH 032/312] provider: mark TestOfflineRecordsThenOnlineRepublish flaky on windows --- provider/reprovider_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/provider/reprovider_test.go b/provider/reprovider_test.go index bfb8fc187..4efd9bda1 100644 --- a/provider/reprovider_test.go +++ b/provider/reprovider_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + "github.com/ipfs/boxo/internal/test" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" dssync "github.com/ipfs/go-datastore/sync" @@ -180,6 +181,9 @@ func testProvider(t *testing.T, singleProvide bool) { } func TestOfflineRecordsThenOnlineRepublish(t *testing.T) { + if runtime.GOOS == "windows" { + test.Flaky(t) + } // Don't run in Parallel as this test is time sensitive. someHash, err := mh.Sum([]byte("Vires in Numeris!"), mh.BLAKE3, -1) From 79159c31ef43f8eeb129f1177a8d7ed665122f54 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 25 Aug 2023 14:15:17 +0200 Subject: [PATCH 033/312] bitswap: mark TestSessionGetBlocks flaky https://github.com/ipfs/boxo/actions/runs/5975685205/job/16212124664?pr=422 --- bitswap/client/internal/session/session_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bitswap/client/internal/session/session_test.go b/bitswap/client/internal/session/session_test.go index 819a535c1..2eb166f90 100644 --- a/bitswap/client/internal/session/session_test.go +++ b/bitswap/client/internal/session/session_test.go @@ -149,6 +149,8 @@ func (pm *fakePeerManager) BroadcastWantHaves(ctx context.Context, cids []cid.Ci func (pm *fakePeerManager) SendCancels(ctx context.Context, cancels []cid.Cid) {} func TestSessionGetBlocks(t *testing.T) { + test.Flaky(t) + ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) fpm := newFakePeerManager() fspm := newFakeSessionPeerManager() From 13569468babd703fc0da2413ef36cded14136b3a Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 25 Aug 2023 17:19:03 +0200 Subject: [PATCH 034/312] feat(routing/http)!: delegated peer routing server and client, IPIP 417 (#422) --- CHANGELOG.md | 18 +- routing/http/README.md | 23 +- routing/http/client/client.go | 130 ++++-- routing/http/client/client_test.go | 238 ++++++++-- routing/http/contentrouter/contentrouter.go | 161 ++++++- .../http/contentrouter/contentrouter_test.go | 195 +++++++-- routing/http/server/server.go | 408 +++++++++++------- routing/http/server/server_test.go | 180 ++++++-- routing/http/types/iter/iter.go | 20 + routing/http/types/json/provider.go | 116 ----- routing/http/types/json/requests.go | 51 +++ routing/http/types/json/responses.go | 98 +++++ routing/http/types/ndjson/provider.go | 36 -- routing/http/types/ndjson/records.go | 46 ++ routing/http/types/provider.go | 17 - routing/http/types/provider_unknown.go | 63 --- routing/http/types/record.go | 6 + ...{provider_bitswap.go => record_bitswap.go} | 88 ++-- routing/http/types/record_peer.go | 81 ++++ routing/http/types/record_unknown.go | 47 ++ 20 files changed, 1428 insertions(+), 594 deletions(-) delete mode 100644 routing/http/types/json/provider.go create mode 100644 routing/http/types/json/requests.go create mode 100644 routing/http/types/json/responses.go delete mode 100644 routing/http/types/ndjson/provider.go create mode 100644 routing/http/types/ndjson/records.go delete mode 100644 routing/http/types/provider.go delete mode 100644 routing/http/types/provider_unknown.go create mode 100644 routing/http/types/record.go rename routing/http/types/{provider_bitswap.go => record_bitswap.go} (64%) create mode 100644 routing/http/types/record_peer.go create mode 100644 routing/http/types/record_unknown.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 7afe79f54..8a4122902 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,10 +16,26 @@ The following emojis are used to highlight certain changes: ### Added +* ✨ The `routing/http` implements Delegated Peer Routing introduced in [IPIP-417](https://github.com/ipfs/specs/pull/417). + ### Changed +* 🛠 The `routing/http` package received the following modifications: + * Client `GetIPNSRecord` and `PutIPNSRecord` have been renamed to `GetIPNS` and + `PutIPNS`, respectively. Similarly, the required function names in the server + `ContentRouter` have also been updated. + * `ReadBitswapProviderRecord` has been renamed to `BitswapRecord` and marked as deprecated. + From now on, please use the protocol-agnostic `PeerRecord` for most use cases. The new + Peer Schema has been introduced in [IPIP-417](https://github.com/ipfs/specs/pull/417). + ### Removed +* 🛠 The `routing/http` package experienced following removals: + * Server and client no longer support the experimental `Provide` method. + `ProvideBitswap` is still usable, but marked as deprecated. A protocol-agnostic + provide mechanism is being worked on in [IPIP-378](https://github.com/ipfs/specs/pull/378). + * Server no longer exports `FindProvidersPath` and `ProvidePath`. + ### Fixed ### Security @@ -32,7 +48,7 @@ The following emojis are used to highlight certain changes: as per [IPIP-379](https://specs.ipfs.tech/ipips/ipip-0379/). * 🛠 The `verifycid` package has been updated with the new Allowlist interface as part of reducing globals efforts. -* The `blockservice` and `provider` packages has been updated to accommodate for +* The `blockservice` and `provider` packages has been updated to accommodate for changes in `verifycid`. ### Changed diff --git a/routing/http/README.md b/routing/http/README.md index 65650ed50..0f0281f8f 100644 --- a/routing/http/README.md +++ b/routing/http/README.md @@ -1,24 +1,9 @@ -go-delegated-routing +Routing V1 Server and Client ======================= -> Delegated routing Client and Server over Reframe RPC - -This package provides delegated routing implementation in Go: -- Client (for IPFS nodes like [Kubo](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingrouters-parameters)), -- Server (for public indexers such as https://cid.contact) +> Delegated Routing V1 Server and Client over HTTP API. ## Documentation -- Go docs: https://pkg.go.dev/github.com/ipfs/boxo/routing/http/ - -## Lead Maintainer - -🦗🎶 - -## Contributing - -Contributions are welcome! This repository is part of the IPFS project and therefore governed by our [contributing guidelines](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md). - -## License - -[SPDX-License-Identifier: Apache-2.0 OR MIT](LICENSE.md) \ No newline at end of file +- Go Documentation: https://pkg.go.dev/github.com/ipfs/boxo/routing/http +- Routing V1 Specification: https://specs.ipfs.tech/routing/http-routing-v1/ diff --git a/routing/http/client/client.go b/routing/http/client/client.go index c504a0315..4a0d29b33 100644 --- a/routing/http/client/client.go +++ b/routing/http/client/client.go @@ -16,14 +16,12 @@ import ( ipns "github.com/ipfs/boxo/ipns" "github.com/ipfs/boxo/routing/http/contentrouter" "github.com/ipfs/boxo/routing/http/internal/drjson" - "github.com/ipfs/boxo/routing/http/server" "github.com/ipfs/boxo/routing/http/types" "github.com/ipfs/boxo/routing/http/types/iter" jsontypes "github.com/ipfs/boxo/routing/http/types/json" "github.com/ipfs/boxo/routing/http/types/ndjson" "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" - record "github.com/libp2p/go-libp2p-record" "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/peer" "github.com/multiformats/go-multiaddr" @@ -31,7 +29,7 @@ import ( var ( _ contentrouter.Client = &client{} - logger = logging.Logger("service/delegatedrouting") + logger = logging.Logger("routing/http/client") defaultHTTPClient = &http.Client{ Transport: &ResponseBodyLimitedTransport{ RoundTripper: http.DefaultTransport, @@ -50,18 +48,17 @@ const ( type client struct { baseURL string httpClient httpClient - validator record.Validator clock clock.Clock - - accepts string + accepts string peerID peer.ID addrs []types.Multiaddr identity crypto.PrivKey - // called immeidately after signing a provide req - // used for testing, e.g. testing the server with a mangled signature - afterSignCallback func(req *types.WriteBitswapProviderRecord) + // Called immediately after signing a provide request. It is used + // for testing, e.g., testing the server with a mangled signature. + //lint:ignore SA1019 // ignore staticcheck + afterSignCallback func(req *types.WriteBitswapRecord) } // defaultUserAgent is used as a fallback to inform HTTP server which library @@ -121,12 +118,11 @@ func WithStreamResultsRequired() Option { } // New creates a content routing API client. -// The Provider and identity parameters are option. If they are nil, the `Provide` method will not function. +// The Provider and identity parameters are option. If they are nil, the [client.ProvideBitswap] method will not function. func New(baseURL string, opts ...Option) (*client, error) { client := &client{ baseURL: baseURL, httpClient: defaultHTTPClient, - validator: ipns.Validator{}, clock: clock.New(), accepts: strings.Join([]string{mediaTypeNDJSON, mediaTypeJSON}, ","), } @@ -164,11 +160,11 @@ func (c *measuringIter[T]) Close() error { return c.Iter.Close() } -func (c *client) FindProviders(ctx context.Context, key cid.Cid) (provs iter.ResultIter[types.ProviderResponse], err error) { +func (c *client) FindProviders(ctx context.Context, key cid.Cid) (providers iter.ResultIter[types.Record], err error) { // TODO test measurements m := newMeasurement("FindProviders") - url := c.baseURL + server.ProvidePath + key.String() + url := c.baseURL + "/routing/v1/providers/" + key.String() req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { return nil, err @@ -192,7 +188,7 @@ func (c *client) FindProviders(ctx context.Context, key cid.Cid) (provs iter.Res if resp.StatusCode == http.StatusNotFound { resp.Body.Close() m.record(ctx) - return iter.FromSlice[iter.Result[types.ProviderResponse]](nil), nil + return iter.FromSlice[iter.Result[types.Record]](nil), nil } if resp.StatusCode != http.StatusOK { @@ -220,24 +216,27 @@ func (c *client) FindProviders(ctx context.Context, key cid.Cid) (provs iter.Res } }() - var it iter.ResultIter[types.ProviderResponse] + var it iter.ResultIter[types.Record] switch mediaType { case mediaTypeJSON: - parsedResp := &jsontypes.ReadProvidersResponse{} + parsedResp := &jsontypes.ProvidersResponse{} err = json.NewDecoder(resp.Body).Decode(parsedResp) - var sliceIt iter.Iter[types.ProviderResponse] = iter.FromSlice(parsedResp.Providers) + var sliceIt iter.Iter[types.Record] = iter.FromSlice(parsedResp.Providers) it = iter.ToResultIter(sliceIt) case mediaTypeNDJSON: skipBodyClose = true - it = ndjson.NewReadProvidersResponseIter(resp.Body) + it = ndjson.NewRecordsIter(resp.Body) default: logger.Errorw("unknown media type", "MediaType", mediaType, "ContentType", respContentType) return nil, errors.New("unknown content type") } - return &measuringIter[iter.Result[types.ProviderResponse]]{Iter: it, ctx: ctx, m: m}, nil + return &measuringIter[iter.Result[types.Record]]{Iter: it, ctx: ctx, m: m}, nil } +// Deprecated: protocol-agnostic provide is being worked on in [IPIP-378]: +// +// [IPIP-378]: https://github.com/ipfs/specs/pull/378 func (c *client) ProvideBitswap(ctx context.Context, keys []cid.Cid, ttl time.Duration) (time.Duration, error) { if c.identity == nil { return 0, errors.New("cannot provide Bitswap records without an identity") @@ -253,7 +252,7 @@ func (c *client) ProvideBitswap(ctx context.Context, keys []cid.Cid, ttl time.Du now := c.clock.Now() - req := types.WriteBitswapProviderRecord{ + req := types.WriteBitswapRecord{ Protocol: "transport-bitswap", Schema: types.SchemaBitswap, Payload: types.BitswapPayload{ @@ -282,10 +281,13 @@ func (c *client) ProvideBitswap(ctx context.Context, keys []cid.Cid, ttl time.Du } // ProvideAsync makes a provide request to a delegated router -func (c *client) provideSignedBitswapRecord(ctx context.Context, bswp *types.WriteBitswapProviderRecord) (time.Duration, error) { - req := jsontypes.WriteProvidersRequest{Providers: []types.WriteProviderRecord{bswp}} +// +//lint:ignore SA1019 // ignore staticcheck +func (c *client) provideSignedBitswapRecord(ctx context.Context, bswp *types.WriteBitswapRecord) (time.Duration, error) { + //lint:ignore SA1019 // ignore staticcheck + req := jsontypes.WriteProvidersRequest{Providers: []types.Record{bswp}} - url := c.baseURL + server.ProvidePath + url := c.baseURL + "/routing/v1/providers/" b, err := drjson.MarshalJSONBytes(req) if err != nil { @@ -306,6 +308,8 @@ func (c *client) provideSignedBitswapRecord(ctx context.Context, bswp *types.Wri if resp.StatusCode != http.StatusOK { return 0, httpError(resp.StatusCode, resp.Body) } + + //lint:ignore SA1019 // ignore staticcheck var provideResult jsontypes.WriteProvidersResponse err = json.NewDecoder(resp.Body).Decode(&provideResult) if err != nil { @@ -315,7 +319,8 @@ func (c *client) provideSignedBitswapRecord(ctx context.Context, bswp *types.Wri return 0, fmt.Errorf("expected 1 result but got %d", len(provideResult.ProvideResults)) } - v, ok := provideResult.ProvideResults[0].(*types.WriteBitswapProviderRecordResponse) + //lint:ignore SA1019 // ignore staticcheck + v, ok := provideResult.ProvideResults[0].(*types.WriteBitswapRecordResponse) if !ok { return 0, fmt.Errorf("expected AdvisoryTTL field") } @@ -327,7 +332,80 @@ func (c *client) provideSignedBitswapRecord(ctx context.Context, bswp *types.Wri return 0, nil } -func (c *client) FindIPNSRecord(ctx context.Context, name ipns.Name) (*ipns.Record, error) { +func (c *client) FindPeers(ctx context.Context, pid peer.ID) (peers iter.ResultIter[types.Record], err error) { + m := newMeasurement("FindPeers") + + url := c.baseURL + "/routing/v1/peers/" + peer.ToCid(pid).String() + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return nil, err + } + req.Header.Set("Accept", c.accepts) + + m.host = req.Host + + start := c.clock.Now() + resp, err := c.httpClient.Do(req) + + m.err = err + m.latency = c.clock.Since(start) + + if err != nil { + m.record(ctx) + return nil, err + } + + m.statusCode = resp.StatusCode + if resp.StatusCode == http.StatusNotFound { + resp.Body.Close() + m.record(ctx) + return iter.FromSlice[iter.Result[types.Record]](nil), nil + } + + if resp.StatusCode != http.StatusOK { + err := httpError(resp.StatusCode, resp.Body) + resp.Body.Close() + m.record(ctx) + return nil, err + } + + respContentType := resp.Header.Get("Content-Type") + mediaType, _, err := mime.ParseMediaType(respContentType) + if err != nil { + resp.Body.Close() + m.err = err + m.record(ctx) + return nil, fmt.Errorf("parsing Content-Type: %w", err) + } + + m.mediaType = mediaType + + var skipBodyClose bool + defer func() { + if !skipBodyClose { + resp.Body.Close() + } + }() + + var it iter.ResultIter[types.Record] + switch mediaType { + case mediaTypeJSON: + parsedResp := &jsontypes.PeersResponse{} + err = json.NewDecoder(resp.Body).Decode(parsedResp) + var sliceIt iter.Iter[types.Record] = iter.FromSlice(parsedResp.Peers) + it = iter.ToResultIter(sliceIt) + case mediaTypeNDJSON: + skipBodyClose = true + it = ndjson.NewRecordsIter(resp.Body) + default: + logger.Errorw("unknown media type", "MediaType", mediaType, "ContentType", respContentType) + return nil, errors.New("unknown content type") + } + + return &measuringIter[iter.Result[types.Record]]{Iter: it, ctx: ctx, m: m}, nil +} + +func (c *client) GetIPNS(ctx context.Context, name ipns.Name) (*ipns.Record, error) { url := c.baseURL + "/routing/v1/ipns/" + name.String() httpReq, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) @@ -365,7 +443,7 @@ func (c *client) FindIPNSRecord(ctx context.Context, name ipns.Name) (*ipns.Reco return record, nil } -func (c *client) ProvideIPNSRecord(ctx context.Context, name ipns.Name, record *ipns.Record) error { +func (c *client) PutIPNS(ctx context.Context, name ipns.Name, record *ipns.Record) error { url := c.baseURL + "/routing/v1/ipns/" + name.String() rawRecord, err := ipns.MarshalRecord(record) diff --git a/routing/http/client/client_test.go b/routing/http/client/client_test.go index c1690b3f2..95683bc3f 100644 --- a/routing/http/client/client_test.go +++ b/routing/http/client/client_test.go @@ -3,6 +3,7 @@ package client import ( "context" "crypto/rand" + "encoding/json" "errors" "net/http" "net/http/httptest" @@ -31,27 +32,28 @@ import ( type mockContentRouter struct{ mock.Mock } -func (m *mockContentRouter) FindProviders(ctx context.Context, key cid.Cid, limit int) (iter.ResultIter[types.ProviderResponse], error) { +func (m *mockContentRouter) FindProviders(ctx context.Context, key cid.Cid, limit int) (iter.ResultIter[types.Record], error) { args := m.Called(ctx, key, limit) - return args.Get(0).(iter.ResultIter[types.ProviderResponse]), args.Error(1) + return args.Get(0).(iter.ResultIter[types.Record]), args.Error(1) } +//lint:ignore SA1019 // ignore staticcheck func (m *mockContentRouter) ProvideBitswap(ctx context.Context, req *server.BitswapWriteProvideRequest) (time.Duration, error) { args := m.Called(ctx, req) return args.Get(0).(time.Duration), args.Error(1) } -func (m *mockContentRouter) Provide(ctx context.Context, req *server.WriteProvideRequest) (types.ProviderResponse, error) { - args := m.Called(ctx, req) - return args.Get(0).(types.ProviderResponse), args.Error(1) +func (m *mockContentRouter) FindPeers(ctx context.Context, pid peer.ID, limit int) (iter.ResultIter[types.Record], error) { + args := m.Called(ctx, pid, limit) + return args.Get(0).(iter.ResultIter[types.Record]), args.Error(1) } -func (m *mockContentRouter) FindIPNSRecord(ctx context.Context, name ipns.Name) (*ipns.Record, error) { +func (m *mockContentRouter) GetIPNS(ctx context.Context, name ipns.Name) (*ipns.Record, error) { args := m.Called(ctx, name) return args.Get(0).(*ipns.Record), args.Error(1) } -func (m *mockContentRouter) ProvideIPNSRecord(ctx context.Context, name ipns.Name, record *ipns.Record) error { +func (m *mockContentRouter) PutIPNS(ctx context.Context, name ipns.Name, record *ipns.Record) error { args := m.Called(ctx, name, record) return args.Error(0) } @@ -144,6 +146,13 @@ func makeCID() cid.Cid { return c } +func drAddrsToAddrs(drmas []types.Multiaddr) (addrs []multiaddr.Multiaddr) { + for _, a := range drmas { + addrs = append(addrs, a.Multiaddr) + } + return +} + func addrsToDRAddrs(addrs []multiaddr.Multiaddr) (drmas []types.Multiaddr) { for _, a := range addrs { drmas = append(drmas, types.Multiaddr{Multiaddr: a}) @@ -151,19 +160,26 @@ func addrsToDRAddrs(addrs []multiaddr.Multiaddr) (drmas []types.Multiaddr) { return } -func drAddrsToAddrs(drmas []types.Multiaddr) (addrs []multiaddr.Multiaddr) { - for _, a := range drmas { - addrs = append(addrs, a.Multiaddr) +func makePeerRecord() types.PeerRecord { + peerID, addrs, _ := makeProviderAndIdentity() + return types.PeerRecord{ + Schema: types.SchemaPeer, + ID: &peerID, + Protocols: []string{"transport-bitswap"}, + Addrs: addrsToDRAddrs(addrs), + Extra: map[string]json.RawMessage{}, } - return } -func makeBSReadProviderResp() types.ReadBitswapProviderRecord { +//lint:ignore SA1019 // ignore staticcheck +func makeBitswapRecord() types.BitswapRecord { peerID, addrs, _ := makeProviderAndIdentity() - return types.ReadBitswapProviderRecord{ - Protocol: "transport-bitswap", + //lint:ignore SA1019 // ignore staticcheck + return types.BitswapRecord{ + //lint:ignore SA1019 // ignore staticcheck Schema: types.SchemaBitswap, ID: &peerID, + Protocol: "transport-bitswap", Addrs: addrsToDRAddrs(addrs), } } @@ -208,35 +224,46 @@ func (e *osErrContains) errContains(t *testing.T, err error) { } func TestClient_FindProviders(t *testing.T) { - bsReadProvResp := makeBSReadProviderResp() - bitswapProvs := []iter.Result[types.ProviderResponse]{ - {Val: &bsReadProvResp}, + peerRecord := makePeerRecord() + peerProviders := []iter.Result[types.Record]{ + {Val: &peerRecord}, + } + + bitswapRecord := makeBitswapRecord() + bitswapProviders := []iter.Result[types.Record]{ + {Val: &bitswapRecord}, } cases := []struct { name string httpStatusCode int stopServer bool - routerProvs []iter.Result[types.ProviderResponse] + routerResult []iter.Result[types.Record] routerErr error clientRequiresStreaming bool serverStreamingDisabled bool expErrContains osErrContains - expProvs []iter.Result[types.ProviderResponse] + expResult []iter.Result[types.Record] expStreamingResponse bool expJSONResponse bool }{ { name: "happy case", - routerProvs: bitswapProvs, - expProvs: bitswapProvs, + routerResult: peerProviders, + expResult: peerProviders, + expStreamingResponse: true, + }, + { + name: "happy case (with deprecated bitswap schema)", + routerResult: bitswapProviders, + expResult: bitswapProviders, expStreamingResponse: true, }, { name: "server doesn't support streaming", - routerProvs: bitswapProvs, - expProvs: bitswapProvs, + routerResult: peerProviders, + expResult: peerProviders, serverStreamingDisabled: true, expJSONResponse: true, }, @@ -262,7 +289,7 @@ func TestClient_FindProviders(t *testing.T) { { name: "returns no providers if the HTTP server returns a 404 respones", httpStatusCode: 404, - expProvs: nil, + expResult: nil, }, } for _, c := range cases { @@ -287,6 +314,7 @@ func TestClient_FindProviders(t *testing.T) { assert.Equal(t, mediaTypeNDJSON, r.Header.Get("Content-Type")) }) } + if c.expJSONResponse { onRespReceived = append(onRespReceived, func(r *http.Response) { assert.Equal(t, mediaTypeJSON, r.Header.Get("Content-Type")) @@ -315,20 +343,18 @@ func TestClient_FindProviders(t *testing.T) { } cid := makeCID() - findProvsIter := iter.FromSlice(c.routerProvs) - + routerResultIter := iter.FromSlice(c.routerResult) if c.expStreamingResponse { - router.On("FindProviders", mock.Anything, cid, 0).Return(findProvsIter, c.routerErr) + router.On("FindProviders", mock.Anything, cid, 0).Return(routerResultIter, c.routerErr) } else { - router.On("FindProviders", mock.Anything, cid, 20).Return(findProvsIter, c.routerErr) + router.On("FindProviders", mock.Anything, cid, 20).Return(routerResultIter, c.routerErr) } - provsIter, err := client.FindProviders(ctx, cid) - + resultIter, err := client.FindProviders(ctx, cid) c.expErrContains.errContains(t, err) - provs := iter.ReadAll[iter.Result[types.ProviderResponse]](provsIter) - assert.Equal(t, c.expProvs, provs) + results := iter.ReadAll[iter.Result[types.Record]](resultIter) + assert.Equal(t, c.expResult, results) }) } } @@ -416,7 +442,8 @@ func TestClient_Provide(t *testing.T) { deps.server.Close() } if c.mangleSignature { - client.afterSignCallback = func(req *types.WriteBitswapProviderRecord) { + //lint:ignore SA1019 // ignore staticcheck + client.afterSignCallback = func(req *types.WriteBitswapRecord) { mh, err := multihash.Encode([]byte("boom"), multihash.SHA2_256) require.NoError(t, err) mb, err := multibase.Encode(multibase.Base64, mh) @@ -426,6 +453,7 @@ func TestClient_Provide(t *testing.T) { } } + //lint:ignore SA1019 // ignore staticcheck expectedProvReq := &server.BitswapWriteProvideRequest{ Keys: c.cids, Timestamp: clock.Now().Truncate(time.Millisecond), @@ -457,6 +485,134 @@ func TestClient_Provide(t *testing.T) { } } +func TestClient_FindPeers(t *testing.T) { + peerRecord := makePeerRecord() + peerRecords := []iter.Result[types.Record]{ + {Val: &peerRecord}, + } + pid := *peerRecord.ID + + cases := []struct { + name string + httpStatusCode int + stopServer bool + routerResult []iter.Result[types.Record] + routerErr error + clientRequiresStreaming bool + serverStreamingDisabled bool + + expErrContains osErrContains + expResult []iter.Result[types.Record] + expStreamingResponse bool + expJSONResponse bool + }{ + { + name: "happy case", + routerResult: peerRecords, + expResult: peerRecords, + expStreamingResponse: true, + }, + { + name: "server doesn't support streaming", + routerResult: peerRecords, + expResult: peerRecords, + serverStreamingDisabled: true, + expJSONResponse: true, + }, + { + name: "client requires streaming but server doesn't support it", + serverStreamingDisabled: true, + clientRequiresStreaming: true, + expErrContains: osErrContains{expContains: "HTTP error with StatusCode=400: no supported content types"}, + }, + { + name: "returns an error if there's a non-200 response", + httpStatusCode: 500, + expErrContains: osErrContains{expContains: "HTTP error with StatusCode=500"}, + }, + { + name: "returns an error if the HTTP client returns a non-HTTP error", + stopServer: true, + expErrContains: osErrContains{ + expContains: "connect: connection refused", + expContainsWin: "connectex: No connection could be made because the target machine actively refused it.", + }, + }, + { + name: "returns no providers if the HTTP server returns a 404 respones", + httpStatusCode: 404, + expResult: nil, + }, + } + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + var ( + clientOpts []Option + serverOpts []server.Option + onRespReceived []func(*http.Response) + onReqReceived []func(*http.Request) + ) + + if c.serverStreamingDisabled { + serverOpts = append(serverOpts, server.WithStreamingResultsDisabled()) + } + + if c.clientRequiresStreaming { + clientOpts = append(clientOpts, WithStreamResultsRequired()) + onReqReceived = append(onReqReceived, func(r *http.Request) { + assert.Equal(t, mediaTypeNDJSON, r.Header.Get("Accept")) + }) + } + + if c.expStreamingResponse { + onRespReceived = append(onRespReceived, func(r *http.Response) { + assert.Equal(t, mediaTypeNDJSON, r.Header.Get("Content-Type")) + }) + } + + if c.expJSONResponse { + onRespReceived = append(onRespReceived, func(r *http.Response) { + assert.Equal(t, mediaTypeJSON, r.Header.Get("Content-Type")) + }) + } + + deps := makeTestDeps(t, clientOpts, serverOpts) + + deps.recordingHTTPClient.f = append(deps.recordingHTTPClient.f, onRespReceived...) + deps.recordingHandler.f = append(deps.recordingHandler.f, onReqReceived...) + + client := deps.client + router := deps.router + + ctx, cancel := context.WithCancel(context.Background()) + t.Cleanup(cancel) + + if c.httpStatusCode != 0 { + deps.server.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(c.httpStatusCode) + }) + } + + if c.stopServer { + deps.server.Close() + } + + routerResultIter := iter.FromSlice(c.routerResult) + if c.expStreamingResponse { + router.On("FindPeers", mock.Anything, pid, 0).Return(routerResultIter, c.routerErr) + } else { + router.On("FindPeers", mock.Anything, pid, 20).Return(routerResultIter, c.routerErr) + } + + resultIter, err := client.FindPeers(ctx, pid) + c.expErrContains.errContains(t, err) + + results := iter.ReadAll[iter.Result[types.Record]](resultIter) + assert.Equal(t, c.expResult, results) + }) + } +} + func makeName(t *testing.T) (crypto.PrivKey, ipns.Name) { sk, _, err := crypto.GenerateEd25519Key(rand.Reader) require.NoError(t, err) @@ -492,9 +648,9 @@ func TestClient_IPNS(t *testing.T) { client := deps.client router := deps.router - router.On("FindIPNSRecord", mock.Anything, name).Return(nil, errors.New("something wrong happened")) + router.On("GetIPNS", mock.Anything, name).Return(nil, errors.New("something wrong happened")) - receivedRecord, err := client.FindIPNSRecord(context.Background(), name) + receivedRecord, err := client.GetIPNS(context.Background(), name) require.Error(t, err) require.Nil(t, receivedRecord) }) @@ -508,9 +664,9 @@ func TestClient_IPNS(t *testing.T) { client := deps.client router := deps.router - router.On("FindIPNSRecord", mock.Anything, name).Return(record, nil) + router.On("GetIPNS", mock.Anything, name).Return(record, nil) - receivedRecord, err := client.FindIPNSRecord(context.Background(), name) + receivedRecord, err := client.GetIPNS(context.Background(), name) require.NoError(t, err) require.Equal(t, record, receivedRecord) }) @@ -524,9 +680,9 @@ func TestClient_IPNS(t *testing.T) { client := deps.client router := deps.router - router.On("FindIPNSRecord", mock.Anything, name2).Return(record, nil) + router.On("GetIPNS", mock.Anything, name2).Return(record, nil) - receivedRecord, err := client.FindIPNSRecord(context.Background(), name2) + receivedRecord, err := client.GetIPNS(context.Background(), name2) require.Error(t, err) require.Nil(t, receivedRecord) }) @@ -539,9 +695,9 @@ func TestClient_IPNS(t *testing.T) { client := deps.client router := deps.router - router.On("ProvideIPNSRecord", mock.Anything, name, record).Return(nil) + router.On("PutIPNS", mock.Anything, name, record).Return(nil) - err := client.ProvideIPNSRecord(context.Background(), name, record) + err := client.PutIPNS(context.Background(), name, record) require.NoError(t, err) }) } diff --git a/routing/http/contentrouter/contentrouter.go b/routing/http/contentrouter/contentrouter.go index 8318a3163..2438d4fea 100644 --- a/routing/http/contentrouter/contentrouter.go +++ b/routing/http/contentrouter/contentrouter.go @@ -3,26 +3,32 @@ package contentrouter import ( "context" "reflect" + "strings" "time" + "github.com/ipfs/boxo/ipns" "github.com/ipfs/boxo/routing/http/internal" "github.com/ipfs/boxo/routing/http/types" "github.com/ipfs/boxo/routing/http/types/iter" "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" + routinghelpers "github.com/libp2p/go-libp2p-routing-helpers" "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/routing" "github.com/multiformats/go-multiaddr" "github.com/multiformats/go-multihash" ) -var logger = logging.Logger("service/contentrouting") +var logger = logging.Logger("routing/http/contentrouter") const ttl = 24 * time.Hour type Client interface { + FindProviders(ctx context.Context, key cid.Cid) (iter.ResultIter[types.Record], error) ProvideBitswap(ctx context.Context, keys []cid.Cid, ttl time.Duration) (time.Duration, error) - FindProviders(ctx context.Context, key cid.Cid) (iter.ResultIter[types.ProviderResponse], error) + FindPeers(ctx context.Context, pid peer.ID) (peers iter.ResultIter[types.Record], err error) + GetIPNS(ctx context.Context, name ipns.Name) (*ipns.Record, error) + PutIPNS(ctx context.Context, name ipns.Name, record *ipns.Record) error } type contentRouter struct { @@ -32,6 +38,10 @@ type contentRouter struct { } var _ routing.ContentRouting = (*contentRouter)(nil) +var _ routing.PeerRouting = (*contentRouter)(nil) +var _ routing.ValueStore = (*contentRouter)(nil) +var _ routinghelpers.ProvideManyRouter = (*contentRouter)(nil) +var _ routinghelpers.ReadyAbleRouter = (*contentRouter)(nil) type option func(c *contentRouter) @@ -60,8 +70,7 @@ func NewContentRoutingClient(c Client, opts ...option) *contentRouter { } func (c *contentRouter) Provide(ctx context.Context, key cid.Cid, announce bool) error { - // If 'true' is - // passed, it also announces it, otherwise it is just kept in the local + // If 'true' is passed, it also announces it, otherwise it is just kept in the local // accounting of which objects are being provided. if !announce { return nil @@ -73,7 +82,7 @@ func (c *contentRouter) Provide(ctx context.Context, key cid.Cid, announce bool) // ProvideMany provides a set of keys to the remote delegate. // Large sets of keys are chunked into multiple requests and sent concurrently, according to the concurrency configuration. -// TODO: implement retries through transient errors +// TODO: switch to use [client.Provide] when ready. func (c *contentRouter) ProvideMany(ctx context.Context, mhKeys []multihash.Multihash) error { keys := make([]cid.Cid, 0, len(mhKeys)) for _, m := range mhKeys { @@ -97,13 +106,14 @@ func (c *contentRouter) ProvideMany(ctx context.Context, mhKeys []multihash.Mult ) } -// Ready is part of the existing `ProvideMany` interface. +// Ready is part of the existing [routing.ReadyAbleRouter] interface. func (c *contentRouter) Ready() bool { return true } -// readProviderResponses reads bitswap records from the iterator into the given channel, dropping non-bitswap records. -func readProviderResponses(iter iter.ResultIter[types.ProviderResponse], ch chan<- peer.AddrInfo) { +// readProviderResponses reads peer records (and bitswap records for legacy +// compatibility) from the iterator into the given channel. +func readProviderResponses(iter iter.ResultIter[types.Record], ch chan<- peer.AddrInfo) { defer close(ch) defer iter.Close() for iter.Next() { @@ -113,8 +123,31 @@ func readProviderResponses(iter iter.ResultIter[types.ProviderResponse], ch chan continue } v := res.Val - if v.GetSchema() == types.SchemaBitswap { - result, ok := v.(*types.ReadBitswapProviderRecord) + switch v.GetSchema() { + case types.SchemaPeer: + result, ok := v.(*types.PeerRecord) + if !ok { + logger.Errorw( + "problem casting find providers result", + "Schema", v.GetSchema(), + "Type", reflect.TypeOf(v).String(), + ) + continue + } + + var addrs []multiaddr.Multiaddr + for _, a := range result.Addrs { + addrs = append(addrs, a.Multiaddr) + } + + ch <- peer.AddrInfo{ + ID: *result.ID, + Addrs: addrs, + } + //lint:ignore SA1019 // ignore staticcheck + case types.SchemaBitswap: + //lint:ignore SA1019 // ignore staticcheck + result, ok := v.(*types.BitswapRecord) if !ok { logger.Errorw( "problem casting find providers result", @@ -149,3 +182,111 @@ func (c *contentRouter) FindProvidersAsync(ctx context.Context, key cid.Cid, num go readProviderResponses(resultsIter, ch) return ch } + +func (c *contentRouter) FindPeer(ctx context.Context, pid peer.ID) (peer.AddrInfo, error) { + iter, err := c.client.FindPeers(ctx, pid) + if err != nil { + return peer.AddrInfo{}, err + } + defer iter.Close() + + for iter.Next() { + res := iter.Val() + if res.Err != nil { + logger.Warnw("error iterating provider responses: %s", res.Err) + continue + } + v := res.Val + if v.GetSchema() == types.SchemaPeer { + result, ok := v.(*types.PeerRecord) + if !ok { + logger.Errorw( + "problem casting find providers result", + "Schema", v.GetSchema(), + "Type", reflect.TypeOf(v).String(), + ) + continue + } + + var addrs []multiaddr.Multiaddr + for _, a := range result.Addrs { + addrs = append(addrs, a.Multiaddr) + } + + return peer.AddrInfo{ + ID: *result.ID, + Addrs: addrs, + }, nil + } + } + + return peer.AddrInfo{}, err +} + +func (c *contentRouter) PutValue(ctx context.Context, key string, data []byte, opts ...routing.Option) error { + if !strings.HasPrefix(key, "/ipns/") { + return routing.ErrNotSupported + } + + name, err := ipns.NameFromRoutingKey([]byte(key)) + if err != nil { + return err + } + + record, err := ipns.UnmarshalRecord(data) + if err != nil { + return err + } + + return c.client.PutIPNS(ctx, name, record) +} + +func (c *contentRouter) GetValue(ctx context.Context, key string, opts ...routing.Option) ([]byte, error) { + if !strings.HasPrefix(key, "/ipns/") { + return nil, routing.ErrNotSupported + } + + name, err := ipns.NameFromRoutingKey([]byte(key)) + if err != nil { + return nil, err + } + + record, err := c.client.GetIPNS(ctx, name) + if err != nil { + return nil, err + } + + return ipns.MarshalRecord(record) +} + +func (c *contentRouter) SearchValue(ctx context.Context, key string, opts ...routing.Option) (<-chan []byte, error) { + if !strings.HasPrefix(key, "/ipns/") { + return nil, routing.ErrNotSupported + } + + name, err := ipns.NameFromRoutingKey([]byte(key)) + if err != nil { + return nil, err + } + + ch := make(chan []byte) + + go func() { + record, err := c.client.GetIPNS(ctx, name) + if err != nil { + close(ch) + return + } + + raw, err := ipns.MarshalRecord(record) + if err != nil { + close(ch) + return + } + + ch <- raw + close(ch) + }() + + return ch, nil +} diff --git a/routing/http/contentrouter/contentrouter_test.go b/routing/http/contentrouter/contentrouter_test.go index 3830482e2..83a086997 100644 --- a/routing/http/contentrouter/contentrouter_test.go +++ b/routing/http/contentrouter/contentrouter_test.go @@ -6,10 +6,15 @@ import ( "testing" "time" + "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/ipns" + ipfspath "github.com/ipfs/boxo/path" "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/crypto" "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/routing" "github.com/multiformats/go-multihash" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -23,9 +28,14 @@ func (m *mockClient) ProvideBitswap(ctx context.Context, keys []cid.Cid, ttl tim return args.Get(0).(time.Duration), args.Error(1) } -func (m *mockClient) FindProviders(ctx context.Context, key cid.Cid) (iter.ResultIter[types.ProviderResponse], error) { +func (m *mockClient) FindProviders(ctx context.Context, key cid.Cid) (iter.ResultIter[types.Record], error) { args := m.Called(ctx, key) - return args.Get(0).(iter.ResultIter[types.ProviderResponse]), args.Error(1) + return args.Get(0).(iter.ResultIter[types.Record]), args.Error(1) +} + +func (m *mockClient) FindPeers(ctx context.Context, pid peer.ID) (iter.ResultIter[types.Record], error) { + args := m.Called(ctx, pid) + return args.Get(0).(iter.ResultIter[types.Record]), args.Error(1) } func (m *mockClient) Ready(ctx context.Context) (bool, error) { @@ -33,18 +43,14 @@ func (m *mockClient) Ready(ctx context.Context) (bool, error) { return args.Bool(0), args.Error(1) } -func makeCID() cid.Cid { - buf := make([]byte, 63) - _, err := rand.Read(buf) - if err != nil { - panic(err) - } - mh, err := multihash.Encode(buf, multihash.SHA2_256) - if err != nil { - panic(err) - } - c := cid.NewCidV1(cid.Raw, mh) - return c +func (m *mockClient) GetIPNS(ctx context.Context, name ipns.Name) (*ipns.Record, error) { + args := m.Called(ctx, name) + return args.Get(0).(*ipns.Record), args.Error(1) +} + +func (m *mockClient) PutIPNS(ctx context.Context, name ipns.Name, record *ipns.Record) error { + args := m.Called(ctx, name, record) + return args.Error(0) } func TestProvide(t *testing.T) { @@ -100,6 +106,20 @@ func TestProvideMany(t *testing.T) { require.NoError(t, err) } +func makeCID() cid.Cid { + buf := make([]byte, 63) + _, err := rand.Read(buf) + if err != nil { + panic(err) + } + mh, err := multihash.Encode(buf, multihash.SHA2_256) + if err != nil { + panic(err) + } + c := cid.NewCidV1(cid.Raw, mh) + return c +} + func TestFindProvidersAsync(t *testing.T) { key := makeCID() ctx := context.Background() @@ -108,26 +128,40 @@ func TestFindProvidersAsync(t *testing.T) { p1 := peer.ID("peer1") p2 := peer.ID("peer2") - ais := []types.ProviderResponse{ - &types.ReadBitswapProviderRecord{ - Protocol: "transport-bitswap", - Schema: types.SchemaBitswap, - ID: &p1, + p3 := peer.ID("peer3") + p4 := peer.ID("peer4") + ais := []types.Record{ + &types.PeerRecord{ + Schema: types.SchemaPeer, + ID: &p1, + Protocols: []string{"transport-bitswap"}, }, - &types.ReadBitswapProviderRecord{ - Protocol: "transport-bitswap", + //lint:ignore SA1019 // ignore staticcheck + &types.BitswapRecord{ + //lint:ignore SA1019 // ignore staticcheck Schema: types.SchemaBitswap, ID: &p2, + Protocol: "transport-bitswap", + }, + &types.PeerRecord{ + Schema: types.SchemaPeer, + ID: &p3, + Protocols: []string{"transport-bitswap"}, + }, + &types.PeerRecord{ + Schema: types.SchemaPeer, + ID: &p4, + Protocols: []string{"transport-horse"}, }, - &types.UnknownProviderRecord{ - Protocol: "UNKNOWN", + &types.UnknownRecord{ + Schema: "unknown", }, } - aisIter := iter.ToResultIter[types.ProviderResponse](iter.FromSlice(ais)) + aisIter := iter.ToResultIter[types.Record](iter.FromSlice(ais)) client.On("FindProviders", ctx, key).Return(aisIter, nil) - aiChan := crc.FindProvidersAsync(ctx, key, 2) + aiChan := crc.FindProvidersAsync(ctx, key, 3) var actualAIs []peer.AddrInfo for ai := range aiChan { @@ -137,7 +171,118 @@ func TestFindProvidersAsync(t *testing.T) { expected := []peer.AddrInfo{ {ID: p1}, {ID: p2}, + {ID: p3}, + {ID: p4}, } require.Equal(t, expected, actualAIs) } + +func TestFindPeer(t *testing.T) { + ctx := context.Background() + client := &mockClient{} + crc := NewContentRoutingClient(client) + + p1 := peer.ID("peer1") + ais := []types.Record{ + &types.UnknownRecord{ + Schema: "unknown", + }, + &types.PeerRecord{ + Schema: types.SchemaPeer, + ID: &p1, + Protocols: []string{"transport-bitswap"}, + }, + } + aisIter := iter.ToResultIter[types.Record](iter.FromSlice(ais)) + + client.On("FindPeers", ctx, p1).Return(aisIter, nil) + + peer, err := crc.FindPeer(ctx, p1) + require.NoError(t, err) + require.Equal(t, peer.ID, p1) +} + +func makeName(t *testing.T) (crypto.PrivKey, ipns.Name) { + sk, _, err := crypto.GenerateEd25519Key(rand.Reader) + require.NoError(t, err) + + pid, err := peer.IDFromPrivateKey(sk) + require.NoError(t, err) + + return sk, ipns.NameFromPeer(pid) +} + +func makeIPNSRecord(t *testing.T, sk crypto.PrivKey, opts ...ipns.Option) (*ipns.Record, []byte) { + cid, err := cid.Decode("bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4") + require.NoError(t, err) + + path := path.IpfsPath(cid) + eol := time.Now().Add(time.Hour * 48) + ttl := time.Second * 20 + + record, err := ipns.NewRecord(sk, ipfspath.FromString(path.String()), 1, eol, ttl, opts...) + require.NoError(t, err) + + rawRecord, err := ipns.MarshalRecord(record) + require.NoError(t, err) + + return record, rawRecord +} + +func TestGetValue(t *testing.T) { + ctx := context.Background() + client := &mockClient{} + crc := NewContentRoutingClient(client) + + t.Run("Fail On Unsupported Key", func(t *testing.T) { + v, err := crc.GetValue(ctx, "/something/unsupported") + require.Nil(t, v) + require.ErrorIs(t, err, routing.ErrNotSupported) + }) + + t.Run("Fail On Invalid IPNS Name", func(t *testing.T) { + v, err := crc.GetValue(ctx, "/ipns/invalid") + require.Nil(t, v) + require.Error(t, err) + }) + + t.Run("Succeeds On Valid IPNS Name", func(t *testing.T) { + sk, name := makeName(t) + rec, rawRec := makeIPNSRecord(t, sk) + client.On("GetIPNS", ctx, name).Return(rec, nil) + v, err := crc.GetValue(ctx, string(name.RoutingKey())) + require.NoError(t, err) + require.Equal(t, rawRec, v) + }) +} + +func TestPutValue(t *testing.T) { + ctx := context.Background() + client := &mockClient{} + crc := NewContentRoutingClient(client) + + sk, name := makeName(t) + _, rawRec := makeIPNSRecord(t, sk) + + t.Run("Fail On Unsupported Key", func(t *testing.T) { + err := crc.PutValue(ctx, "/something/unsupported", rawRec) + require.ErrorIs(t, err, routing.ErrNotSupported) + }) + + t.Run("Fail On Invalid IPNS Name", func(t *testing.T) { + err := crc.PutValue(ctx, "/ipns/invalid", rawRec) + require.Error(t, err) + }) + + t.Run("Fail On Invalid IPNS Record", func(t *testing.T) { + err := crc.PutValue(ctx, string(name.RoutingKey()), []byte("gibberish")) + require.Error(t, err) + }) + + t.Run("Succeeds On Valid IPNS Name & Record", func(t *testing.T) { + client.On("PutIPNS", ctx, name, mock.Anything).Return(nil) + err := crc.PutValue(ctx, string(name.RoutingKey()), rawRec) + require.NoError(t, err) + }) +} diff --git a/routing/http/server/server.go b/routing/http/server/server.go index 835262990..9e7d81a04 100644 --- a/routing/http/server/server.go +++ b/routing/http/server/server.go @@ -37,34 +37,45 @@ const ( DefaultStreamingRecordsLimit = 0 ) -var logger = logging.Logger("service/server/delegatedrouting") +var logger = logging.Logger("routing/http/server") const ( - ProvidePath = "/routing/v1/providers/" - FindProvidersPath = "/routing/v1/providers/{cid}" - IPNSPath = "/routing/v1/ipns/{cid}" + providePath = "/routing/v1/providers/" + findProvidersPath = "/routing/v1/providers/{cid}" + findPeersPath = "/routing/v1/peers/{peer-id}" + GetIPNSPath = "/routing/v1/ipns/{cid}" ) type FindProvidersAsyncResponse struct { - ProviderResponse types.ProviderResponse + ProviderResponse types.Record Error error } type ContentRouter interface { - // FindProviders searches for peers who are able to provide a given key. Limit - // indicates the maximum amount of results to return. 0 means unbounded. - FindProviders(ctx context.Context, key cid.Cid, limit int) (iter.ResultIter[types.ProviderResponse], error) + // FindProviders searches for peers who are able to provide the given [cid.Cid]. + // Limit indicates the maximum amount of results to return; 0 means unbounded. + FindProviders(ctx context.Context, cid cid.Cid, limit int) (iter.ResultIter[types.Record], error) + + // Deprecated: protocol-agnostic provide is being worked on in [IPIP-378]: + // + // [IPIP-378]: https://github.com/ipfs/specs/pull/378 ProvideBitswap(ctx context.Context, req *BitswapWriteProvideRequest) (time.Duration, error) - Provide(ctx context.Context, req *WriteProvideRequest) (types.ProviderResponse, error) - // FindIPNSRecord searches for an [ipns.Record] for the given [ipns.Name]. - FindIPNSRecord(ctx context.Context, name ipns.Name) (*ipns.Record, error) + // FindPeers searches for peers who have the provided [peer.ID]. + // Limit indicates the maximum amount of results to return; 0 means unbounded. + FindPeers(ctx context.Context, pid peer.ID, limit int) (iter.ResultIter[types.Record], error) + + // GetIPNS searches for an [ipns.Record] for the given [ipns.Name]. + GetIPNS(ctx context.Context, name ipns.Name) (*ipns.Record, error) - // ProvideIPNSRecord stores the provided [ipns.Record] for the given [ipns.Name]. It is - // guaranteed that the record matches the provided name. - ProvideIPNSRecord(ctx context.Context, name ipns.Name, record *ipns.Record) error + // PutIPNS stores the provided [ipns.Record] for the given [ipns.Name]. + // It is guaranteed that the record matches the provided name. + PutIPNS(ctx context.Context, name ipns.Name, record *ipns.Record) error } +// Deprecated: protocol-agnostic provide is being worked on in [IPIP-378]: +// +// [IPIP-378]: https://github.com/ipfs/specs/pull/378 type BitswapWriteProvideRequest struct { Keys []cid.Cid Timestamp time.Time @@ -73,6 +84,9 @@ type BitswapWriteProvideRequest struct { Addrs []multiaddr.Multiaddr } +// Deprecated: protocol-agnostic provide is being worked on in [IPIP-378]: +// +// [IPIP-378]: https://github.com/ipfs/specs/pull/378 type WriteProvideRequest struct { Protocol string Schema string @@ -88,16 +102,18 @@ func WithStreamingResultsDisabled() Option { } } -// WithRecordsLimit sets a limit that will be passed to ContentRouter.FindProviders -// for non-streaming requests (application/json). Default is DefaultRecordsLimit. +// WithRecordsLimit sets a limit that will be passed to [ContentRouter.FindProviders] +// and [ContentRouter.FindPeers] for non-streaming requests (application/json). +// Default is [DefaultRecordsLimit]. func WithRecordsLimit(limit int) Option { return func(s *server) { s.recordsLimit = limit } } -// WithStreamingRecordsLimit sets a limit that will be passed to ContentRouter.FindProviders -// for streaming requests (application/x-ndjson). Default is DefaultStreamingRecordsLimit. +// WithStreamingRecordsLimit sets a limit that will be passed to [ContentRouter.FindProviders] +// and [ContentRouter.FindPeers] for streaming requests (application/x-ndjson). +// Default is [DefaultStreamingRecordsLimit]. func WithStreamingRecordsLimit(limit int) Option { return func(s *server) { s.streamingRecordsLimit = limit @@ -116,12 +132,11 @@ func Handler(svc ContentRouter, opts ...Option) http.Handler { } r := mux.NewRouter() - r.HandleFunc(ProvidePath, server.provide).Methods(http.MethodPut) - r.HandleFunc(FindProvidersPath, server.findProviders).Methods(http.MethodGet) - - r.HandleFunc(IPNSPath, server.getIPNSRecord).Methods(http.MethodGet) - r.HandleFunc(IPNSPath, server.putIPNSRecord).Methods(http.MethodPut) - + r.HandleFunc(findProvidersPath, server.findProviders).Methods(http.MethodGet) + r.HandleFunc(providePath, server.provide).Methods(http.MethodPut) + r.HandleFunc(findPeersPath, server.findPeers).Methods(http.MethodGet) + r.HandleFunc(GetIPNSPath, server.GetIPNS).Methods(http.MethodGet) + r.HandleFunc(GetIPNSPath, server.PutIPNS).Methods(http.MethodPut) return r } @@ -132,7 +147,149 @@ type server struct { streamingRecordsLimit int } +func (s *server) detectResponseType(r *http.Request) (string, error) { + var ( + supportsNDJSON bool + supportsJSON bool + + acceptHeaders = r.Header.Values("Accept") + ) + + if len(acceptHeaders) == 0 { + return mediaTypeJSON, nil + } + + for _, acceptHeader := range acceptHeaders { + for _, accept := range strings.Split(acceptHeader, ",") { + mediaType, _, err := mime.ParseMediaType(accept) + if err != nil { + return "", fmt.Errorf("unable to parse Accept header: %w", err) + } + + switch mediaType { + case mediaTypeJSON, mediaTypeWildcard: + supportsJSON = true + case mediaTypeNDJSON: + supportsNDJSON = true + } + } + } + + if supportsNDJSON && !s.disableNDJSON { + return mediaTypeNDJSON, nil + } else if supportsJSON { + return mediaTypeJSON, nil + } else { + return "", errors.New("no supported content types") + } +} + +func (s *server) findProviders(w http.ResponseWriter, httpReq *http.Request) { + vars := mux.Vars(httpReq) + cidStr := vars["cid"] + cid, err := cid.Decode(cidStr) + if err != nil { + writeErr(w, "FindProviders", http.StatusBadRequest, fmt.Errorf("unable to parse CID: %w", err)) + return + } + + mediaType, err := s.detectResponseType(httpReq) + if err != nil { + writeErr(w, "FindProviders", http.StatusBadRequest, err) + return + } + + var ( + handlerFunc func(w http.ResponseWriter, provIter iter.ResultIter[types.Record]) + recordsLimit int + ) + + if mediaType == mediaTypeNDJSON { + handlerFunc = s.findProvidersNDJSON + recordsLimit = s.streamingRecordsLimit + } else { + handlerFunc = s.findProvidersJSON + recordsLimit = s.recordsLimit + } + + provIter, err := s.svc.FindProviders(httpReq.Context(), cid, recordsLimit) + if err != nil { + writeErr(w, "FindProviders", http.StatusInternalServerError, fmt.Errorf("delegate error: %w", err)) + return + } + + handlerFunc(w, provIter) +} + +func (s *server) findProvidersJSON(w http.ResponseWriter, provIter iter.ResultIter[types.Record]) { + defer provIter.Close() + + providers, err := iter.ReadAllResults(provIter) + if err != nil { + writeErr(w, "FindProviders", http.StatusInternalServerError, fmt.Errorf("delegate error: %w", err)) + return + } + + writeJSONResult(w, "FindProviders", jsontypes.ProvidersResponse{ + Providers: providers, + }) +} + +func (s *server) findProvidersNDJSON(w http.ResponseWriter, provIter iter.ResultIter[types.Record]) { + writeResultsIterNDJSON(w, provIter) +} + +func (s *server) findPeers(w http.ResponseWriter, r *http.Request) { + pidStr := mux.Vars(r)["peer-id"] + + // pidStr must be in CIDv1 format. Therefore, use [cid.Decode]. We can't use + // [peer.Decode] because that would allow other formats to pass through. + cid, err := cid.Decode(pidStr) + if err != nil { + if pid, err := peer.Decode(pidStr); err == nil { + writeErr(w, "FindPeers", http.StatusBadRequest, fmt.Errorf("the value is a peer ID, try using its CID representation: %s", peer.ToCid(pid).String())) + } else { + writeErr(w, "FindPeers", http.StatusBadRequest, fmt.Errorf("unable to parse peer ID: %w", err)) + } + return + } + + pid, err := peer.FromCid(cid) + if err != nil { + writeErr(w, "FindPeers", http.StatusBadRequest, fmt.Errorf("unable to parse peer ID: %w", err)) + return + } + + mediaType, err := s.detectResponseType(r) + if err != nil { + writeErr(w, "FindPeers", http.StatusBadRequest, err) + return + } + + var ( + handlerFunc func(w http.ResponseWriter, provIter iter.ResultIter[types.Record]) + recordsLimit int + ) + + if mediaType == mediaTypeNDJSON { + handlerFunc = s.findPeersNDJSON + recordsLimit = s.streamingRecordsLimit + } else { + handlerFunc = s.findPeersJSON + recordsLimit = s.recordsLimit + } + + provIter, err := s.svc.FindPeers(r.Context(), pid, recordsLimit) + if err != nil { + writeErr(w, "FindPeers", http.StatusInternalServerError, fmt.Errorf("delegate error: %w", err)) + return + } + + handlerFunc(w, provIter) +} + func (s *server) provide(w http.ResponseWriter, httpReq *http.Request) { + //lint:ignore SA1019 // ignore staticcheck req := jsontypes.WriteProvidersRequest{} err := json.NewDecoder(httpReq.Body).Decode(&req) _ = httpReq.Body.Close() @@ -141,11 +298,13 @@ func (s *server) provide(w http.ResponseWriter, httpReq *http.Request) { return } + //lint:ignore SA1019 // ignore staticcheck resp := jsontypes.WriteProvidersResponse{} for i, prov := range req.Providers { switch v := prov.(type) { - case *types.WriteBitswapProviderRecord: + //lint:ignore SA1019 // ignore staticcheck + case *types.WriteBitswapRecord: err := v.Verify() if err != nil { logErr("Provide", "signature verification failed", err) @@ -173,148 +332,42 @@ func (s *server) provide(w http.ResponseWriter, httpReq *http.Request) { return } resp.ProvideResults = append(resp.ProvideResults, - &types.WriteBitswapProviderRecordResponse{ + //lint:ignore SA1019 // ignore staticcheck + &types.WriteBitswapRecordResponse{ Protocol: v.Protocol, Schema: v.Schema, AdvisoryTTL: &types.Duration{Duration: advisoryTTL}, }, ) - case *types.UnknownProviderRecord: - provResp, err := s.svc.Provide(httpReq.Context(), &WriteProvideRequest{ - Protocol: v.Protocol, - Schema: v.Schema, - Bytes: v.Bytes, - }) - if err != nil { - writeErr(w, "Provide", http.StatusInternalServerError, fmt.Errorf("delegate error: %w", err)) - return - } - resp.ProvideResults = append(resp.ProvideResults, provResp) default: - writeErr(w, "Provide", http.StatusBadRequest, fmt.Errorf("provider record %d does not contain a protocol", i)) + writeErr(w, "Provide", http.StatusBadRequest, fmt.Errorf("provider record %d is not bitswap", i)) return } } writeJSONResult(w, "Provide", resp) } -func (s *server) findProviders(w http.ResponseWriter, httpReq *http.Request) { - vars := mux.Vars(httpReq) - cidStr := vars["cid"] - cid, err := cid.Decode(cidStr) - if err != nil { - writeErr(w, "FindProviders", http.StatusBadRequest, fmt.Errorf("unable to parse CID: %w", err)) - return - } - - var handlerFunc func(w http.ResponseWriter, provIter iter.ResultIter[types.ProviderResponse]) - - var supportsNDJSON bool - var supportsJSON bool - var recordsLimit int - acceptHeaders := httpReq.Header.Values("Accept") - if len(acceptHeaders) == 0 { - handlerFunc = s.findProvidersJSON - recordsLimit = s.recordsLimit - } else { - for _, acceptHeader := range acceptHeaders { - for _, accept := range strings.Split(acceptHeader, ",") { - mediaType, _, err := mime.ParseMediaType(accept) - if err != nil { - writeErr(w, "FindProviders", http.StatusBadRequest, fmt.Errorf("unable to parse Accept header: %w", err)) - return - } - - switch mediaType { - case mediaTypeJSON, mediaTypeWildcard: - supportsJSON = true - case mediaTypeNDJSON: - supportsNDJSON = true - } - } - } - - if supportsNDJSON && !s.disableNDJSON { - handlerFunc = s.findProvidersNDJSON - recordsLimit = s.streamingRecordsLimit - } else if supportsJSON { - handlerFunc = s.findProvidersJSON - recordsLimit = s.recordsLimit - } else { - writeErr(w, "FindProviders", http.StatusBadRequest, errors.New("no supported content types")) - return - } - } +func (s *server) findPeersJSON(w http.ResponseWriter, peersIter iter.ResultIter[types.Record]) { + defer peersIter.Close() - provIter, err := s.svc.FindProviders(httpReq.Context(), cid, recordsLimit) + peers, err := iter.ReadAllResults(peersIter) if err != nil { - writeErr(w, "FindProviders", http.StatusInternalServerError, fmt.Errorf("delegate error: %w", err)) + writeErr(w, "FindPeers", http.StatusInternalServerError, fmt.Errorf("delegate error: %w", err)) return } - handlerFunc(w, provIter) + writeJSONResult(w, "FindPeers", jsontypes.PeersResponse{ + Peers: peers, + }) } -func (s *server) findProvidersJSON(w http.ResponseWriter, provIter iter.ResultIter[types.ProviderResponse]) { - defer provIter.Close() - - var ( - providers []types.ProviderResponse - i int - ) - - for provIter.Next() { - res := provIter.Val() - if res.Err != nil { - writeErr(w, "FindProviders", http.StatusInternalServerError, fmt.Errorf("delegate error on result %d: %w", i, res.Err)) - return - } - providers = append(providers, res.Val) - i++ - } - response := jsontypes.ReadProvidersResponse{Providers: providers} - writeJSONResult(w, "FindProviders", response) -} - -func (s *server) findProvidersNDJSON(w http.ResponseWriter, provIter iter.ResultIter[types.ProviderResponse]) { - defer provIter.Close() - - w.Header().Set("Content-Type", mediaTypeNDJSON) - w.WriteHeader(http.StatusOK) - for provIter.Next() { - res := provIter.Val() - if res.Err != nil { - logger.Errorw("FindProviders ndjson iterator error", "Error", res.Err) - return - } - // don't use an encoder because we can't easily differentiate writer errors from encoding errors - b, err := drjson.MarshalJSONBytes(res.Val) - if err != nil { - logger.Errorw("FindProviders ndjson marshal error", "Error", err) - return - } - - _, err = w.Write(b) - if err != nil { - logger.Warn("FindProviders ndjson write error", "Error", err) - return - } - - _, err = w.Write([]byte{'\n'}) - if err != nil { - logger.Warn("FindProviders ndjson write error", "Error", err) - return - } - - if f, ok := w.(http.Flusher); ok { - f.Flush() - } - } +func (s *server) findPeersNDJSON(w http.ResponseWriter, peersIter iter.ResultIter[types.Record]) { + writeResultsIterNDJSON(w, peersIter) } -func (s *server) getIPNSRecord(w http.ResponseWriter, r *http.Request) { +func (s *server) GetIPNS(w http.ResponseWriter, r *http.Request) { if !strings.Contains(r.Header.Get("Accept"), mediaTypeIPNSRecord) { - writeErr(w, "GetIPNSRecord", http.StatusNotAcceptable, errors.New("content type in 'Accept' header is missing or not supported")) + writeErr(w, "GetIPNS", http.StatusNotAcceptable, errors.New("content type in 'Accept' header is missing or not supported")) return } @@ -322,25 +375,25 @@ func (s *server) getIPNSRecord(w http.ResponseWriter, r *http.Request) { cidStr := vars["cid"] cid, err := cid.Decode(cidStr) if err != nil { - writeErr(w, "GetIPNSRecord", http.StatusBadRequest, fmt.Errorf("unable to parse CID: %w", err)) + writeErr(w, "GetIPNS", http.StatusBadRequest, fmt.Errorf("unable to parse CID: %w", err)) return } name, err := ipns.NameFromCid(cid) if err != nil { - writeErr(w, "GetIPNSRecord", http.StatusBadRequest, fmt.Errorf("peer ID CID is not valid: %w", err)) + writeErr(w, "GetIPNS", http.StatusBadRequest, fmt.Errorf("peer ID CID is not valid: %w", err)) return } - record, err := s.svc.FindIPNSRecord(r.Context(), name) + record, err := s.svc.GetIPNS(r.Context(), name) if err != nil { - writeErr(w, "GetIPNSRecord", http.StatusInternalServerError, fmt.Errorf("delegate error: %w", err)) + writeErr(w, "GetIPNS", http.StatusInternalServerError, fmt.Errorf("delegate error: %w", err)) return } rawRecord, err := ipns.MarshalRecord(record) if err != nil { - writeErr(w, "GetIPNSRecord", http.StatusInternalServerError, err) + writeErr(w, "GetIPNS", http.StatusInternalServerError, err) return } @@ -356,9 +409,9 @@ func (s *server) getIPNSRecord(w http.ResponseWriter, r *http.Request) { w.Write(rawRecord) } -func (s *server) putIPNSRecord(w http.ResponseWriter, r *http.Request) { +func (s *server) PutIPNS(w http.ResponseWriter, r *http.Request) { if !strings.Contains(r.Header.Get("Content-Type"), mediaTypeIPNSRecord) { - writeErr(w, "PutIPNSRecord", http.StatusNotAcceptable, errors.New("content type in 'Content-Type' header is missing or not supported")) + writeErr(w, "PutIPNS", http.StatusNotAcceptable, errors.New("content type in 'Content-Type' header is missing or not supported")) return } @@ -366,38 +419,38 @@ func (s *server) putIPNSRecord(w http.ResponseWriter, r *http.Request) { cidStr := vars["cid"] cid, err := cid.Decode(cidStr) if err != nil { - writeErr(w, "PutIPNSRecord", http.StatusBadRequest, fmt.Errorf("unable to parse CID: %w", err)) + writeErr(w, "PutIPNS", http.StatusBadRequest, fmt.Errorf("unable to parse CID: %w", err)) return } name, err := ipns.NameFromCid(cid) if err != nil { - writeErr(w, "PutIPNSRecord", http.StatusBadRequest, fmt.Errorf("peer ID CID is not valid: %w", err)) + writeErr(w, "PutIPNS", http.StatusBadRequest, fmt.Errorf("peer ID CID is not valid: %w", err)) return } // Limit the reader to the maximum record size. rawRecord, err := io.ReadAll(io.LimitReader(r.Body, int64(ipns.MaxRecordSize))) if err != nil { - writeErr(w, "PutIPNSRecord", http.StatusBadRequest, fmt.Errorf("provided record is too long: %w", err)) + writeErr(w, "PutIPNS", http.StatusBadRequest, fmt.Errorf("provided record is too long: %w", err)) return } record, err := ipns.UnmarshalRecord(rawRecord) if err != nil { - writeErr(w, "PutIPNSRecord", http.StatusBadRequest, fmt.Errorf("provided record is invalid: %w", err)) + writeErr(w, "PutIPNS", http.StatusBadRequest, fmt.Errorf("provided record is invalid: %w", err)) return } err = ipns.ValidateWithName(record, name) if err != nil { - writeErr(w, "PutIPNSRecord", http.StatusBadRequest, fmt.Errorf("provided record is invalid: %w", err)) + writeErr(w, "PutIPNS", http.StatusBadRequest, fmt.Errorf("provided record is invalid: %w", err)) return } - err = s.svc.ProvideIPNSRecord(r.Context(), name, record) + err = s.svc.PutIPNS(r.Context(), name, record) if err != nil { - writeErr(w, "PutIPNSRecord", http.StatusInternalServerError, fmt.Errorf("delegate error: %w", err)) + writeErr(w, "PutIPNS", http.StatusInternalServerError, fmt.Errorf("delegate error: %w", err)) return } @@ -437,3 +490,40 @@ func writeErr(w http.ResponseWriter, method string, statusCode int, cause error) func logErr(method, msg string, err error) { logger.Infow(msg, "Method", method, "Error", err) } + +func writeResultsIterNDJSON(w http.ResponseWriter, resultIter iter.ResultIter[types.Record]) { + defer resultIter.Close() + + w.Header().Set("Content-Type", mediaTypeNDJSON) + w.WriteHeader(http.StatusOK) + + for resultIter.Next() { + res := resultIter.Val() + if res.Err != nil { + logger.Errorw("ndjson iterator error", "Error", res.Err) + return + } + // don't use an encoder because we can't easily differentiate writer errors from encoding errors + b, err := drjson.MarshalJSONBytes(res.Val) + if err != nil { + logger.Errorw("ndjson marshal error", "Error", err) + return + } + + _, err = w.Write(b) + if err != nil { + logger.Warn("ndjson write error", "Error", err) + return + } + + _, err = w.Write([]byte{'\n'}) + if err != nil { + logger.Warn("ndjson write error", "Error", err) + return + } + + if f, ok := w.(http.Flusher); ok { + f.Flush() + } + } +} diff --git a/routing/http/server/server_test.go b/routing/http/server/server_test.go index dfe38f0da..f6d4a3dba 100644 --- a/routing/http/server/server_test.go +++ b/routing/http/server/server_test.go @@ -18,6 +18,7 @@ import ( "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/peer" + b58 "github.com/mr-tron/base58/base58" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) @@ -28,12 +29,11 @@ func TestHeaders(t *testing.T) { t.Cleanup(server.Close) serverAddr := "http://" + server.Listener.Addr().String() - results := iter.FromSlice([]iter.Result[types.ProviderResponse]{ - {Val: &types.ReadBitswapProviderRecord{ - Protocol: "transport-bitswap", - Schema: types.SchemaBitswap, - }}, - }, + results := iter.FromSlice([]iter.Result[types.Record]{ + {Val: &types.PeerRecord{ + Schema: types.SchemaPeer, + Protocols: []string{"transport-bitswap"}, + }}}, ) c := "baeabep4vu3ceru7nerjjbk37sxb7wmftteve4hcosmyolsbsiubw2vr6pqzj6mw7kv6tbn6nqkkldnklbjgm5tzbi4hkpkled4xlcr7xz4bq" @@ -43,13 +43,13 @@ func TestHeaders(t *testing.T) { router.On("FindProviders", mock.Anything, cb, DefaultRecordsLimit). Return(results, nil) - resp, err := http.Get(serverAddr + ProvidePath + c) + resp, err := http.Get(serverAddr + "/routing/v1/providers/" + c) require.NoError(t, err) require.Equal(t, 200, resp.StatusCode) header := resp.Header.Get("Content-Type") require.Equal(t, mediaTypeJSON, header) - resp, err = http.Get(serverAddr + ProvidePath + "BAD_CID") + resp, err = http.Get(serverAddr + "/routing/v1/providers/" + "BAD_CID") require.NoError(t, err) defer resp.Body.Close() require.Equal(t, 400, resp.StatusCode) @@ -57,7 +57,17 @@ func TestHeaders(t *testing.T) { require.Equal(t, "text/plain; charset=utf-8", header) } -func TestResponse(t *testing.T) { +func makePeerID(t *testing.T) (crypto.PrivKey, peer.ID) { + sk, _, err := crypto.GenerateEd25519Key(rand.Reader) + require.NoError(t, err) + + pid, err := peer.IDFromPrivateKey(sk) + require.NoError(t, err) + + return sk, pid +} + +func TestProviders(t *testing.T) { pidStr := "12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vn" pid2Str := "12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vz" cidStr := "bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4" @@ -73,20 +83,21 @@ func TestResponse(t *testing.T) { runTest := func(t *testing.T, contentType string, expectedStream bool, expectedBody string) { t.Parallel() - results := iter.FromSlice([]iter.Result[types.ProviderResponse]{ - {Val: &types.ReadBitswapProviderRecord{ - Protocol: "transport-bitswap", - Schema: types.SchemaBitswap, - ID: &pid, - Addrs: []types.Multiaddr{}, + results := iter.FromSlice([]iter.Result[types.Record]{ + {Val: &types.PeerRecord{ + Schema: types.SchemaPeer, + ID: &pid, + Protocols: []string{"transport-bitswap"}, + Addrs: []types.Multiaddr{}, }}, - {Val: &types.ReadBitswapProviderRecord{ - Protocol: "transport-bitswap", + //lint:ignore SA1019 // ignore staticcheck + {Val: &types.BitswapRecord{ + //lint:ignore SA1019 // ignore staticcheck Schema: types.SchemaBitswap, ID: &pid2, + Protocol: "transport-bitswap", Addrs: []types.Multiaddr{}, - }}, - }, + }}}, ) router := &mockContentRouter{} @@ -98,7 +109,7 @@ func TestResponse(t *testing.T) { limit = DefaultStreamingRecordsLimit } router.On("FindProviders", mock.Anything, cid, limit).Return(results, nil) - urlStr := serverAddr + ProvidePath + cidStr + urlStr := serverAddr + "/routing/v1/providers/" + cidStr req, err := http.NewRequest(http.MethodGet, urlStr, nil) require.NoError(t, err) @@ -113,25 +124,120 @@ func TestResponse(t *testing.T) { body, err := io.ReadAll(resp.Body) require.NoError(t, err) - require.Equal(t, string(body), expectedBody) + require.Equal(t, expectedBody, string(body)) } t.Run("JSON Response", func(t *testing.T) { - runTest(t, mediaTypeJSON, false, `{"Providers":[{"Protocol":"transport-bitswap","Schema":"bitswap","ID":"12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vn","Addrs":[]},{"Protocol":"transport-bitswap","Schema":"bitswap","ID":"12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vz","Addrs":[]}]}`) + runTest(t, mediaTypeJSON, false, `{"Providers":[{"Addrs":[],"ID":"12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vn","Protocols":["transport-bitswap"],"Schema":"peer"},{"Schema":"bitswap","Protocol":"transport-bitswap","ID":"12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vz"}]}`) }) t.Run("NDJSON Response", func(t *testing.T) { - runTest(t, mediaTypeNDJSON, true, `{"Protocol":"transport-bitswap","Schema":"bitswap","ID":"12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vn","Addrs":[]}`+"\n"+`{"Protocol":"transport-bitswap","Schema":"bitswap","ID":"12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vz","Addrs":[]}`+"\n") + runTest(t, mediaTypeNDJSON, true, `{"Addrs":[],"ID":"12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vn","Protocols":["transport-bitswap"],"Schema":"peer"}`+"\n"+`{"Schema":"bitswap","Protocol":"transport-bitswap","ID":"12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vz"}`+"\n") }) } -func makeName(t *testing.T) (crypto.PrivKey, ipns.Name) { - sk, _, err := crypto.GenerateEd25519Key(rand.Reader) - require.NoError(t, err) +func TestPeers(t *testing.T) { + makeRequest := func(t *testing.T, router *mockContentRouter, contentType, arg string) *http.Response { + server := httptest.NewServer(Handler(router)) + t.Cleanup(server.Close) + req, err := http.NewRequest(http.MethodGet, "http://"+server.Listener.Addr().String()+"/routing/v1/peers/"+arg, nil) + require.NoError(t, err) + req.Header.Set("Accept", contentType) + resp, err := http.DefaultClient.Do(req) + require.NoError(t, err) + return resp + } - pid, err := peer.IDFromPrivateKey(sk) - require.NoError(t, err) + t.Run("GET /routing/v1/peers/{non-peer-cid} returns 400", func(t *testing.T) { + t.Parallel() + router := &mockContentRouter{} + resp := makeRequest(t, router, mediaTypeJSON, "bafkqaaa") + require.Equal(t, 400, resp.StatusCode) + }) + + t.Run("GET /routing/v1/peers/{base58-peer-id} returns 400", func(t *testing.T) { + t.Parallel() + + _, pid := makePeerID(t) + router := &mockContentRouter{} + resp := makeRequest(t, router, mediaTypeJSON, b58.Encode([]byte(pid))) + require.Equal(t, 400, resp.StatusCode) + }) + + t.Run("GET /routing/v1/peers/{cid-peer-id} returns 200 with correct body (JSON)", func(t *testing.T) { + t.Parallel() + + _, pid := makePeerID(t) + results := iter.FromSlice([]iter.Result[types.Record]{ + {Val: &types.PeerRecord{ + Schema: types.SchemaPeer, + ID: &pid, + Protocols: []string{"transport-bitswap", "transport-foo"}, + Addrs: []types.Multiaddr{}, + }}, + {Val: &types.PeerRecord{ + Schema: types.SchemaPeer, + ID: &pid, + Protocols: []string{"transport-foo"}, + Addrs: []types.Multiaddr{}, + }}, + }) + + router := &mockContentRouter{} + router.On("FindPeers", mock.Anything, pid, 20).Return(results, nil) + + resp := makeRequest(t, router, mediaTypeJSON, peer.ToCid(pid).String()) + require.Equal(t, 200, resp.StatusCode) + + header := resp.Header.Get("Content-Type") + require.Equal(t, mediaTypeJSON, header) + + body, err := io.ReadAll(resp.Body) + require.NoError(t, err) + + expectedBody := `{"Peers":[{"Addrs":[],"ID":"` + pid.String() + `","Protocols":["transport-bitswap","transport-foo"],"Schema":"peer"},{"Addrs":[],"ID":"` + pid.String() + `","Protocols":["transport-foo"],"Schema":"peer"}]}` + require.Equal(t, expectedBody, string(body)) + }) + + t.Run("GET /routing/v1/peers/{cid-peer-id} returns 200 with correct body (NDJSON)", func(t *testing.T) { + t.Parallel() + + _, pid := makePeerID(t) + results := iter.FromSlice([]iter.Result[types.Record]{ + {Val: &types.PeerRecord{ + Schema: types.SchemaPeer, + ID: &pid, + Protocols: []string{"transport-bitswap", "transport-foo"}, + Addrs: []types.Multiaddr{}, + }}, + {Val: &types.PeerRecord{ + Schema: types.SchemaPeer, + ID: &pid, + Protocols: []string{"transport-foo"}, + Addrs: []types.Multiaddr{}, + }}, + }) + + router := &mockContentRouter{} + router.On("FindPeers", mock.Anything, pid, 0).Return(results, nil) + + resp := makeRequest(t, router, mediaTypeNDJSON, peer.ToCid(pid).String()) + require.Equal(t, 200, resp.StatusCode) + + header := resp.Header.Get("Content-Type") + require.Equal(t, mediaTypeNDJSON, header) + + body, err := io.ReadAll(resp.Body) + require.NoError(t, err) + + expectedBody := `{"Addrs":[],"ID":"` + pid.String() + `","Protocols":["transport-bitswap","transport-foo"],"Schema":"peer"}` + "\n" + `{"Addrs":[],"ID":"` + pid.String() + `","Protocols":["transport-foo"],"Schema":"peer"}` + "\n" + require.Equal(t, expectedBody, string(body)) + }) +} + +func makeName(t *testing.T) (crypto.PrivKey, ipns.Name) { + sk, pid := makePeerID(t) return sk, ipns.NameFromPeer(pid) } @@ -179,7 +285,7 @@ func TestIPNS(t *testing.T) { require.NoError(t, err) router := &mockContentRouter{} - router.On("FindIPNSRecord", mock.Anything, name1).Return(rec, nil) + router.On("GetIPNS", mock.Anything, name1).Return(rec, nil) resp := makeRequest(t, router, "/routing/v1/ipns/"+name1.String()) require.Equal(t, 200, resp.StatusCode) @@ -212,7 +318,7 @@ func TestIPNS(t *testing.T) { t.Parallel() router := &mockContentRouter{} - router.On("ProvideIPNSRecord", mock.Anything, name1, record1).Return(nil) + router.On("PutIPNS", mock.Anything, name1, record1).Return(nil) server := httptest.NewServer(Handler(router)) t.Cleanup(server.Close) @@ -259,9 +365,9 @@ func TestIPNS(t *testing.T) { type mockContentRouter struct{ mock.Mock } -func (m *mockContentRouter) FindProviders(ctx context.Context, key cid.Cid, limit int) (iter.ResultIter[types.ProviderResponse], error) { +func (m *mockContentRouter) FindProviders(ctx context.Context, key cid.Cid, limit int) (iter.ResultIter[types.Record], error) { args := m.Called(ctx, key, limit) - return args.Get(0).(iter.ResultIter[types.ProviderResponse]), args.Error(1) + return args.Get(0).(iter.ResultIter[types.Record]), args.Error(1) } func (m *mockContentRouter) ProvideBitswap(ctx context.Context, req *BitswapWriteProvideRequest) (time.Duration, error) { @@ -269,17 +375,17 @@ func (m *mockContentRouter) ProvideBitswap(ctx context.Context, req *BitswapWrit return args.Get(0).(time.Duration), args.Error(1) } -func (m *mockContentRouter) Provide(ctx context.Context, req *WriteProvideRequest) (types.ProviderResponse, error) { - args := m.Called(ctx, req) - return args.Get(0).(types.ProviderResponse), args.Error(1) +func (m *mockContentRouter) FindPeers(ctx context.Context, pid peer.ID, limit int) (iter.ResultIter[types.Record], error) { + args := m.Called(ctx, pid, limit) + return args.Get(0).(iter.ResultIter[types.Record]), args.Error(1) } -func (m *mockContentRouter) FindIPNSRecord(ctx context.Context, name ipns.Name) (*ipns.Record, error) { +func (m *mockContentRouter) GetIPNS(ctx context.Context, name ipns.Name) (*ipns.Record, error) { args := m.Called(ctx, name) return args.Get(0).(*ipns.Record), args.Error(1) } -func (m *mockContentRouter) ProvideIPNSRecord(ctx context.Context, name ipns.Name, record *ipns.Record) error { +func (m *mockContentRouter) PutIPNS(ctx context.Context, name ipns.Name, record *ipns.Record) error { args := m.Called(ctx, name, record) return args.Error(0) } diff --git a/routing/http/types/iter/iter.go b/routing/http/types/iter/iter.go index 67c6dde00..2e9801d46 100644 --- a/routing/http/types/iter/iter.go +++ b/routing/http/types/iter/iter.go @@ -1,5 +1,7 @@ package iter +import "fmt" + // Iter is an iterator of arbitrary values. // Iterators are generally not goroutine-safe, to make them safe just read from them into a channel. // For our use cases, these usually have a single reader. This motivates iterators instead of channels, @@ -44,3 +46,21 @@ func ReadAll[T any](iter Iter[T]) []T { } return vs } + +func ReadAllResults[T any](iter ResultIter[T]) ([]T, error) { + var ( + vs []T + i int + ) + + for iter.Next() { + res := iter.Val() + if res.Err != nil { + return nil, fmt.Errorf("error on result %d: %w", i, res.Err) + } + vs = append(vs, res.Val) + i++ + } + + return vs, nil +} diff --git a/routing/http/types/json/provider.go b/routing/http/types/json/provider.go deleted file mode 100644 index 351197338..000000000 --- a/routing/http/types/json/provider.go +++ /dev/null @@ -1,116 +0,0 @@ -package json - -import ( - "encoding/json" - - "github.com/ipfs/boxo/routing/http/types" -) - -// ReadProvidersResponse is the result of a Provide request -type ReadProvidersResponse struct { - Providers []types.ProviderResponse -} - -func (r *ReadProvidersResponse) UnmarshalJSON(b []byte) error { - var tempFPR struct{ Providers []json.RawMessage } - err := json.Unmarshal(b, &tempFPR) - if err != nil { - return err - } - - for _, provBytes := range tempFPR.Providers { - var readProv types.UnknownProviderRecord - err := json.Unmarshal(provBytes, &readProv) - if err != nil { - return err - } - - switch readProv.Schema { - case types.SchemaBitswap: - var prov types.ReadBitswapProviderRecord - err := json.Unmarshal(readProv.Bytes, &prov) - if err != nil { - return err - } - r.Providers = append(r.Providers, &prov) - default: - r.Providers = append(r.Providers, &readProv) - } - - } - return nil -} - -type WriteProvidersRequest struct { - Providers []types.WriteProviderRecord -} - -func (r *WriteProvidersRequest) UnmarshalJSON(b []byte) error { - type wpr struct{ Providers []json.RawMessage } - var tempWPR wpr - err := json.Unmarshal(b, &tempWPR) - if err != nil { - return err - } - - for _, provBytes := range tempWPR.Providers { - var rawProv types.UnknownProviderRecord - err := json.Unmarshal(provBytes, &rawProv) - if err != nil { - return err - } - - switch rawProv.Schema { - case types.SchemaBitswap: - var prov types.WriteBitswapProviderRecord - err := json.Unmarshal(rawProv.Bytes, &prov) - if err != nil { - return err - } - r.Providers = append(r.Providers, &prov) - default: - var prov types.UnknownProviderRecord - err := json.Unmarshal(b, &prov) - if err != nil { - return err - } - r.Providers = append(r.Providers, &prov) - } - } - return nil -} - -// WriteProvidersResponse is the result of a Provide operation -type WriteProvidersResponse struct { - ProvideResults []types.ProviderResponse -} - -func (r *WriteProvidersResponse) UnmarshalJSON(b []byte) error { - var tempWPR struct{ ProvideResults []json.RawMessage } - err := json.Unmarshal(b, &tempWPR) - if err != nil { - return err - } - - for _, provBytes := range tempWPR.ProvideResults { - var rawProv types.UnknownProviderRecord - err := json.Unmarshal(provBytes, &rawProv) - if err != nil { - return err - } - - switch rawProv.Schema { - case types.SchemaBitswap: - var prov types.WriteBitswapProviderRecordResponse - err := json.Unmarshal(rawProv.Bytes, &prov) - if err != nil { - return err - } - r.ProvideResults = append(r.ProvideResults, &prov) - default: - r.ProvideResults = append(r.ProvideResults, &rawProv) - } - } - - return nil -} diff --git a/routing/http/types/json/requests.go b/routing/http/types/json/requests.go new file mode 100644 index 000000000..4b582c3ba --- /dev/null +++ b/routing/http/types/json/requests.go @@ -0,0 +1,51 @@ +package json + +import ( + "encoding/json" + + "github.com/ipfs/boxo/routing/http/types" +) + +// Deprecated: protocol-agnostic provide is being worked on in [IPIP-378]: +// +// [IPIP-378]: https://github.com/ipfs/specs/pull/378 +type WriteProvidersRequest struct { + Providers []types.Record +} + +func (r *WriteProvidersRequest) UnmarshalJSON(b []byte) error { + type wpr struct{ Providers []json.RawMessage } + var tempWPR wpr + err := json.Unmarshal(b, &tempWPR) + if err != nil { + return err + } + + for _, provBytes := range tempWPR.Providers { + var rawProv types.UnknownRecord + err := json.Unmarshal(provBytes, &rawProv) + if err != nil { + return err + } + + switch rawProv.Schema { + //lint:ignore SA1019 // ignore staticcheck + case types.SchemaBitswap: + //lint:ignore SA1019 // ignore staticcheck + var prov types.WriteBitswapRecord + err := json.Unmarshal(rawProv.Bytes, &prov) + if err != nil { + return err + } + r.Providers = append(r.Providers, &prov) + default: + var prov types.UnknownRecord + err := json.Unmarshal(b, &prov) + if err != nil { + return err + } + r.Providers = append(r.Providers, &prov) + } + } + return nil +} diff --git a/routing/http/types/json/responses.go b/routing/http/types/json/responses.go new file mode 100644 index 000000000..dfcfad830 --- /dev/null +++ b/routing/http/types/json/responses.go @@ -0,0 +1,98 @@ +package json + +import ( + "encoding/json" + + "github.com/ipfs/boxo/routing/http/types" +) + +// ProvidersResponse is the result of a GET Providers request. +type ProvidersResponse struct { + Providers RecordsArray +} + +// PeersResponse is the result of a GET Peers request. +type PeersResponse struct { + Peers RecordsArray +} + +// RecordsArray is an array of [types.Record] +type RecordsArray []types.Record + +func (r *RecordsArray) UnmarshalJSON(b []byte) error { + var tempRecords []json.RawMessage + err := json.Unmarshal(b, &tempRecords) + if err != nil { + return err + } + + for _, provBytes := range tempRecords { + var readProv types.UnknownRecord + err := json.Unmarshal(provBytes, &readProv) + if err != nil { + return err + } + + switch readProv.Schema { + case types.SchemaPeer: + var prov types.PeerRecord + err := json.Unmarshal(provBytes, &prov) + if err != nil { + return err + } + *r = append(*r, &prov) + //lint:ignore SA1019 // ignore staticcheck + case types.SchemaBitswap: + //lint:ignore SA1019 // ignore staticcheck + var prov types.BitswapRecord + err := json.Unmarshal(provBytes, &prov) + if err != nil { + return err + } + *r = append(*r, &prov) + default: + *r = append(*r, &readProv) + } + + } + return nil +} + +// Deprecated: protocol-agnostic provide is being worked on in [IPIP-378]: +// +// [IPIP-378]: https://github.com/ipfs/specs/pull/378 +type WriteProvidersResponse struct { + ProvideResults []types.Record +} + +func (r *WriteProvidersResponse) UnmarshalJSON(b []byte) error { + var tempWPR struct{ ProvideResults []json.RawMessage } + err := json.Unmarshal(b, &tempWPR) + if err != nil { + return err + } + + for _, provBytes := range tempWPR.ProvideResults { + var rawProv types.UnknownRecord + err := json.Unmarshal(provBytes, &rawProv) + if err != nil { + return err + } + + switch rawProv.Schema { + //lint:ignore SA1019 // ignore staticcheck + case types.SchemaBitswap: + //lint:ignore SA1019 // ignore staticcheck + var prov types.WriteBitswapRecordResponse + err := json.Unmarshal(rawProv.Bytes, &prov) + if err != nil { + return err + } + r.ProvideResults = append(r.ProvideResults, &prov) + default: + r.ProvideResults = append(r.ProvideResults, &rawProv) + } + } + + return nil +} diff --git a/routing/http/types/ndjson/provider.go b/routing/http/types/ndjson/provider.go deleted file mode 100644 index 38e28df9a..000000000 --- a/routing/http/types/ndjson/provider.go +++ /dev/null @@ -1,36 +0,0 @@ -package ndjson - -import ( - "encoding/json" - "io" - - "github.com/ipfs/boxo/routing/http/types" - "github.com/ipfs/boxo/routing/http/types/iter" -) - -// NewReadProvidersResponseIter returns an iterator that reads Read Provider Records from the given reader. -func NewReadProvidersResponseIter(r io.Reader) iter.Iter[iter.Result[types.ProviderResponse]] { - jsonIter := iter.FromReaderJSON[types.UnknownProviderRecord](r) - mapFn := func(upr iter.Result[types.UnknownProviderRecord]) iter.Result[types.ProviderResponse] { - var result iter.Result[types.ProviderResponse] - if upr.Err != nil { - result.Err = upr.Err - return result - } - switch upr.Val.Schema { - case types.SchemaBitswap: - var prov types.ReadBitswapProviderRecord - err := json.Unmarshal(upr.Val.Bytes, &prov) - if err != nil { - result.Err = err - return result - } - result.Val = &prov - default: - result.Val = &upr.Val - } - return result - } - - return iter.Map[iter.Result[types.UnknownProviderRecord]](jsonIter, mapFn) -} diff --git a/routing/http/types/ndjson/records.go b/routing/http/types/ndjson/records.go new file mode 100644 index 000000000..d1a36b411 --- /dev/null +++ b/routing/http/types/ndjson/records.go @@ -0,0 +1,46 @@ +package ndjson + +import ( + "encoding/json" + "io" + + "github.com/ipfs/boxo/routing/http/types" + "github.com/ipfs/boxo/routing/http/types/iter" +) + +// NewRecordsIter returns an iterator that reads [types.Record] from the given [io.Reader]. +func NewRecordsIter(r io.Reader) iter.Iter[iter.Result[types.Record]] { + jsonIter := iter.FromReaderJSON[types.UnknownRecord](r) + mapFn := func(upr iter.Result[types.UnknownRecord]) iter.Result[types.Record] { + var result iter.Result[types.Record] + if upr.Err != nil { + result.Err = upr.Err + return result + } + switch upr.Val.Schema { + case types.SchemaPeer: + var prov types.PeerRecord + err := json.Unmarshal(upr.Val.Bytes, &prov) + if err != nil { + result.Err = err + return result + } + result.Val = &prov + //lint:ignore SA1019 // ignore staticcheck + case types.SchemaBitswap: + //lint:ignore SA1019 // ignore staticcheck + var prov types.BitswapRecord + err := json.Unmarshal(upr.Val.Bytes, &prov) + if err != nil { + result.Err = err + return result + } + result.Val = &prov + default: + result.Val = &upr.Val + } + return result + } + + return iter.Map[iter.Result[types.UnknownRecord]](jsonIter, mapFn) +} diff --git a/routing/http/types/provider.go b/routing/http/types/provider.go deleted file mode 100644 index 6e8e303f7..000000000 --- a/routing/http/types/provider.go +++ /dev/null @@ -1,17 +0,0 @@ -package types - -// WriteProviderRecord is a type that enforces structs to imlement it to avoid confusion -type WriteProviderRecord interface { - IsWriteProviderRecord() -} - -// ReadProviderRecord is a type that enforces structs to imlement it to avoid confusion -type ReadProviderRecord interface { - IsReadProviderRecord() -} - -// ProviderResponse is implemented for any ProviderResponse. It needs to have a Protocol field. -type ProviderResponse interface { - GetProtocol() string - GetSchema() string -} diff --git a/routing/http/types/provider_unknown.go b/routing/http/types/provider_unknown.go deleted file mode 100644 index 915cac481..000000000 --- a/routing/http/types/provider_unknown.go +++ /dev/null @@ -1,63 +0,0 @@ -package types - -import ( - "encoding/json" - - "github.com/ipfs/boxo/routing/http/internal/drjson" -) - -var ( - _ ReadProviderRecord = &UnknownProviderRecord{} - _ WriteProviderRecord = &UnknownProviderRecord{} - _ ProviderResponse = &UnknownProviderRecord{} -) - -// UnknownProviderRecord is used when we cannot parse the provider record using `GetProtocol` -type UnknownProviderRecord struct { - Protocol string - Schema string - Bytes []byte -} - -func (u *UnknownProviderRecord) GetProtocol() string { - return u.Protocol -} - -func (u *UnknownProviderRecord) GetSchema() string { - return u.Schema -} - -func (u *UnknownProviderRecord) IsReadProviderRecord() {} -func (u UnknownProviderRecord) IsWriteProviderRecord() {} - -func (u *UnknownProviderRecord) UnmarshalJSON(b []byte) error { - m := map[string]interface{}{} - if err := json.Unmarshal(b, &m); err != nil { - return err - } - - ps, ok := m["Protocol"].(string) - if ok { - u.Protocol = ps - } - schema, ok := m["Schema"].(string) - if ok { - u.Schema = schema - } - - u.Bytes = b - - return nil -} - -func (u UnknownProviderRecord) MarshalJSON() ([]byte, error) { - m := map[string]interface{}{} - err := json.Unmarshal(u.Bytes, &m) - if err != nil { - return nil, err - } - m["Protocol"] = u.Protocol - m["Schema"] = u.Schema - - return drjson.MarshalJSONBytes(m) -} diff --git a/routing/http/types/record.go b/routing/http/types/record.go new file mode 100644 index 000000000..4a734d5f5 --- /dev/null +++ b/routing/http/types/record.go @@ -0,0 +1,6 @@ +package types + +// Record is implemented for any record. +type Record interface { + GetSchema() string +} diff --git a/routing/http/types/provider_bitswap.go b/routing/http/types/record_bitswap.go similarity index 64% rename from routing/http/types/provider_bitswap.go rename to routing/http/types/record_bitswap.go index f0b5056e4..0780fc3eb 100644 --- a/routing/http/types/provider_bitswap.go +++ b/routing/http/types/record_bitswap.go @@ -12,14 +12,37 @@ import ( "github.com/multiformats/go-multibase" ) +// Deprecated: use the more versatile [SchemaPeer] instead. For more information, read [IPIP-417]. +// +// [IPIP-417]: https://github.com/ipfs/specs/pull/417 const SchemaBitswap = "bitswap" -var _ WriteProviderRecord = &WriteBitswapProviderRecord{} +var ( + _ Record = &BitswapRecord{} +) -// WriteBitswapProviderRecord is used when we want to add a new provider record that is using bitswap. -type WriteBitswapProviderRecord struct { - Protocol string +// Deprecated: use the more versatile [PeerRecord] instead. For more information, read [IPIP-417]. +// +// [IPIP-417]: https://github.com/ipfs/specs/pull/417 +type BitswapRecord struct { + Schema string + Protocol string + ID *peer.ID + Addrs []Multiaddr `json:",omitempty"` +} + +func (br *BitswapRecord) GetSchema() string { + return br.Schema +} + +var _ Record = &WriteBitswapRecord{} + +// Deprecated: protocol-agnostic provide is being worked on in [IPIP-378]: +// +// [IPIP-378]: https://github.com/ipfs/specs/pull/378 +type WriteBitswapRecord struct { Schema string + Protocol string Signature string // this content must be untouched because it is signed and we need to verify it @@ -35,11 +58,13 @@ type BitswapPayload struct { Addrs []Multiaddr } -func (*WriteBitswapProviderRecord) IsWriteProviderRecord() {} +func (wr *WriteBitswapRecord) GetSchema() string { + return wr.Schema +} -type tmpBWPR WriteBitswapProviderRecord +type tmpBWPR WriteBitswapRecord -func (p *WriteBitswapProviderRecord) UnmarshalJSON(b []byte) error { +func (p *WriteBitswapRecord) UnmarshalJSON(b []byte) error { var bwp tmpBWPR err := json.Unmarshal(b, &bwp) if err != nil { @@ -54,11 +79,11 @@ func (p *WriteBitswapProviderRecord) UnmarshalJSON(b []byte) error { return json.Unmarshal(bwp.RawPayload, &p.Payload) } -func (p *WriteBitswapProviderRecord) IsSigned() bool { +func (p *WriteBitswapRecord) IsSigned() bool { return p.Signature != "" } -func (p *WriteBitswapProviderRecord) setRawPayload() error { +func (p *WriteBitswapRecord) setRawPayload() error { payloadBytes, err := drjson.MarshalJSONBytes(p.Payload) if err != nil { return fmt.Errorf("marshaling bitswap write provider payload: %w", err) @@ -69,7 +94,7 @@ func (p *WriteBitswapProviderRecord) setRawPayload() error { return nil } -func (p *WriteBitswapProviderRecord) Sign(peerID peer.ID, key crypto.PrivKey) error { +func (p *WriteBitswapRecord) Sign(peerID peer.ID, key crypto.PrivKey) error { if p.IsSigned() { return errors.New("already signed") } @@ -105,7 +130,7 @@ func (p *WriteBitswapProviderRecord) Sign(peerID peer.ID, key crypto.PrivKey) er return nil } -func (p *WriteBitswapProviderRecord) Verify() error { +func (p *WriteBitswapRecord) Verify() error { if !p.IsSigned() { return errors.New("not signed") } @@ -145,42 +170,17 @@ func (p *WriteBitswapProviderRecord) Verify() error { return nil } -var _ ProviderResponse = &WriteBitswapProviderRecordResponse{} +var _ Record = &WriteBitswapRecordResponse{} -// WriteBitswapProviderRecordResponse will be returned as a result of WriteBitswapProviderRecord -type WriteBitswapProviderRecordResponse struct { - Protocol string +// Deprecated: protocol-agnostic provide is being worked on in [IPIP-378]: +// +// [IPIP-378]: https://github.com/ipfs/specs/pull/378 +type WriteBitswapRecordResponse struct { Schema string + Protocol string AdvisoryTTL *Duration } -func (wbprr *WriteBitswapProviderRecordResponse) GetProtocol() string { - return wbprr.Protocol +func (r *WriteBitswapRecordResponse) GetSchema() string { + return r.Schema } - -func (wbprr *WriteBitswapProviderRecordResponse) GetSchema() string { - return wbprr.Schema -} - -var ( - _ ReadProviderRecord = &ReadBitswapProviderRecord{} - _ ProviderResponse = &ReadBitswapProviderRecord{} -) - -// ReadBitswapProviderRecord is a provider result with parameters for bitswap providers -type ReadBitswapProviderRecord struct { - Protocol string - Schema string - ID *peer.ID - Addrs []Multiaddr -} - -func (rbpr *ReadBitswapProviderRecord) GetProtocol() string { - return rbpr.Protocol -} - -func (rbpr *ReadBitswapProviderRecord) GetSchema() string { - return rbpr.Schema -} - -func (*ReadBitswapProviderRecord) IsReadProviderRecord() {} diff --git a/routing/http/types/record_peer.go b/routing/http/types/record_peer.go new file mode 100644 index 000000000..76bd810e0 --- /dev/null +++ b/routing/http/types/record_peer.go @@ -0,0 +1,81 @@ +package types + +import ( + "encoding/json" + + "github.com/ipfs/boxo/routing/http/internal/drjson" + "github.com/libp2p/go-libp2p/core/peer" +) + +const SchemaPeer = "peer" + +var _ Record = &PeerRecord{} + +type PeerRecord struct { + Schema string + ID *peer.ID + Addrs []Multiaddr + Protocols []string + + // Extra contains extra fields that were included in the original JSON raw + // message, except for the known ones represented by the remaining fields. + Extra map[string]json.RawMessage +} + +func (pr *PeerRecord) GetSchema() string { + return pr.Schema +} + +func (pr *PeerRecord) UnmarshalJSON(b []byte) error { + // Unmarshal all known fields and assign them. + v := struct { + Schema string + ID *peer.ID + Addrs []Multiaddr + Protocols []string + }{} + err := json.Unmarshal(b, &v) + if err != nil { + return err + } + pr.Schema = v.Schema + pr.ID = v.ID + pr.Addrs = v.Addrs + pr.Protocols = v.Protocols + + // Unmarshal everything into the Extra field and remove the + // known fields to avoid conflictual usages of the struct. + err = json.Unmarshal(b, &pr.Extra) + if err != nil { + return err + } + delete(pr.Extra, "Schema") + delete(pr.Extra, "ID") + delete(pr.Extra, "Addrs") + delete(pr.Extra, "Protocols") + + return nil +} + +func (pr PeerRecord) MarshalJSON() ([]byte, error) { + m := map[string]interface{}{} + if pr.Extra != nil { + for key, val := range pr.Extra { + m[key] = val + } + } + + // Schema and ID must always be set. + m["Schema"] = pr.Schema + m["ID"] = pr.ID + + if pr.Addrs != nil { + m["Addrs"] = pr.Addrs + } + + if pr.Protocols != nil { + m["Protocols"] = pr.Protocols + } + + return drjson.MarshalJSONBytes(m) +} diff --git a/routing/http/types/record_unknown.go b/routing/http/types/record_unknown.go new file mode 100644 index 000000000..9b2f6f960 --- /dev/null +++ b/routing/http/types/record_unknown.go @@ -0,0 +1,47 @@ +package types + +import ( + "encoding/json" + + "github.com/ipfs/boxo/routing/http/internal/drjson" +) + +var _ Record = &UnknownRecord{} + +type UnknownRecord struct { + Schema string + + // Bytes contains the raw JSON bytes that were used to unmarshal this record. + // This value can be used, for example, to unmarshal de record into a different + // type if Schema is of a known value. + Bytes []byte +} + +func (ur *UnknownRecord) GetSchema() string { + return ur.Schema +} + +func (ur *UnknownRecord) UnmarshalJSON(b []byte) error { + v := struct { + Schema string + }{} + err := json.Unmarshal(b, &v) + if err != nil { + return err + } + ur.Schema = v.Schema + ur.Bytes = b + return nil +} + +func (ur UnknownRecord) MarshalJSON() ([]byte, error) { + m := map[string]interface{}{} + if ur.Bytes != nil { + err := json.Unmarshal(ur.Bytes, &m) + if err != nil { + return nil, err + } + } + m["Schema"] = ur.Schema + return drjson.MarshalJSONBytes(m) +} From 574df963653c940ea19b1b8a0d37cd30360c22e9 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Tue, 5 Sep 2023 09:30:37 +0200 Subject: [PATCH 035/312] ci: remove obsolete protocol/cache-go-action (#460) --- .github/workflows/gateway-sharness.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/gateway-sharness.yml b/.github/workflows/gateway-sharness.yml index f362ab994..72c36a26c 100644 --- a/.github/workflows/gateway-sharness.yml +++ b/.github/workflows/gateway-sharness.yml @@ -16,7 +16,7 @@ jobs: shell: bash steps: - name: Setup Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: go-version: 1.19.1 - name: Checkout boxo @@ -30,10 +30,6 @@ jobs: path: kubo - name: Install Missing Tools run: sudo apt install -y socat net-tools fish libxml2-utils - - name: Restore Go Cache - uses: protocol/cache-go-action@v1 - with: - name: ${{ github.job }} - name: Replace boxo in Kubo go.mod run: | go mod edit -replace=github.com/ipfs/boxo=../boxo From 68914ea368f4645de1cf6365a6948112b92c408d Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 19 Sep 2023 12:43:29 +0200 Subject: [PATCH 036/312] fix(gateway): normalization of DNSLink inlining (#462) Co-authored-by: Henrique Dias --- .github/workflows/gateway-conformance.yml | 2 +- .github/workflows/gateway-sharness.yml | 2 +- CHANGELOG.md | 3 ++ gateway/hostname.go | 43 +++++++++++++++-------- gateway/hostname_test.go | 5 ++- 5 files changed, 37 insertions(+), 18 deletions(-) diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index 61471c015..a2a3734f6 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -25,7 +25,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v3 with: - go-version: 1.19.x + go-version: 1.21.x - name: Checkout boxo uses: actions/checkout@v3 with: diff --git a/.github/workflows/gateway-sharness.yml b/.github/workflows/gateway-sharness.yml index 72c36a26c..25daf6141 100644 --- a/.github/workflows/gateway-sharness.yml +++ b/.github/workflows/gateway-sharness.yml @@ -18,7 +18,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v4 with: - go-version: 1.19.1 + go-version: 1.21.x - name: Checkout boxo uses: actions/checkout@v3 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a4122902..b11a4165e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,9 @@ The following emojis are used to highlight certain changes: ### Fixed +* The normalization of DNSLink identifiers in `gateway` has been corrected in the edge + case where the value passed to the path component of the URL is already normalized. + ### Security ## [v0.12.0] diff --git a/gateway/hostname.go b/gateway/hostname.go index 0bf6b4d72..758d8499c 100644 --- a/gateway/hostname.go +++ b/gateway/hostname.go @@ -300,7 +300,7 @@ func isHTTPSRequest(r *http.Request) bool { // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto xproto := r.Header.Get("X-Forwarded-Proto") // Is request a native TLS (not used atm, but future-proofing) - // or a proxied HTTPS (eg. go-ipfs behind nginx at a public gw)? + // or a proxied HTTPS (eg. Kubo behind nginx at a public gw)? return r.URL.Scheme == "https" || xproto == "https" } @@ -396,27 +396,40 @@ func toSubdomainURL(hostname, path string, r *http.Request, inlineDNSLink bool, } } else { // rootID is not a CID - // Check if rootID is a FQDN with DNSLink and convert it to TLS-safe - // representation that fits in a single DNS label. We support this so - // loading DNSLink names over TLS "just works" on public HTTP gateways - // that pass 'https' in X-Forwarded-Proto to go-ipfs. - // - // Rationale can be found under "Option C" - // at: https://github.com/ipfs/in-web-browsers/issues/169 - // - // TLDR is: - // /ipns/my.v-long.example.com - // can be loaded from a subdomain gateway with a wildcard TLS cert if - // represented as a single DNS label: - // https://my-v--long-example-com.ipns.dweb.link + // If rootID is an inlined notation of a FQDN with DNSLink we need to + // un-inline it first, to make it work in contexts where subdomain + // identifier is used on a path (/ipns/my-v--long-example-com) + // e.g. when ipfs-companion extension passes value from subdomain gateway + // for further normalization: https://github.com/ipfs/ipfs-companion/issues/1278#issuecomment-1724550623 + if ns == "ipns" && !strings.Contains(rootID, ".") && strings.Contains(rootID, "-") { + dnsLinkFqdn := toDNSLinkFQDN(rootID) // my-v--long-example-com → my.v-long.example.com + if hasDNSLinkRecord(r.Context(), backend, dnsLinkFqdn) { + // update path prefix to use real FQDN with DNSLink + rootID = dnsLinkFqdn + } + } + if (inlineDNSLink || isHTTPS) && ns == "ipns" && strings.Contains(rootID, ".") { + // If rootID is a FQDN with DNSLink we need to inline it to make it TLS-safe + // representation that fits in a single DNS label. We support this so + // loading DNSLink names over TLS "just works" on public HTTP gateways + // that pass 'https' in X-Forwarded-Proto to Kubo. + // + // Rationale can be found under "Option C" + // at: https://github.com/ipfs/in-web-browsers/issues/169 + // + // TLDR is: + // /ipns/my.v-long.example.com + // can be loaded from a subdomain gateway with a wildcard TLS cert if + // represented as a single DNS label: + // https://my-v--long-example-com.ipns.dweb.link if hasDNSLinkRecord(r.Context(), backend, rootID) { // my.v-long.example.com → my-v--long-example-com dnsLabel, err := toDNSLinkDNSLabel(rootID) if err != nil { return "", err } - // update path prefix to use real FQDN with DNSLink + // update path prefix to use inlined FQDN with DNSLink as a single DNS label rootID = dnsLabel } } else if ns == "ipfs" { diff --git a/gateway/hostname_test.go b/gateway/hostname_test.go index a58e0d404..f7cee35a2 100644 --- a/gateway/hostname_test.go +++ b/gateway/hostname_test.go @@ -55,9 +55,12 @@ func TestToSubdomainURL(t *testing.T) { {httpRequest, "dweb.link", false, "/ipns/dnslink.long-name.example.com", "http://dnslink.long-name.example.com.ipns.dweb.link/", nil}, {httpsRequest, "dweb.link", false, "/ipns/dnslink.long-name.example.com", "https://dnslink-long--name-example-com.ipns.dweb.link/", nil}, {httpsProxiedRequest, "dweb.link", false, "/ipns/dnslink.long-name.example.com", "https://dnslink-long--name-example-com.ipns.dweb.link/", nil}, - // HTTP requests can also be converted to fit into a single DNS label - https://github.com/ipfs/kubo/issues/9243 + // Enabling DNS label inlining: HTTP requests can also be converted to fit into a single DNS label when it matters - https://github.com/ipfs/kubo/issues/9243 {httpRequest, "localhost", true, "/ipns/dnslink.long-name.example.com", "http://dnslink-long--name-example-com.ipns.localhost/", nil}, {httpRequest, "dweb.link", true, "/ipns/dnslink.long-name.example.com", "http://dnslink-long--name-example-com.ipns.dweb.link/", nil}, + // Disabling DNS label inlining: should un-inline any inlined DNS labels put in a path + {httpRequest, "localhost", false, "/ipns/dnslink-long--name-example-com", "http://dnslink.long-name.example.com.ipns.localhost/", nil}, + {httpRequest, "dweb.link", false, "/ipns/dnslink-long--name-example-com", "http://dnslink.long-name.example.com.ipns.dweb.link/", nil}, // Correctly redirects paths when there is a ? (question mark) character - https://github.com/ipfs/kubo/issues/9882 {httpRequest, "localhost", false, "/ipns/example.com/this is a file with some spaces . dots and - but also a ?.png", "http://example.com.ipns.localhost/this%20is%20a%20file%20with%20some%20spaces%20.%20dots%20and%20-%20but%20also%20a%20%3F.png", nil}, {httpRequest, "localhost", false, "/ipfs/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n/this is a file with some spaces . dots and - but also a ?.png", "http://bafybeif7a7gdklt6hodwdrmwmxnhksctcuav6lfxlcyfz4khzl3qfmvcgu.ipfs.localhost/this%20is%20a%20file%20with%20some%20spaces%20.%20dots%20and%20-%20but%20also%20a%20%3F.png", nil}, From 857bb53200243e54c82f989d6a969f6e4a8386d4 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 20 Sep 2023 08:15:38 +0200 Subject: [PATCH 037/312] docs: update changelog for v0.13.0 --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b11a4165e..0f35bfc66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,18 @@ The following emojis are used to highlight certain changes: ### Added +### Changed + +### Removed + +### Fixed + +### Security + +## [v0.13.0] + +### Added + * ✨ The `routing/http` implements Delegated Peer Routing introduced in [IPIP-417](https://github.com/ipfs/specs/pull/417). ### Changed From f0ff3ce58775c7bc957584d1bd8e464c2e8677a9 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 20 Sep 2023 08:46:37 +0200 Subject: [PATCH 038/312] chore: bump to v0.13.0 --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index 21e148a94..d3f796811 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "v0.12.0" + "version": "v0.13.0" } From 0d1016971811530b3f76f7740e0681673e011451 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 21 Sep 2023 13:34:13 +0200 Subject: [PATCH 039/312] fix(gateway): ipfs install link website changed, this should be more future-proof --- gateway/assets/header.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gateway/assets/header.html b/gateway/assets/header.html index 7f144e14e..6753fe6b4 100644 --- a/gateway/assets/header.html +++ b/gateway/assets/header.html @@ -2,7 +2,7 @@