From 00b54cc812389ea16aa5f7884d578688145d380c Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Fri, 16 Jun 2023 14:19:00 +1000 Subject: [PATCH] feat: remove unixfs-preload use --- go.mod | 5 + go.sum | 12 +- pkg/internal/itest/testpeer/generator.go | 4 +- pkg/internal/testutil/toblocks.go | 3 +- pkg/retriever/bitswapretriever.go | 5 +- pkg/verifiedcar/verifiedcar.go | 157 ++++++++++++++--------- pkg/verifiedcar/verifiedcar_test.go | 22 +++- 7 files changed, 129 insertions(+), 79 deletions(-) diff --git a/go.mod b/go.mod index e647c2d4..171a3611 100644 --- a/go.mod +++ b/go.mod @@ -21,6 +21,7 @@ require ( github.com/ipfs/go-ipfs-delay v0.0.1 github.com/ipfs/go-ipfs-exchange-interface v0.2.0 github.com/ipfs/go-ipld-format v0.5.0 + github.com/ipfs/go-libipfs v0.6.0 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-unixfsnode v1.7.1 github.com/ipld/go-car/v2 v2.10.1 @@ -166,3 +167,7 @@ require ( lukechampine.com/blake3 v1.1.7 // indirect nhooyr.io/websocket v1.8.7 // indirect ) + +replace github.com/ipfs/go-unixfsnode => ../../ipfs/go-unixfsnode + +replace github.com/ipld/go-ipld-prime => ../../ipld/go-ipld-prime diff --git a/go.sum b/go.sum index 88cf9a7c..c2e72b7c 100644 --- a/go.sum +++ b/go.sum @@ -126,7 +126,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.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= @@ -292,10 +292,11 @@ github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNo github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= github.com/ipfs/go-ipfs-exchange-interface v0.2.0/go.mod h1:z6+RhJuDQbqKguVyslSOuVDhqF9JtTrO3eptSAiW2/Y= github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= -github.com/ipfs/go-ipfs-files v0.0.8 h1:8o0oFJkJ8UkO/ABl8T6ac6tKF3+NIpj67aAB6ZpusRg= +github.com/ipfs/go-ipfs-files v0.3.0 h1:fallckyc5PYjuMEitPNrjRfpwl7YFt69heCOUhsbGxQ= github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= +github.com/ipfs/go-ipfs-routing v0.3.0 h1:9W/W3N+g+y4ZDeffSgqhgo7BsBSJwPMcyssET9OWevc= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= @@ -311,6 +312,7 @@ github.com/ipfs/go-ipld-format v0.5.0 h1:WyEle9K96MSrvr47zZHKKcDxJ/vlpET6PSiQsAF github.com/ipfs/go-ipld-format v0.5.0/go.mod h1:ImdZqJQaEouMjCvqCe0ORUS+uoBmf7Hf+EO/jh+nk3M= github.com/ipfs/go-ipld-legacy v0.2.1 h1:mDFtrBpmU7b//LzLSypVrXsD8QxkEWxu5qVxN99/+tk= github.com/ipfs/go-libipfs v0.6.0 h1:3FuckAJEm+zdHbHbf6lAyk0QUzc45LsFcGw102oBCZM= +github.com/ipfs/go-libipfs v0.6.0/go.mod h1:UjjDIuehp2GzlNP0HEr5I9GfFT7zWgst+YfpUEIThtw= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.0/go.mod h1:JO7RzlMK6rA+CIxFMLOuB6Wf5b81GDiKElL7UPSIKjA= github.com/ipfs/go-log v1.0.1/go.mod h1:HuWlQttfN6FWNHRhlY5yMk/lW7evQC0HHGOxEwMRR8I= @@ -329,15 +331,11 @@ github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= -github.com/ipfs/go-unixfsnode v1.7.1 h1:RRxO2b6CSr5UQ/kxnGzaChTjp5LWTdf3Y4n8ANZgB/s= -github.com/ipfs/go-unixfsnode v1.7.1/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipld/go-car/v2 v2.10.1 h1:MRDqkONNW9WRhB79u+Z3U5b+NoN7lYA5B8n8qI3+BoI= github.com/ipld/go-car/v2 v2.10.1/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.1-0.20230329011551-5056175565b0 h1:iJTl9tx5DEsnKpppX5PmfdoQ3ITuBmkh3yyEpHWY2SI= -github.com/ipld/go-ipld-prime v0.20.1-0.20230329011551-5056175565b0/go.mod h1:wmOtdy70ajP48iZITH8uLsGJVMqA4EJM61/bSfYYGhs= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= github.com/ipni/go-libipni v0.0.8-0.20230425184153-86a1fcb7f7ff h1:xbKrIvnpQkbF8iHPk/HGcegsypCDpcXWHhzBCLyCWf8= github.com/ipni/go-libipni v0.0.8-0.20230425184153-86a1fcb7f7ff/go.mod h1:paYP9U4N3/vOzGCuN9kU972vtvw9JUcQjOKyiCFGwRk= @@ -616,7 +614,7 @@ github.com/urfave/cli/v2 v2.24.4 h1:0gyJJEBYtCV87zI/x2nZCPyDxD51K6xM8SkwjHFCNEU= github.com/urfave/cli/v2 v2.24.4/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= 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-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= diff --git a/pkg/internal/itest/testpeer/generator.go b/pkg/internal/itest/testpeer/generator.go index c5db167a..a30bc2f5 100644 --- a/pkg/internal/itest/testpeer/generator.go +++ b/pkg/internal/itest/testpeer/generator.go @@ -451,7 +451,7 @@ func MockIpfsHandler(ctx context.Context, lsys linking.LinkSystem) func(http.Res } progress := traversal.Progress{Cfg: cfg} - err = progress.WalkAdv(rootNode, sel, visitNoop) + err = progress.WalkMatching(rootNode, sel, unixfsnode.BytesConsumingMatcher) if err != nil { // if we loaded the first block, we can't write headers any more return @@ -482,5 +482,3 @@ func RandTestPeerIdentity() (tnet.Identity, error) { } return nil, errors.New("failed to find an available port") } - -func visitNoop(p traversal.Progress, n datamodel.Node, vr traversal.VisitReason) error { return nil } diff --git a/pkg/internal/testutil/toblocks.go b/pkg/internal/testutil/toblocks.go index bbc43927..81061f8e 100644 --- a/pkg/internal/testutil/toblocks.go +++ b/pkg/internal/testutil/toblocks.go @@ -53,8 +53,7 @@ func ToBlocks(t *testing.T, lsys linking.LinkSystem, root cid.Cid, selNode datam LinkTargetNodePrototypeChooser: dagpb.AddSupportToChooser(basicnode.Chooser), }, } - vf := func(p traversal.Progress, n datamodel.Node, vr traversal.VisitReason) error { return nil } - err = prog.WalkAdv(rootNode, sel, vf) + err = prog.WalkMatching(rootNode, sel, unixfsnode.BytesConsumingMatcher) require.NoError(t, err) return traversedBlocks diff --git a/pkg/retriever/bitswapretriever.go b/pkg/retriever/bitswapretriever.go index 75dd3ae7..b66d9d38 100644 --- a/pkg/retriever/bitswapretriever.go +++ b/pkg/retriever/bitswapretriever.go @@ -18,6 +18,9 @@ import ( "github.com/ipfs/boxo/bitswap/network" "github.com/ipfs/boxo/blockservice" "github.com/ipfs/go-cid" + "github.com/ipfs/go-libipfs/bitswap/client" + "github.com/ipfs/go-libipfs/bitswap/network" + "github.com/ipfs/go-unixfsnode" dagpb "github.com/ipld/go-codec-dagpb" "github.com/ipld/go-ipld-prime/datamodel" "github.com/ipld/go-ipld-prime/linking" @@ -342,5 +345,5 @@ func easyTraverse( if err != nil { return err } - return progress.WalkAdv(node, compiledSelector, func(prog traversal.Progress, n datamodel.Node, reason traversal.VisitReason) error { return nil }) + return progress.WalkMatching(node, compiledSelector, unixfsnode.BytesConsumingMatcher) } diff --git a/pkg/verifiedcar/verifiedcar.go b/pkg/verifiedcar/verifiedcar.go index 34acdd30..9d7affeb 100644 --- a/pkg/verifiedcar/verifiedcar.go +++ b/pkg/verifiedcar/verifiedcar.go @@ -91,7 +91,6 @@ func (cfg Config) VerifyCar(ctx context.Context, rdr io.Reader, lsys linking.Lin } func (cfg Config) VerifyBlockStream(ctx context.Context, cbr BlockReader, lsys linking.LinkSystem) (uint64, uint64, error) { - sel, err := selector.CompileSelector(cfg.Selector) if err != nil { return 0, 0, err @@ -104,7 +103,8 @@ func (cfg Config) VerifyBlockStream(ctx context.Context, cbr BlockReader, lsys l lsys.TrustedStorage = true // we can rely on the CAR decoder to check CID integrity unixfsnode.AddUnixFSReificationToLinkSystem(&lsys) - lsys.StorageReadOpener = cfg.nextBlockReadOpener(ctx, cr, bt, lsys) + vro := newVerifyingReadOpener(ctx, cfg, cr, bt, lsys) + lsys.StorageReadOpener = vro.StorageReadOpener // run traversal in this goroutine progress := traversal.Progress{ @@ -120,27 +120,13 @@ func (cfg Config) VerifyBlockStream(ctx context.Context, cbr BlockReader, lsys l NodeBudget: math.MaxInt64, } } - lc := linking.LinkContext{Ctx: ctx} - lnk := cidlink.Link{Cid: cfg.Root} - proto, err := protoChooser(lnk, lc) - if err != nil { - return 0, 0, err - } - rootNode, err := lsys.Load(lc, lnk, proto) + + rootNode, err := loadNode(ctx, cfg.Root, lsys) if err != nil { - return 0, 0, err + return 0, 0, fmt.Errorf("failed to load root node: %w", err) } - if err := progress.WalkMatching(rootNode, sel, func(p traversal.Progress, n datamodel.Node) error { - if lbn, ok := n.(datamodel.LargeBytesNode); ok { - rdr, err := lbn.AsLargeBytes() - if err != nil { - return err - } - _, err = io.Copy(io.Discard, rdr) - return err - } - return nil - }); err != nil { + // if err := progress.WalkAdv(rootNode, sel, visitNoop); err != nil { + if err := progress.WalkMatching(rootNode, sel, unixfsnode.BytesConsumingMatcher); err != nil { return 0, 0, traversalError(err) } @@ -150,62 +136,107 @@ func (cfg Config) VerifyBlockStream(ctx context.Context, cbr BlockReader, lsys l return 0, 0, ErrExtraneousBlock } + if vro.err != nil { + return 0, 0, fmt.Errorf("block load failed during traversal: %w", vro.err) + } + // wait for parser to finish and provide errors or stats return bt.blocks, bt.bytes, nil } -func (cfg *Config) nextBlockReadOpener(ctx context.Context, cr *carReader, bt *writeTracker, lsys linking.LinkSystem) linking.BlockReadOpener { - seen := make(map[cid.Cid]struct{}) - return func(lc linking.LinkContext, l datamodel.Link) (io.Reader, error) { - cid := l.(cidlink.Link).Cid - - var data []byte - var err error - if _, ok := seen[cid]; ok { - if cfg.ExpectDuplicatesIn { - // duplicate block, but in this case we are expecting the stream to have it - data, err = cr.readNextBlock(ctx, cid) - if err != nil { - return nil, err - } - if !cfg.WriteDuplicatesOut { - return bytes.NewReader(data), nil - } - } else { - // duplicate block, rely on the supplied LinkSystem to have stored this - rdr, err := lsys.StorageReadOpener(lc, l) - if !cfg.WriteDuplicatesOut { - return rdr, err - } - data, err = io.ReadAll(rdr) - if err != nil { - return nil, err - } +func loadNode(ctx context.Context, rootCid cid.Cid, lsys linking.LinkSystem) (datamodel.Node, error) { + lnk := cidlink.Link{Cid: rootCid} + lnkCtx := linking.LinkContext{Ctx: ctx} + proto, err := protoChooser(lnk, lnkCtx) + if err != nil { + return nil, fmt.Errorf("failed to choose prototype for CID %s: %w", rootCid.String(), err) + } + rootNode, err := lsys.Load(lnkCtx, lnk, proto) + if err != nil { + return nil, fmt.Errorf("failed to load root CID: %w", err) + } + return rootNode, nil +} + +type verifyingReadOpener struct { + ctx context.Context + cfg Config + cr *carReader + bt *writeTracker + lsys linking.LinkSystem + + seen map[cid.Cid]struct{} + err error +} + +func newVerifyingReadOpener(ctx context.Context, cfg Config, cr *carReader, bt *writeTracker, lsys linking.LinkSystem) *verifyingReadOpener { + return &verifyingReadOpener{ + ctx: ctx, + cfg: cfg, + cr: cr, + bt: bt, + lsys: lsys, + seen: make(map[cid.Cid]struct{}), + } +} + +func (vro *verifyingReadOpener) StorageReadOpener(lc linking.LinkContext, l datamodel.Link) (io.Reader, error) { + cid := l.(cidlink.Link).Cid + + var data []byte + var err error + if _, ok := vro.seen[cid]; ok { + if vro.cfg.ExpectDuplicatesIn { + // duplicate block, but in this case we are expecting the stream to have it + data, err = vro.cr.readNextBlock(vro.ctx, cid) + if err != nil { + vro.err = err + return nil, err + } + if !vro.cfg.WriteDuplicatesOut { + return bytes.NewReader(data), nil } } else { - seen[cid] = struct{}{} - data, err = cr.readNextBlock(ctx, cid) + // duplicate block, rely on the supplied LinkSystem to have stored this + rdr, err := vro.lsys.StorageReadOpener(lc, l) + if !vro.cfg.WriteDuplicatesOut { + vro.err = err + return rdr, err + } + data, err = io.ReadAll(rdr) if err != nil { + vro.err = err return nil, err } } - bt.recordBlock(data) - w, wc, err := lsys.StorageWriteOpener(lc) + } else { + vro.seen[cid] = struct{}{} + data, err = vro.cr.readNextBlock(vro.ctx, cid) if err != nil { + vro.err = err return nil, err } - rdr := bytes.NewReader(data) - if _, err := io.Copy(w, rdr); err != nil { - return nil, err - } - if err := wc(l); err != nil { - return nil, err - } - if _, err := rdr.Seek(0, io.SeekStart); err != nil { - return nil, err - } - return io.NopCloser(rdr), nil } + vro.bt.recordBlock(data) + w, wc, err := vro.lsys.StorageWriteOpener(lc) + if err != nil { + vro.err = err + return nil, err + } + rdr := bytes.NewReader(data) + if _, err := io.Copy(w, rdr); err != nil { + vro.err = err + return nil, err + } + if err := wc(l); err != nil { + vro.err = err + return nil, err + } + if _, err := rdr.Seek(0, io.SeekStart); err != nil { + vro.err = err + return nil, err + } + return io.NopCloser(rdr), nil } type carReader struct { diff --git a/pkg/verifiedcar/verifiedcar_test.go b/pkg/verifiedcar/verifiedcar_test.go index 51a949cf..42c152d4 100644 --- a/pkg/verifiedcar/verifiedcar_test.go +++ b/pkg/verifiedcar/verifiedcar_test.go @@ -24,6 +24,7 @@ import ( "github.com/ipld/go-ipld-prime/node/basicnode" "github.com/ipld/go-ipld-prime/storage/memstore" "github.com/ipld/go-ipld-prime/traversal" + "github.com/ipld/go-ipld-prime/traversal/selector" "github.com/ipld/go-ipld-prime/traversal/selector/builder" selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse" "github.com/stretchr/testify/require" @@ -86,7 +87,13 @@ func TestVerifiedCar(t *testing.T) { } } - unixfsShardedDir := testutil.GenerateNoDupes(func() unixfs.DirEntry { return unixfs.GenerateDirectory(t, &lsys, rndReader, 8<<20, true) }) + var unixfsShardedDir unixfs.DirEntry + for { + unixfsShardedDir = testutil.GenerateNoDupes(func() unixfs.DirEntry { return unixfs.GenerateDirectory(t, &lsys, rndReader, 8<<20, true) }) + if len(unixfsShardedDir.SelfCids) >= 4 { // we want an _actual_ sharded directory + break + } + } unixfsShardedDirBlocks := testutil.ToBlocks(t, lsys, unixfsShardedDir.Root, allSelector) unixfsPreloadSelector := unixfsnode.MatchUnixFSPreloadSelector.Node() @@ -98,6 +105,11 @@ func TestVerifiedCar(t *testing.T) { unixfsWrappedPathSelector := unixfsnode.UnixFSPathSelectorBuilder(wrapPath, unixfsnode.ExploreAllRecursivelySelector, false) unixfsWrappedPreloadPathSelector := unixfsnode.UnixFSPathSelectorBuilder(wrapPath, unixfsnode.MatchUnixFSPreloadSelector, false) + preloadSubst := ssb.ExploreInterpretAs("unixfs", ssb.ExploreRecursive( + selector.RecursionLimitDepth(1), + ssb.ExploreAll(ssb.ExploreRecursiveEdge()), + )) + unixfsWrappedPreloadPathSelectorSubst := unixfsnode.UnixFSPathSelectorBuilder(wrapPath, preloadSubst, false) unixfsWrappedFile := testutil.GenerateNoDupes(func() unixfs.DirEntry { return unixfs.WrapContent(t, rndReader, &lsys, unixfsFile, wrapPath, false) }) unixfsWrappedFileBlocks := testutil.ToBlocks(t, lsys, unixfsWrappedFile.Root, allSelector) @@ -124,6 +136,7 @@ func TestVerifiedCar(t *testing.T) { mismatchedCidBlk, _ := blocks.NewBlockWithCid(extraneousByts, allBlocks[99].Cid()) testCases := []struct { name string + skip bool blocks []expectedBlock roots []cid.Cid carv2 bool @@ -304,7 +317,7 @@ func TestVerifiedCar(t *testing.T) { name: "unixfs: all of large sharded directory with file scope, errors", blocks: consumedBlocks(unixfsShardedDirBlocks), roots: []cid.Cid{unixfsShardedDir.Root}, - err: "extraneous block in CAR", + err: "unexpected block in CAR", cfg: verifiedcar.Config{ Root: unixfsShardedDir.Root, Selector: unixfsPreloadSelector, @@ -449,7 +462,7 @@ func TestVerifiedCar(t *testing.T) { roots: []cid.Cid{unixfsExclusiveWrappedShardedDir.Root}, cfg: verifiedcar.Config{ Root: unixfsExclusiveWrappedShardedDir.Root, - Selector: unixfsWrappedPreloadPathSelector, + Selector: unixfsWrappedPreloadPathSelectorSubst, }, }, { @@ -528,6 +541,9 @@ func TestVerifiedCar(t *testing.T) { for _, testCase := range testCases { testCase := testCase t.Run(testCase.name, func(t *testing.T) { + if testCase.skip { + t.Skip() + } t.Parallel() ctx, cancel := context.WithTimeout(ctx, 2*time.Second)