@cryptotaxi247 / kubo / commits / e7ca9554d

Add ability to retrieve blocks even if given using a different CID version.

This is done via a wrapper blockstore. License: MIT Signed-off-by: Kevin Atkinson <k@kevina.org>

Kevin Atkinson committed Aug 6, 2018 at 22:12 UTC e7ca9554d06b6ddcee776359edee665f5188ab50
3 files changed +203
core/builder.go
+3
@@ -13,6 +13,7 @@ import (
13 pin "github.com/ipfs/go-ipfs/pin"
14 repo "github.com/ipfs/go-ipfs/repo"
15 cfg "github.com/ipfs/go-ipfs/repo/config"
16 + cidv0v1 "github.com/ipfs/go-ipfs/thirdparty/cidv0v1"
17 "github.com/ipfs/go-ipfs/thirdparty/verifbs"
18 uio "gx/ipfs/QmWdTRLi3H7ZJQ8s7NYo8oitz5JHEEPKLn1QPMsJVWg2Ew/go-unixfs/io"
19 dag "gx/ipfs/Qma2BR57Wqp8w9vPreK4dEzoXXk8DFFRL3LresMZg4QpzN/go-merkledag"
@@ -211,6 +212,8 @@ func setupNode(ctx context.Context, n *IpfsNode, cfg *BuildCfg) error {
212
213 wbs = bstore.NewIdStore(wbs)
214
215 + wbs = cidv0v1.NewBlockstore(wbs)
216 +
217 n.BaseBlocks = wbs
218 n.GCLocker = bstore.NewGCLocker()
219 n.Blockstore = bstore.NewGCBlockstore(wbs, n.GCLocker)
test/sharness/t0276-cidv0v1.sh new
+129
@@ -0,0 +1,129 @@
1 +#!/usr/bin/env bash
2 +#
3 +# Copyright (c) 2017 Jakub Sztandera
4 +# MIT Licensed; see the LICENSE file in this repository.
5 +#
6 +
7 +test_description="CID Version 0/1 Duality"
8 +
9 +. lib/test-lib.sh
10 +
11 +test_init_ipfs
12 +
13 +#
14 +#
15 +#
16 +
17 +test_expect_success "create two small files" '
18 + random 1000 7 > afile
19 + random 1000 9 > bfile
20 +'
21 +
22 +test_expect_success "add file using CIDv1 but don't pin" '
23 + AHASHv1=$(ipfs add -q --cid-version=1 --raw-leaves=false --pin=false afile)
24 +'
25 +
26 +test_expect_success "add file using CIDv0" '
27 + AHASHv0=$(ipfs add -q --cid-version=0 afile)
28 +'
29 +
30 +test_expect_success "check hashes" '
31 + test "$(cid-fmt %v-%c $AHASHv0)" = "cidv0-protobuf" &&
32 + test "$(cid-fmt %v-%c $AHASHv1)" = "cidv1-protobuf" &&
33 + test "$(cid-fmt -v 0 %s $AHASHv1)" = "$AHASHv0"
34 +'
35 +
36 +test_expect_success "make sure CIDv1 hash really is in the repo" '
37 + ipfs refs local | grep -q $AHASHv1
38 +'
39 +
40 +test_expect_success "make sure CIDv0 hash really is in the repo" '
41 + ipfs refs local | grep -q $AHASHv0
42 +'
43 +
44 +test_expect_success "run gc" '
45 + ipfs repo gc
46 +'
47 +
48 +test_expect_success "make sure the CIDv0 hash is in the repo" '
49 + ipfs refs local | grep -q $AHASHv0
50 +'
51 +
52 +test_expect_success "make sure we can get CIDv0 added file" '
53 + ipfs cat $AHASHv0 > thefile &&
54 + test_cmp afile thefile
55 +'
56 +
57 +test_expect_success "make sure the CIDv1 hash is not in the repo" '
58 + ! ipfs refs local | grep -q $AHASHv1
59 +'
60 +
61 +test_expect_success "clean up" '
62 + ipfs pin rm $AHASHv0 &&
63 + ipfs repo gc &&
64 + ! ipfs refs local | grep -q $AHASHv0
65 +'
66 +
67 +#
68 +#
69 +#
70 +
71 +test_expect_success "add file using CIDv1 but don't pin" '
72 + ipfs add -q --cid-version=1 --raw-leaves=false --pin=false afile
73 +'
74 +
75 +test_expect_success "check that we can access the file when converted to CIDv0" '
76 + ipfs cat $AHASHv0 > thefile &&
77 + test_cmp afile thefile
78 +'
79 +
80 +test_expect_success "clean up" '
81 + ipfs repo gc
82 +'
83 +
84 +test_expect_success "add file using CIDv0 but don't pin" '
85 + ipfs add -q --cid-version=0 --raw-leaves=false --pin=false afile
86 +'
87 +
88 +test_expect_success "check that we can access the file when converted to CIDv1" '
89 + ipfs cat $AHASHv1 > thefile &&
90 + test_cmp afile thefile
91 +'
92 +
93 +#
94 +#
95 +#
96 +
97 +test_expect_success "set up iptb testbed" '
98 + iptb init -n 2 -p 0 -f --bootstrap=none
99 +'
100 +
101 +test_expect_success "start nodes" '
102 + iptb start &&
103 + iptb connect 0 1
104 +'
105 +
106 +test_expect_success "add afile using CIDv0 to node 0" '
107 + iptb run 0 ipfs add -q --cid-version=0 afile
108 +'
109 +
110 +test_expect_success "get afile using CIDv1 via node 1" '
111 + iptb run 1 ipfs --timeout=2s cat $AHASHv1 > thefile &&
112 + test_cmp afile thefile
113 +'
114 +
115 +test_expect_success "add bfile using CIDv1 to node 0" '
116 + BHASHv1=$(iptb run 0 ipfs add -q --cid-version=1 --raw-leaves=false bfile)
117 +'
118 +
119 +test_expect_success "get bfile using CIDv0 via node 1" '
120 + BHASHv0=$(cid-fmt -v 0 %s $BHASHv1)
121 + iptb run 1 ipfs --timeout=2s cat $BHASHv0 > thefile &&
122 + test_cmp bfile thefile
123 +'
124 +
125 +test_expect_success "stop testbed" '
126 + iptb stop
127 +'
128 +
129 +test_done
thirdparty/cidv0v1/blockstore.go new
+71
@@ -0,0 +1,71 @@
1 +package cidv0v1
2 +
3 +import (
4 + blocks "gx/ipfs/QmVzK524a2VWLqyvtBeiHKsUAWYgeAk4DBeZoY7vpNPNRx/go-block-format"
5 + cid "gx/ipfs/QmYVNvtQkeZ6AKSwDrjQTs432QtL6umrrK41EBq3cu7iSP/go-cid"
6 + bs "gx/ipfs/QmadMhXJLHMFjpRmh85XjpmVDkEtQpNYEZNRpWRvYVLrvb/go-ipfs-blockstore"
7 +)
8 +
9 +type blockstore struct {
10 + bs.Blockstore
11 +}
12 +
13 +func NewBlockstore(b bs.Blockstore) bs.Blockstore {
14 + return &blockstore{b}
15 +}
16 +
17 +func (b *blockstore) Has(c *cid.Cid) (bool, error) {
18 + have, err := b.Blockstore.Has(c)
19 + if have || err != nil {
20 + return have, err
21 + }
22 + c1 := tryOtherCidVersion(c)
23 + if c1 == nil {
24 + return false, nil
25 + }
26 + return b.Blockstore.Has(c1)
27 +}
28 +
29 +func (b *blockstore) Get(c *cid.Cid) (blocks.Block, error) {
30 + block, err := b.Blockstore.Get(c)
31 + if err == nil {
32 + return block, nil
33 + }
34 + if err != bs.ErrNotFound {
35 + return nil, err
36 + }
37 + c1 := tryOtherCidVersion(c)
38 + if c1 == nil {
39 + return nil, bs.ErrNotFound
40 + }
41 + block, err = b.Blockstore.Get(c1)
42 + if err != nil {
43 + return nil, err
44 + }
45 + // modify block so it has the original CID
46 + block, err = blocks.NewBlockWithCid(block.RawData(), c)
47 + if err != nil {
48 + return nil, err
49 + }
50 + // insert the block with the original CID to avoid problems
51 + // with pinning
52 + err = b.Blockstore.Put(block)
53 + if err != nil {
54 + return nil, err
55 + }
56 + return block, nil
57 +}
58 +
59 +func tryOtherCidVersion(c *cid.Cid) *cid.Cid {
60 + prefix := c.Prefix()
61 + if prefix.Codec != cid.DagProtobuf {
62 + return nil
63 + }
64 + var c1 *cid.Cid
65 + if prefix.Version == 0 {
66 + c1 = cid.NewCidV1(cid.DagProtobuf, c.Hash())
67 + } else {
68 + c1 = cid.NewCidV0(c.Hash())
69 + }
70 + return c1
71 +}