merkledag
Juan Batiz-Benet committed
Jul 4, 2014 at 14:54 UTC
e4ea7ce59ab62397577135181e7f9059b8c0aa5b
3 files changed
+137
merkledag/coding.go
new
+61
@@ -0,0 +1,61 @@
1
+package merkledag
2
+
3
+import (
4
+ "fmt"
5
+ mh "github.com/jbenet/go-multihash"
6
+)
7
+
8
+// for now, we use a PBNode intermediate thing.
9
+// because native go objects are nice.
10
+
11
+func (n *Node) Unmarshal(encoded []byte) error {
12
+ var pbn PBNode
13
+ if err := pbn.Unmarshal(encoded), err != nil {
14
+ return fmt.Errorf("Unmarshal failed. %v", err)
15
+ }
16
+
17
+ pbnl := pbn.Links()
18
+ n.Links = make([]*Link, len(pbnl))
19
+ for i, l := range(pbnl) {
20
+ n.Links[i] = &Link{Name: l.GetName(), Size: l.GetSize()}
21
+ n.Links[i].Hash, err := mh.Cast(l.GetHash())
22
+ if err != nil {
23
+ return fmt.Errorf("Link hash is not valid multihash. %v", err)
24
+ }
25
+ }
26
+
27
+ n.Data = pbn.GetData()
28
+ return nil
29
+}
30
+
31
+func (n *Node) MarshalTo(encoded []byte) error {
32
+ pbn := n.getPBNode()
33
+ if err := pbn.MarshalTo(encoded), err != nil {
34
+ return fmt.Errorf("Marshal failed. %v", err)
35
+ }
36
+ return nil
37
+}
38
+
39
+func (n *Node) Marshal() ([]byte, error) {
40
+ pbn := n.getPBNode()
41
+ data, err := pbn.Marshal()
42
+ if err != nil {
43
+ return data, fmt.Errorf("Marshal failed. %v", err)
44
+ }
45
+ return data, nil
46
+}
47
+
48
+func (n *Node) getPBNode() *PBNode {
49
+ pbn := &PBNode{}
50
+ pbn.Links = make([]*PBLink, len(n.Links))
51
+ for i, l := range(n.Links) {
52
+ pbn.Links[i] = &PBLink{}
53
+ n.Links[i].Name = &l.Name
54
+ n.Links[i].Size = l.Size
55
+ n.Links[i].Hash = &[]byte(l.Hash)
56
+ }
57
+
58
+ pbn.Data = &n.Data
59
+ return pbn, nil
60
+}
61
+
merkledag/merkledag.go
new
+36
@@ -0,0 +1,36 @@
1
+package merkledag
2
+
3
+import (
4
+ mh "github.com/jbenet/go-multihash"
5
+)
6
+
7
+// A node in the IPFS Merkle DAG.
8
+// nodes have opaque data and a set of navigable links.
9
+type Node {
10
+ Links []*Link
11
+ Data []byte
12
+}
13
+
14
+
15
+// An IPFS Merkle DAG Link
16
+type Link {
17
+ // utf string name. should be unique per object
18
+ Name string // utf8
19
+
20
+ // cumulative size of target object
21
+ Size uint64
22
+
23
+ // multihash of the target object
24
+ Hash mh.Multihash
25
+}
26
+
27
+
28
+type EncodedNode []byte
29
+
30
+
31
+func (n *Node) Size() uint64 {
32
+ uint64 s = len(n.Encode())
33
+ for _, l := range(n.Links) {
34
+ s += l.Size
35
+ }
36
+}
merkledag/merkledag.proto
new
+40
@@ -0,0 +1,40 @@
1
+package merkledag
2
+
3
+import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
4
+
5
+option (gogoproto.gostring_all) = true;
6
+option (gogoproto.equal_all) = true;
7
+option (gogoproto.verbose_equal_all) = true;
8
+option (gogoproto.goproto_stringer_all) = false;
9
+option (gogoproto.stringer_all) = true;
10
+option (gogoproto.populate_all) = true;
11
+option (gogoproto.testgen_all) = true;
12
+option (gogoproto.benchgen_all) = true;
13
+option (gogoproto.marshaler_all) = true;
14
+option (gogoproto.sizer_all) = true;
15
+option (gogoproto.unmarshaler_all) = true;
16
+
17
+
18
+// An IPFS MerkleDAG Node
19
+message PBNode {
20
+
21
+ // refs to other objects
22
+ repeated Link Links = 2;
23
+
24
+ // opaque user data
25
+ optional bytes Data = 1;
26
+}
27
+
28
+
29
+// An IPFS MerkleDAG Link
30
+message PBLink {
31
+
32
+ // multihash of the target object
33
+ optional bytes Hash = 1;
34
+
35
+ // utf string name. should be unique per object
36
+ optional string Name = 2;
37
+
38
+ // cumulative size of target object
39
+ optional uint64 Size = 3;
40
+}