@cryptotaxi247 / kubo / commits / 518adec02

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 {