adder: add support for using CidV1
License: MIT Signed-off-by: Kevin Atkinson <k@kevina.org>
Kevin Atkinson committed
Mar 2, 2017 at 21:35 UTC
518adec022db6ec1273dcf9c3d2cf082eabf2206
15 files changed
+220
-51
core/commands/add.go
+14
@@ -38,6 +38,7 @@ const (
38
rawLeavesOptionName = "raw-leaves"
39
noCopyOptionName = "nocopy"
40
fstoreCacheOptionName = "fscache"
41
+ cidVersionOptionName = "cid-version"
42
)
43
44
const adderOutChanSize = 8
@@ -88,6 +89,7 @@ You can now refer to the added file in a gateway, like so:
89
cmds.BoolOption(rawLeavesOptionName, "Use raw blocks for leaf nodes. (experimental)"),
90
cmds.BoolOption(noCopyOptionName, "Add the file using filestore. (experimental)"),
91
cmds.BoolOption(fstoreCacheOptionName, "Check the filestore for pre-existing blocks. (experimental)"),
92
+ cmds.IntOption(cidVersionOptionName, "Cid version. Non-zero value will change default of 'raw-leaves' to true. (experimental)").Default(0),
93
},
94
PreRun: func(req cmds.Request) error {
95
quiet, _, _ := req.Option(quietOptionName).Bool()
@@ -161,6 +163,7 @@ You can now refer to the added file in a gateway, like so:
163
rawblks, rbset, _ := req.Option(rawLeavesOptionName).Bool()
164
nocopy, _, _ := req.Option(noCopyOptionName).Bool()
165
fscache, _, _ := req.Option(fstoreCacheOptionName).Bool()
166
+ cidVer, _, _ := req.Option(cidVersionOptionName).Int()
167
168
if nocopy && !cfg.Experimental.FilestoreEnabled {
169
res.SetError(errors.New("filestore is not enabled, see https://git.io/vy4XN"),
@@ -177,6 +180,16 @@ You can now refer to the added file in a gateway, like so:
180
return
181
}
182
183
+ if cidVer >= 1 && !rbset {
184
+ rawblks = true
185
+ }
186
+
187
+ prefix, err := dag.PrefixForCidVersion(cidVer)
188
+ if err != nil {
189
+ res.SetError(err, cmds.ErrNormal)
190
+ return
191
+ }
192
+
193
if hash {
194
nilnode, err := core.NewNode(n.Context(), &core.BuildCfg{
195
//TODO: need this to be true or all files
@@ -223,6 +236,7 @@ You can now refer to the added file in a gateway, like so:
236
fileAdder.Silent = silent
237
fileAdder.RawLeaves = rawblks
238
fileAdder.NoCopy = nocopy
239
+ fileAdder.Prefix = prefix
240
241
if hash {
242
md := dagtest.Mock()
core/coreunix/add.go
+49
-17
@@ -69,13 +69,7 @@ type AddedObject struct {
69
}
70
71
func NewAdder(ctx context.Context, p pin.Pinner, bs bstore.GCBlockstore, ds dag.DAGService) (*Adder, error) {
72
- mr, err := mfs.NewRoot(ctx, ds, unixfs.EmptyDirNode(), nil)
73
- if err != nil {
74
- return nil, err
75
- }
76
-
72
return &Adder{
78
- mr: mr,
73
ctx: ctx,
74
pinning: p,
75
blockstore: bs,
@@ -87,7 +81,6 @@ func NewAdder(ctx context.Context, p pin.Pinner, bs bstore.GCBlockstore, ds dag.
81
Wrap: false,
82
Chunker: "",
83
}, nil
90
-
84
}
85
86
// Adder holds the switches passed to the `add` command.
@@ -107,13 +100,28 @@ type Adder struct {
100
NoCopy bool
101
Chunker string
102
root node.Node
110
- mr *mfs.Root
103
+ mroot *mfs.Root
104
unlocker bs.Unlocker
105
tempRoot *cid.Cid
106
+ Prefix cid.Prefix
107
+}
108
+
109
+func (adder *Adder) mfsRoot() (*mfs.Root, error) {
110
+ if adder.mroot != nil {
111
+ return adder.mroot, nil
112
+ }
113
+ rnode := unixfs.EmptyDirNode()
114
+ rnode.SetPrefix(adder.Prefix)
115
+ mr, err := mfs.NewRoot(adder.ctx, adder.dagService, rnode, nil)
116
+ if err != nil {
117
+ return nil, err
118
+ }
119
+ adder.mroot = mr
120
+ return adder.mroot, nil
121
}
122
123
func (adder *Adder) SetMfsRoot(r *mfs.Root) {
116
- adder.mr = r
124
+ adder.mroot = r
125
}
126
127
// Constructs a node from reader's data, and adds it. Doesn't pin.
@@ -122,11 +130,13 @@ func (adder Adder) add(reader io.Reader) (node.Node, error) {
130
if err != nil {
131
return nil, err
132
}
133
+
134
params := ihelper.DagBuilderParams{
135
Dagserv: adder.dagService,
136
RawLeaves: adder.RawLeaves,
137
Maxlinks: ihelper.DefaultLinksPerBlock,
138
NoCopy: adder.NoCopy,
139
+ Prefix: adder.Prefix,
140
}
141
142
if adder.Trickle {
@@ -142,7 +152,11 @@ func (adder *Adder) RootNode() (node.Node, error) {
152
return adder.root, nil
153
}
154
145
- root, err := adder.mr.GetValue().GetNode()
155
+ mr, err := adder.mfsRoot()
156
+ if err != nil {
157
+ return nil, err
158
+ }
159
+ root, err := mr.GetValue().GetNode()
160
if err != nil {
161
return nil, err
162
}
@@ -188,9 +202,13 @@ func (adder *Adder) PinRoot() error {
202
}
203
204
func (adder *Adder) Finalize() (node.Node, error) {
191
- root := adder.mr.GetValue()
205
+ mr, err := adder.mfsRoot()
206
+ if err != nil {
207
+ return nil, err
208
+ }
209
+ root := mr.GetValue()
210
193
- err := root.Flush()
211
+ err = root.Flush()
212
if err != nil {
213
return nil, err
214
}
@@ -203,7 +221,12 @@ func (adder *Adder) Finalize() (node.Node, error) {
221
}
222
name = children[0]
223
206
- dir, ok := adder.mr.GetValue().(*mfs.Directory)
224
+ mr, err := adder.mfsRoot()
225
+ if err != nil {
226
+ return nil, err
227
+ }
228
+
229
+ dir, ok := mr.GetValue().(*mfs.Directory)
230
if !ok {
231
return nil, fmt.Errorf("root is not a directory")
232
}
@@ -219,7 +242,7 @@ func (adder *Adder) Finalize() (node.Node, error) {
242
return nil, err
243
}
244
222
- err = adder.mr.Close()
245
+ err = mr.Close()
246
if err != nil {
247
return nil, err
248
}
@@ -357,14 +380,18 @@ func (adder *Adder) addNode(node node.Node, path string) error {
380
node = pi.Node
381
}
382
383
+ mr, err := adder.mfsRoot()
384
+ if err != nil {
385
+ return err
386
+ }
387
dir := gopath.Dir(path)
388
if dir != "." {
362
- if err := mfs.Mkdir(adder.mr, dir, true, false); err != nil {
389
+ if err := mfs.Mkdir(mr, dir, true, false); err != nil {
390
return err
391
}
392
}
393
367
- if err := mfs.PutNode(adder.mr, path, node); err != nil {
394
+ if err := mfs.PutNode(mr, path, node); err != nil {
395
return err
396
}
397
@@ -406,6 +433,7 @@ func (adder *Adder) addFile(file files.File) error {
433
}
434
435
dagnode := dag.NodeWithData(sdata)
436
+ dagnode.SetPrefix(adder.Prefix)
437
_, err = adder.dagService.Add(dagnode)
438
if err != nil {
439
return err
@@ -439,7 +467,11 @@ func (adder *Adder) addFile(file files.File) error {
467
func (adder *Adder) addDir(dir files.File) error {
468
log.Infof("adding directory: %s", dir.FileName())
469
442
- err := mfs.Mkdir(adder.mr, dir.FileName(), true, false)
470
+ mr, err := adder.mfsRoot()
471
+ if err != nil {
472
+ return err
473
+ }
474
+ err = mfs.Mkdir(mr, dir.FileName(), true, false)
475
if err != nil {
476
return err
477
}
importer/balanced/builder.go
+3
-3
@@ -13,7 +13,7 @@ func BalancedLayout(db *h.DagBuilderHelper) (node.Node, error) {
13
var root *h.UnixfsNode
14
for level := 0; !db.Done(); level++ {
15
16
- nroot := h.NewUnixfsNode()
16
+ nroot := db.NewUnixfsNode()
17
db.SetPosInfo(nroot, 0)
18
19
// add our old root as a child of the new root.
@@ -33,7 +33,7 @@ func BalancedLayout(db *h.DagBuilderHelper) (node.Node, error) {
33
34
}
35
if root == nil {
36
- root = h.NewUnixfsNode()
36
+ root = db.NewUnixfsNode()
37
}
38
39
out, err := db.Add(root)
@@ -72,7 +72,7 @@ func fillNodeRec(db *h.DagBuilderHelper, node *h.UnixfsNode, depth int, offset u
72
73
// while we have room AND we're not done
74
for node.NumChildren() < db.Maxlinks() && !db.Done() {
75
- child := h.NewUnixfsNode()
75
+ child := db.NewUnixfsNode()
76
db.SetPosInfo(child, offset)
77
78
err := fillNodeRec(db, child, depth-1, offset)
importer/helpers/dagbuilder.go
+28
-1
@@ -7,7 +7,9 @@ import (
7
"github.com/ipfs/go-ipfs/commands/files"
8
"github.com/ipfs/go-ipfs/importer/chunk"
9
dag "github.com/ipfs/go-ipfs/merkledag"
10
+ ft "github.com/ipfs/go-ipfs/unixfs"
11
12
+ cid "gx/ipfs/QmYhQaCYEcaPPjxJX7YcPcVKkQfRy6sJ7B3XmGFk82XYdQ/go-cid"
13
node "gx/ipfs/Qmb3Hm9QDFmfYuET4pu7Kyg8JV78jFa1nvZx5vnCZsK4ck/go-ipld-format"
14
)
15
@@ -23,6 +25,7 @@ type DagBuilderHelper struct {
25
batch *dag.Batch
26
fullPath string
27
stat os.FileInfo
28
+ prefix cid.Prefix
29
}
30
31
type DagBuilderParams struct {
@@ -33,6 +36,9 @@ type DagBuilderParams struct {
36
// instead of using the unixfs TRaw type
37
RawLeaves bool
38
39
+ // CID Prefix to use
40
+ Prefix cid.Prefix
41
+
42
// DAGService to write blocks to (required)
43
Dagserv dag.DAGService
44
@@ -48,6 +54,7 @@ func (dbp *DagBuilderParams) New(spl chunk.Splitter) *DagBuilderHelper {
54
dserv: dbp.Dagserv,
55
spl: spl,
56
rawLeaves: dbp.RawLeaves,
57
+ prefix: dbp.Prefix,
58
maxlinks: dbp.Maxlinks,
59
batch: dbp.Dagserv.Batch(),
60
}
@@ -103,6 +110,26 @@ func (db *DagBuilderHelper) GetDagServ() dag.DAGService {
110
return db.dserv
111
}
112
113
+// NewUnixfsNode creates a new Unixfs node to represent a file.
114
+func (db *DagBuilderHelper) NewUnixfsNode() *UnixfsNode {
115
+ n := &UnixfsNode{
116
+ node: new(dag.ProtoNode),
117
+ ufmt: &ft.FSNode{Type: ft.TFile},
118
+ }
119
+ n.SetPrefix(db.prefix)
120
+ return n
121
+}
122
+
123
+// NewUnixfsBlock creates a new Unixfs node to represent a raw data block
124
+func (db *DagBuilderHelper) NewUnixfsBlock() *UnixfsNode {
125
+ n := &UnixfsNode{
126
+ node: new(dag.ProtoNode),
127
+ ufmt: &ft.FSNode{Type: ft.TRaw},
128
+ }
129
+ n.SetPrefix(db.prefix)
130
+ return n
131
+}
132
+
133
// FillNodeLayer will add datanodes as children to the give node until
134
// at most db.indirSize ndoes are added
135
//
@@ -143,7 +170,7 @@ func (db *DagBuilderHelper) GetNextDataNode() (*UnixfsNode, error) {
170
raw: true,
171
}, nil
172
} else {
146
- blk := NewUnixfsBlock()
173
+ blk := db.NewUnixfsBlock()
174
blk.SetData(data)
175
return blk, nil
176
}
importer/helpers/helpers.go
+5
-16
@@ -10,6 +10,7 @@ import (
10
pi "github.com/ipfs/go-ipfs/thirdparty/posinfo"
11
ft "github.com/ipfs/go-ipfs/unixfs"
12
13
+ cid "gx/ipfs/QmYhQaCYEcaPPjxJX7YcPcVKkQfRy6sJ7B3XmGFk82XYdQ/go-cid"
14
node "gx/ipfs/Qmb3Hm9QDFmfYuET4pu7Kyg8JV78jFa1nvZx5vnCZsK4ck/go-ipld-format"
15
)
16
@@ -48,22 +49,6 @@ type UnixfsNode struct {
49
posInfo *pi.PosInfo
50
}
51
51
-// NewUnixfsNode creates a new Unixfs node to represent a file
52
-func NewUnixfsNode() *UnixfsNode {
53
- return &UnixfsNode{
54
- node: new(dag.ProtoNode),
55
- ufmt: &ft.FSNode{Type: ft.TFile},
56
- }
57
-}
58
-
59
-// NewUnixfsBlock creates a new Unixfs node to represent a raw data block
60
-func NewUnixfsBlock() *UnixfsNode {
61
- return &UnixfsNode{
62
- node: new(dag.ProtoNode),
63
- ufmt: &ft.FSNode{Type: ft.TRaw},
64
- }
65
-}
66
-
52
// NewUnixfsNodeFromDag reconstructs a Unixfs node from a given dag node
53
func NewUnixfsNodeFromDag(nd *dag.ProtoNode) (*UnixfsNode, error) {
54
mb, err := ft.FSNodeFromBytes(nd.Data())
@@ -77,6 +62,10 @@ func NewUnixfsNodeFromDag(nd *dag.ProtoNode) (*UnixfsNode, error) {
62
}, nil
63
}
64
65
+func (n *UnixfsNode) SetPrefix(prefix cid.Prefix) {
66
+ n.node.SetPrefix(prefix)
67
+}
68
+
69
func (n *UnixfsNode) NumChildren() int {
70
return n.ufmt.NumChildren()
71
}
importer/trickle/trickledag.go
+6
-6
@@ -18,13 +18,13 @@ import (
18
const layerRepeat = 4
19
20
func TrickleLayout(db *h.DagBuilderHelper) (node.Node, error) {
21
- root := h.NewUnixfsNode()
21
+ root := db.NewUnixfsNode()
22
if err := db.FillNodeLayer(root); err != nil {
23
return nil, err
24
}
25
for level := 1; !db.Done(); level++ {
26
for i := 0; i < layerRepeat && !db.Done(); i++ {
27
- next := h.NewUnixfsNode()
27
+ next := db.NewUnixfsNode()
28
if err := fillTrickleRec(db, next, level); err != nil {
29
return nil, err
30
}
@@ -54,7 +54,7 @@ func fillTrickleRec(db *h.DagBuilderHelper, node *h.UnixfsNode, depth int) error
54
55
for i := 1; i < depth && !db.Done(); i++ {
56
for j := 0; j < layerRepeat && !db.Done(); j++ {
57
- next := h.NewUnixfsNode()
57
+ next := db.NewUnixfsNode()
58
if err := fillTrickleRec(db, next, i); err != nil {
59
return err
60
}
@@ -117,7 +117,7 @@ func TrickleAppend(ctx context.Context, basen node.Node, db *h.DagBuilderHelper)
117
// Now, continue filling out tree like normal
118
for i := n; !db.Done(); i++ {
119
for j := 0; j < layerRepeat && !db.Done(); j++ {
120
- next := h.NewUnixfsNode()
120
+ next := db.NewUnixfsNode()
121
err := fillTrickleRec(db, next, i)
122
if err != nil {
123
return nil, err
@@ -162,7 +162,7 @@ func appendFillLastChild(ctx context.Context, ufsn *h.UnixfsNode, depth int, lay
162
// Partially filled depth layer
163
if layerFill != 0 {
164
for ; layerFill < layerRepeat && !db.Done(); layerFill++ {
165
- next := h.NewUnixfsNode()
165
+ next := db.NewUnixfsNode()
166
err := fillTrickleRec(db, next, depth)
167
if err != nil {
168
return err
@@ -211,7 +211,7 @@ func trickleAppendRec(ctx context.Context, ufsn *h.UnixfsNode, db *h.DagBuilderH
211
// Now, continue filling out tree like normal
212
for i := n; i < depth && !db.Done(); i++ {
213
for j := 0; j < layerRepeat && !db.Done(); j++ {
214
- next := h.NewUnixfsNode()
214
+ next := db.NewUnixfsNode()
215
if err := fillTrickleRec(db, next, i); err != nil {
216
return nil, err
217
}
merkledag/coding.go
+1
-1
@@ -86,7 +86,7 @@ func (n *ProtoNode) EncodeProtobuf(force bool) ([]byte, error) {
86
87
if n.cached == nil {
88
if n.Prefix.Codec == 0 { // unset
89
- n.Prefix = defaultCidPrefix
89
+ n.Prefix = v0CidPrefix
90
}
91
c, err := n.Prefix.Sum(n.encoded)
92
if err != nil {
merkledag/node.go
+29
-2
@@ -28,13 +28,37 @@ type ProtoNode struct {
28
Prefix cid.Prefix
29
}
30
31
-var defaultCidPrefix = cid.Prefix{
31
+var v0CidPrefix = cid.Prefix{
32
Codec: cid.DagProtobuf,
33
MhLength: -1,
34
MhType: mh.SHA2_256,
35
Version: 0,
36
}
37
38
+var v1CidPrefix = cid.Prefix{
39
+ Codec: cid.DagProtobuf,
40
+ MhLength: -1,
41
+ MhType: mh.SHA2_256,
42
+ Version: 1,
43
+}
44
+
45
+func PrefixForCidVersion(version int) (cid.Prefix, error) {
46
+ switch version {
47
+ case 0:
48
+ return v0CidPrefix, nil
49
+ case 1:
50
+ return v1CidPrefix, nil
51
+ default:
52
+ return cid.Prefix{}, fmt.Errorf("unknown CID version: %d", version)
53
+ }
54
+}
55
+
56
+func (n *ProtoNode) SetPrefix(prefix cid.Prefix) {
57
+ n.Prefix = prefix
58
+ n.encoded = nil
59
+ n.cached = nil
60
+}
61
+
62
type LinkSlice []*node.Link
63
64
func (ls LinkSlice) Len() int { return len(ls) }
@@ -158,6 +182,9 @@ func (n *ProtoNode) Copy() node.Node {
182
nnode.links = make([]*node.Link, len(n.links))
183
copy(nnode.links, n.links)
184
}
185
+
186
+ nnode.Prefix = n.Prefix
187
+
188
return nnode
189
}
190
@@ -260,7 +287,7 @@ func (n *ProtoNode) Cid() *cid.Cid {
287
}
288
289
if n.Prefix.Codec == 0 {
263
- n.Prefix = defaultCidPrefix
290
+ n.Prefix = v0CidPrefix
291
}
292
293
c, err := n.Prefix.Sum(n.RawData())
mfs/dir.go
+5
@@ -15,6 +15,7 @@ import (
15
uio "github.com/ipfs/go-ipfs/unixfs/io"
16
ufspb "github.com/ipfs/go-ipfs/unixfs/pb"
17
18
+ cid "gx/ipfs/QmYhQaCYEcaPPjxJX7YcPcVKkQfRy6sJ7B3XmGFk82XYdQ/go-cid"
19
node "gx/ipfs/Qmb3Hm9QDFmfYuET4pu7Kyg8JV78jFa1nvZx5vnCZsK4ck/go-ipld-format"
20
)
21
@@ -57,6 +58,10 @@ func NewDirectory(ctx context.Context, name string, node node.Node, parent child
58
}, nil
59
}
60
61
+func (d *Directory) SetPrefix(prefix cid.Prefix) {
62
+ d.dirbuilder.SetPrefix(prefix)
63
+}
64
+
65
// closeChild updates the child by the given name to the dag node 'nd'
66
// and changes its own dag node
67
func (d *Directory) closeChild(name string, nd node.Node, sync bool) error {
mfs/ops.go
+2
@@ -134,6 +134,7 @@ func Mkdir(r *Root, pth string, mkparents bool, flush bool) error {
134
if err != nil {
135
return err
136
}
137
+ mkd.SetPrefix(r.Prefix)
138
fsn = mkd
139
} else if err != nil {
140
return err
@@ -152,6 +153,7 @@ func Mkdir(r *Root, pth string, mkparents bool, flush bool) error {
153
return err
154
}
155
}
156
+ final.SetPrefix(r.Prefix)
157
158
if flush {
159
err := final.Flush()
mfs/system.go
+3
@@ -61,6 +61,9 @@ type Root struct {
61
dserv dag.DAGService
62
63
Type string
64
+
65
+ // Prefix to use for any children created
66
+ Prefix cid.Prefix
67
}
68
69
type PubFunc func(context.Context, *cid.Cid) error
test/sharness/t0040-add-and-cat.sh
+36
-5
@@ -100,7 +100,7 @@ test_add_cat_5MB() {
100
test_cmp sha1_expected sha1_actual
101
'
102
103
- test_expect_success "'ipfs add bigfile' succeeds" '
103
+ test_expect_success "'ipfs add $ADD_FLAGS bigfile' succeeds" '
104
ipfs add $ADD_FLAGS mountdir/bigfile >actual ||
105
test_fsh cat daemon_err
106
'
@@ -142,6 +142,9 @@ test_add_cat_raw() {
142
}
143
144
test_add_cat_expensive() {
145
+ ADD_FLAGS="$1"
146
+ HASH="$2"
147
+
148
test_expect_success EXPENSIVE "generate 100MB file using go-random" '
149
random 104857600 42 >mountdir/bigfile
150
'
@@ -152,12 +155,11 @@ test_add_cat_expensive() {
155
test_cmp sha1_expected sha1_actual
156
'
157
155
- test_expect_success EXPENSIVE "ipfs add bigfile succeeds" '
156
- ipfs add mountdir/bigfile >actual
158
+ test_expect_success EXPENSIVE "ipfs add $ADD_FLAGS bigfile succeeds" '
159
+ ipfs add $ADD_FLAGS mountdir/bigfile >actual
160
'
161
162
test_expect_success EXPENSIVE "ipfs add bigfile output looks good" '
160
- HASH="QmU9SWAPPmNEKZB8umYMmjYvN7VyHqABNvdA6GUi4MMEz3" &&
163
echo "added $HASH bigfile" >expected &&
164
test_cmp expected actual
165
'
@@ -391,6 +393,16 @@ MARS="zb2rhZdTkQNawVajsTNiYc9cTPHqgLdJVvBRkZok9RjkgQYRU"
393
VENUS="zb2rhn6TGvnUaMAg4VV4y9HVx5W42HihcH4jsyrDv8mkepFqq"
394
add_directory '--raw-leaves'
395
396
+PLANETS="zdj7Wnbun6P41Z5ddTkNvZaDTmQ8ZLdiKFcJrL9sV87rPScMP"
397
+MARS="zb2rhZdTkQNawVajsTNiYc9cTPHqgLdJVvBRkZok9RjkgQYRU"
398
+VENUS="zb2rhn6TGvnUaMAg4VV4y9HVx5W42HihcH4jsyrDv8mkepFqq"
399
+add_directory '--cid-version=1'
400
+
401
+PLANETS="zdj7WiC51v78BjBcmZR7uuBvmDWxSn5EDr5MiyTwE18e8qvb7"
402
+MARS="zdj7WWx6fGNrNGkdpkuTAxCjKbQ1pPtarqA6VQhedhLTZu34J"
403
+VENUS="zdj7WbB1BUF8WejmVpQCmMLd1RbPnxJtvAj1Lep6eTmXRFbrz"
404
+add_directory '--cid-version=1 --raw-leaves=false'
405
+
406
407
test_expect_success "'ipfs add -rn' succeeds" '
408
mkdir -p mountdir/moons/jupiter &&
@@ -425,7 +437,20 @@ test_add_cat_5MB "" "QmSr7FqYkxYWGoSfy8ZiaMWQ5vosb18DQGCzjwEQnVHkTb"
437
438
test_add_cat_5MB --raw-leaves "QmbdLHCmdi48eM8T7D67oXjA1S2Puo8eMfngdHhdPukFd6"
439
428
-test_add_cat_expensive
440
+# note: the specified hash implies that internal nodes are stored
441
+# using CidV1 and leaves are stored using raw blocks
442
+test_add_cat_5MB --cid-version=1 "zdj7WiiaedqVBXjX4SNqx3jfuZideDqdLYnDzCDJ66JDMK9o2"
443
+
444
+# note: the specified hash implies that internal nodes are stored
445
+# using CidV1 and leaves are stored using CidV1 but using the legacy
446
+# format (i.e. not raw)
447
+test_add_cat_5MB '--cid-version=1 --raw-leaves=false' "zdj7WfgEsj897BBZj2mcfsRLhaPZcCixPV2G7DkWgF1Wdr64P"
448
+
449
+test_add_cat_expensive "" "QmU9SWAPPmNEKZB8umYMmjYvN7VyHqABNvdA6GUi4MMEz3"
450
+
451
+# note: the specified hash implies that internal nodes are stored
452
+# using CidV1 and leaves are stored using raw blocks
453
+test_add_cat_expensive "--cid-version=1" "zdj7WcatQrtuE4WMkS4XsfsMixuQN2po4irkYhqxeJyW1wgCq"
454
455
test_add_named_pipe " Post http://$API_ADDR/api/v0/add?encoding=json&progress=true&r=true&stream-channels=true:"
456
@@ -433,6 +458,12 @@ test_add_pwd_is_symlink
458
459
test_add_cat_raw
460
461
+test_expect_success "ipfs add --cid-version=9 fails" '
462
+ echo "context" > afile.txt &&
463
+ test_must_fail ipfs add --cid-version=9 afile.txt 2>&1 | tee add_out &&
464
+ grep -q "unknown CID version" add_out
465
+'
466
+
467
test_kill_ipfs_daemon
468
469
# should work offline
test/sharness/t0043-add-w.sh
+16
@@ -27,6 +27,14 @@ added QmYC3u5jGWuyFwvTxtvLYm2K3SpWZ31tg3NjpVVvh9cJaJ _jo7/wzvsihy
27
added QmQkib3f9XNX5sj6WEahLUPFpheTcwSRJwUCSvjcv8b9by _jo7
28
added QmNQoesMj1qp8ApE51NbtTjFYksyzkezPD4cat7V2kzbKN '
29
30
+add_w_d1_v1='added zb2rhjXyHbbgwgtAUwHtpBd8iXLgK22ZjVmaiJSMNmqBTpXS3 _jo7/-s782qgs
31
+added zb2rhi6PQqQFbS4QsvrV8sL9ue1fvFoqtLVqogNPCZri8rquN _jo7/15totauzkak-
32
+added zb2rhjQthC6LgnNZztpsF9LcfPxznh3cJnmzUx8dnSqNqJ8Yz _jo7/galecuirrj4r
33
+added zb2rhYh9hgDw1DpaZfLUU5MkKNezPWjPTkgGQPiTyLpZYu3jn _jo7/mzo50r-1xidf5zx
34
+added zb2rhZK5xwEUhY4uskfj4sn979aCH27cnqseVVznYDn7NFWtt _jo7/wzvsihy
35
+added zdj7WfNC8EZchqskczxsgrVEqwLVpksQ9B5kopf391jVbCGwv _jo7
36
+added zdj7Wn5jf686mfYE8gUKWzY7aTjp5eAQcecD8q4ZtqLJbDNxe '
37
+
38
add_w_d2='added Qme987pqNBhZZXy4ckeXiR7zaRQwBabB7fTgHurW2yJfNu 4r93
39
added QmU9Jqks8TPu4vFr6t7EKkAKQrSJuEujNj1AkzoCeTEDFJ gnz66h/1k0xpx34
40
added QmSLYZycXAufRw3ePMVH2brbtYWCcWsmksGLbHcT8ia9Ke gnz66h/9cwudvacx
@@ -133,6 +141,14 @@ test_add_w() {
141
test_sort_cmp expected actual
142
'
143
144
+ test_expect_success "ipfs add -w -r (dir) --cid-version=1 succeeds" '
145
+ ipfs add -r -w --cid-version=1 m/t_1wp-8a2/_jo7 >actual
146
+ '
147
+
148
+ test_expect_success "ipfs add -w -r (dir) --cid-version=1 is correct" '
149
+ echo "$add_w_d1_v1" >expected &&
150
+ test_sort_cmp expected actual
151
+ '
152
}
153
154
test_init_ipfs
test/sharness/t0044-add-symlink.sh
+11
@@ -27,6 +27,17 @@ test_add_symlinks() {
27
test_cmp filehash_exp filehash_out
28
'
29
30
+ test_expect_success "ipfs add --cid-version=1 files succeeds" '
31
+ ipfs add -q -r --cid-version=1 files >filehash_all &&
32
+ tail -n 1 filehash_all >filehash_out
33
+ '
34
+
35
+ test_expect_success "output looks good" '
36
+ # note this hash implies all internal nodes are stored using CidV1
37
+ echo zdj7WZDQ2xMmr4qn6aRZTsE9fCUs2KmvPigpHdpssqUobwcWK > filehash_exp &&
38
+ test_cmp filehash_exp filehash_out
39
+ '
40
+
41
test_expect_success "adding a symlink adds the link itself" '
42
ipfs add -q files/bar/baz > goodlink_out
43
'
unixfs/io/dirbuilder.go
+12
@@ -8,6 +8,7 @@ import (
8
mdag "github.com/ipfs/go-ipfs/merkledag"
9
format "github.com/ipfs/go-ipfs/unixfs"
10
hamt "github.com/ipfs/go-ipfs/unixfs/hamt"
11
+ cid "gx/ipfs/QmYhQaCYEcaPPjxJX7YcPcVKkQfRy6sJ7B3XmGFk82XYdQ/go-cid"
12
13
node "gx/ipfs/Qmb3Hm9QDFmfYuET4pu7Kyg8JV78jFa1nvZx5vnCZsK4ck/go-ipld-format"
14
)
@@ -79,6 +80,17 @@ func NewDirectoryFromNode(dserv mdag.DAGService, nd node.Node) (*Directory, erro
80
}
81
}
82
83
+// SetPrefix sets the prefix of the root node
84
+func (d *Directory) SetPrefix(prefix cid.Prefix) {
85
+ if d.dirnode != nil {
86
+ d.dirnode.SetPrefix(prefix)
87
+ }
88
+ // FIXME: Should we do this? -- kevina
89
+ //if d.shard != nil {
90
+ // d.shard.SetPrefix(prefix)
91
+ //}
92
+}
93
+
94
// AddChild adds a (name, key)-pair to the root node.
95
func (d *Directory) AddChild(ctx context.Context, name string, nd node.Node) error {
96
if d.shard == nil {