@cryptotaxi247 / kubo / commits / 6b797f10a

Implement cbor ipld nodes and a first pass at the 'dag' command

License: MIT Signed-off-by: Jeromy <why@ipfs.io>

Jeromy committed Oct 24, 2016 at 12:00 UTC 6b797f10a41002d7b9dfcba473e187b31e6ea0a1
5 files changed +229 -8
core/commands/block.go
-5
@@ -2,7 +2,6 @@ package commands
2
3 import (
4 "bytes"
5 - "errors"
5 "fmt"
6 "io"
7 "io/ioutil"
@@ -168,10 +167,6 @@ func getBlockForKey(req cmds.Request, skey string) (blocks.Block, error) {
167 return nil, err
168 }
169
171 - if !u.IsValidHash(skey) {
172 - return nil, errors.New("Not a valid hash")
173 - }
174 -
170 c, err := cid.Decode(skey)
171 if err != nil {
172 return nil, err
core/commands/dag/dag.go new
+216
@@ -0,0 +1,216 @@
1 +package dagcmd
2 +
3 +import (
4 + "encoding/json"
5 + "fmt"
6 + "io"
7 + "strings"
8 +
9 + cmds "github.com/ipfs/go-ipfs/commands"
10 +
11 + node "gx/ipfs/QmU7bFWQ793qmvNy7outdCaMfSDNk8uqhx4VNrxYj5fj5g/go-ipld-node"
12 + cid "gx/ipfs/QmXfiyr2RWEXpVDdaYnD2HNiBk6UBddsvEP4RPfXb6nGqY/go-cid"
13 + ipldcbor "gx/ipfs/QmYRzW9YDHVNCDbfFzbS7TEXAG1swE1yjq1basZ5WnJYH4/go-ipld-cbor"
14 +)
15 +
16 +var DagCmd = &cmds.Command{
17 + Helptext: cmds.HelpText{
18 + Tagline: "Interact with ipld dag objects.",
19 + ShortDescription: ``,
20 + },
21 +
22 + Subcommands: map[string]*cmds.Command{
23 + "put": DagPutCmd,
24 + "get": DagGetCmd,
25 + },
26 +}
27 +
28 +type OutputObject struct {
29 + Cid *cid.Cid
30 +}
31 +
32 +var DagPutCmd = &cmds.Command{
33 + Helptext: cmds.HelpText{
34 + Tagline: "Add a dag node to ipfs.",
35 + },
36 + Arguments: []cmds.Argument{
37 + cmds.FileArg("object data", true, false, "The object to put").EnableStdin(),
38 + },
39 + Options: []cmds.Option{
40 + cmds.StringOption("format", "f", "Format that the object will be.").Default("cbor"),
41 + cmds.StringOption("input-enc", "Format that the object will be.").Default("json"),
42 + },
43 + Run: func(req cmds.Request, res cmds.Response) {
44 + n, err := req.InvocContext().GetNode()
45 + if err != nil {
46 + res.SetError(err, cmds.ErrNormal)
47 + return
48 + }
49 +
50 + fi, err := req.Files().NextFile()
51 + if err != nil {
52 + res.SetError(err, cmds.ErrNormal)
53 + return
54 + }
55 +
56 + ienc, _, _ := req.Option("input-enc").String()
57 + format, _, _ := req.Option("format").String()
58 + _ = format
59 + switch ienc {
60 + case "json":
61 + var obj map[string]interface{}
62 + err := json.NewDecoder(fi).Decode(&obj)
63 + if err != nil {
64 + res.SetError(err, cmds.ErrNormal)
65 + return
66 + }
67 +
68 + nd, err := convertJsonToType(obj, format)
69 + if err != nil {
70 + res.SetError(err, cmds.ErrNormal)
71 + return
72 + }
73 +
74 + c, err := n.DAG.Add(nd)
75 + if err != nil {
76 + res.SetError(err, cmds.ErrNormal)
77 + return
78 + }
79 +
80 + res.SetOutput(&OutputObject{Cid: c})
81 + return
82 + /*
83 + case "btc":
84 + data, err := ioutil.ReadAll(fi)
85 + if err != nil {
86 + res.SetError(err, cmds.ErrNormal)
87 + return
88 + }
89 +
90 + blk, err := ipldbtc.DecodeBlock(data)
91 + if err != nil {
92 + res.SetError(err, cmds.ErrNormal)
93 + return
94 + }
95 +
96 + c, err := n.DAG.Add(blk)
97 + if err != nil {
98 + res.SetError(err, cmds.ErrNormal)
99 + return
100 + }
101 +
102 + res.SetOutput(&OutputObject{Cid: c})
103 + return
104 + */
105 + }
106 + },
107 + Type: OutputObject{},
108 + Marshalers: cmds.MarshalerMap{
109 + cmds.Text: func(res cmds.Response) (io.Reader, error) {
110 + oobj, ok := res.Output().(*OutputObject)
111 + if !ok {
112 + return nil, fmt.Errorf("expected a different object in marshaler")
113 + }
114 +
115 + return strings.NewReader(oobj.Cid.String()), nil
116 + },
117 + },
118 +}
119 +
120 +var DagGetCmd = &cmds.Command{
121 + Helptext: cmds.HelpText{
122 + Tagline: "Get a dag node from ipfs.",
123 + },
124 + Arguments: []cmds.Argument{
125 + cmds.StringArg("cid", true, false, "The cid of the object to get").EnableStdin(),
126 + },
127 + Run: func(req cmds.Request, res cmds.Response) {
128 + n, err := req.InvocContext().GetNode()
129 + if err != nil {
130 + res.SetError(err, cmds.ErrNormal)
131 + return
132 + }
133 +
134 + c, err := cid.Decode(req.Arguments()[0])
135 + if err != nil {
136 + res.SetError(err, cmds.ErrNormal)
137 + return
138 + }
139 +
140 + obj, err := n.DAG.Get(req.Context(), c)
141 + if err != nil {
142 + res.SetError(err, cmds.ErrNormal)
143 + return
144 + }
145 +
146 + res.SetOutput(obj)
147 + },
148 +}
149 +
150 +func convertJsonToType(obj map[string]interface{}, format string) (node.Node, error) {
151 + switch format {
152 + case "cbor", "dag-cbor":
153 + return convertJsonToCbor(obj)
154 + case "dag-pb", "protobuf":
155 + return nil, fmt.Errorf("protobuf handling in 'dag' command not yet implemented")
156 + default:
157 + return nil, fmt.Errorf("unknown target format: %s", format)
158 + }
159 +}
160 +
161 +func convertJsonToCbor(from map[string]interface{}) (*ipldcbor.Node, error) {
162 + out, err := convertMapSIToCbor(from)
163 + if err != nil {
164 + return nil, err
165 + }
166 +
167 + return ipldcbor.WrapMap(out)
168 +}
169 +func convertMapSIToCbor(from map[string]interface{}) (map[interface{}]interface{}, error) {
170 + to := make(map[interface{}]interface{})
171 + for k, v := range from {
172 + out, err := convertToCborIshObj(v)
173 + if err != nil {
174 + return nil, err
175 + }
176 + to[k] = out
177 + }
178 +
179 + return to, nil
180 +}
181 +
182 +func convertToCborIshObj(i interface{}) (interface{}, error) {
183 + switch v := i.(type) {
184 + case map[string]interface{}:
185 + if lnk, ok := v["/"]; ok && len(v) == 1 {
186 + // special case for links
187 + vstr, ok := lnk.(string)
188 + if !ok {
189 + return nil, fmt.Errorf("link should have been a string")
190 + }
191 +
192 + c, err := cid.Decode(vstr)
193 + if err != nil {
194 + return nil, err
195 + }
196 +
197 + return &ipldcbor.Link{Target: c}, nil
198 + }
199 +
200 + return convertMapSIToCbor(v)
201 + case []interface{}:
202 + var out []interface{}
203 + for _, o := range v {
204 + obj, err := convertToCborIshObj(o)
205 + if err != nil {
206 + return nil, err
207 + }
208 +
209 + out = append(out, obj)
210 + }
211 +
212 + return out, nil
213 + default:
214 + return v, nil
215 + }
216 +}
core/commands/root.go
+2
@@ -5,6 +5,7 @@ import (
5 "strings"
6
7 cmds "github.com/ipfs/go-ipfs/commands"
8 + dag "github.com/ipfs/go-ipfs/core/commands/dag"
9 files "github.com/ipfs/go-ipfs/core/commands/files"
10 ocmd "github.com/ipfs/go-ipfs/core/commands/object"
11 unixfs "github.com/ipfs/go-ipfs/core/commands/unixfs"
@@ -86,6 +87,7 @@ var rootSubcommands = map[string]*cmds.Command{
87 "cat": CatCmd,
88 "commands": CommandsDaemonCmd,
89 "config": ConfigCmd,
90 + "dag": dag.DagCmd,
91 "dht": DhtCmd,
92 "diag": DiagCmd,
93 "dns": DNSCmd,
merkledag/merkledag.go
+7
@@ -14,6 +14,7 @@ import (
14 logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
15 node "gx/ipfs/QmU7bFWQ793qmvNy7outdCaMfSDNk8uqhx4VNrxYj5fj5g/go-ipld-node"
16 cid "gx/ipfs/QmXfiyr2RWEXpVDdaYnD2HNiBk6UBddsvEP4RPfXb6nGqY/go-cid"
17 + ipldcbor "gx/ipfs/QmYRzW9YDHVNCDbfFzbS7TEXAG1swE1yjq1basZ5WnJYH4/go-ipld-cbor"
18 )
19
20 var log = logging.Logger("merkledag")
@@ -105,6 +106,12 @@ func decodeBlock(b blocks.Block) (node.Node, error) {
106 return decnd, nil
107 case cid.Raw:
108 return NewRawNode(b.RawData()), nil
109 + case cid.CBOR:
110 + return ipldcbor.Decode(b.RawData())
111 + /*
112 + case cid.Bitcoin:
113 + return ipldbtc.DecodeBlock(b.RawData())
114 + */
115 default:
116 return nil, fmt.Errorf("unrecognized object type: %s", c.Type())
117 }
package.json
+4 -3
@@ -277,9 +277,10 @@
277 "version": "0.3.2"
278 },
279 {
280 - "hash": "QmQKEgGgYCDyk8VNY6A65FpuE4YwbspvjXHco1rdb75PVc",
281 - "name": "go-libp2p-routing",
282 - "version": "2.2.2"
280 + "author": "whyrusleeping",
281 + "hash": "QmYRzW9YDHVNCDbfFzbS7TEXAG1swE1yjq1basZ5WnJYH4",
282 + "name": "go-ipld-cbor",
283 + "version": "0.2.1"
284 }
285 ],
286 "gxVersion": "0.4.0",