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
+}