@cryptotaxi247 / kubo / commits / 35984c2c8

Change IPFS to use the new pluggable Block to IPLD decoding framework.

Later, we should: 1. Pull the other node formats out of IPFS (at least the raw one). 2. Pull out the decoder registration/management into a `go-ipld` library. License: MIT Signed-off-by: Steven Allen <steven@stebalien.com>

Steven Allen committed Jul 11, 2017 at 20:27 UTC 35984c2c884ddcb676abd142e58c8b80301398b8
3 files changed +51 -29
merkledag/coding.go
+27
@@ -3,6 +3,9 @@ package merkledag
3 import (
4 "fmt"
5 "sort"
6 + "strings"
7 +
8 + "gx/ipfs/QmVA4mafxbfH5aEvNz8fyoxC6J1xhAtw88B4GerPznSZBg/go-block-format"
9
10 pb "github.com/ipfs/go-ipfs/merkledag/pb"
11
@@ -108,3 +111,27 @@ func DecodeProtobuf(encoded []byte) (*ProtoNode, error) {
111 }
112 return n, nil
113 }
114 +
115 +// DecodeProtobufBlock is a block decoder for protobuf IPLD nodes conforming to
116 +// node.DecodeBlockFunc
117 +func DecodeProtobufBlock(b blocks.Block) (node.Node, error) {
118 + c := b.Cid()
119 + if c.Type() != cid.DagProtobuf {
120 + return nil, fmt.Errorf("this function can only decode protobuf nodes")
121 + }
122 +
123 + decnd, err := DecodeProtobuf(b.RawData())
124 + if err != nil {
125 + if strings.Contains(err.Error(), "Unmarshal failed") {
126 + return nil, fmt.Errorf("The block referred to by '%s' was not a valid merkledag node", c)
127 + }
128 + return nil, fmt.Errorf("Failed to decode Protocol Buffers: %v", err)
129 + }
130 +
131 + decnd.cached = c
132 + decnd.Prefix = c.Prefix()
133 + return decnd, nil
134 +}
135 +
136 +// Type assertion
137 +var _ node.DecodeBlockFunc = DecodeProtobufBlock
merkledag/merkledag.go
+12 -29
@@ -4,7 +4,6 @@ package merkledag
4 import (
5 "context"
6 "fmt"
7 - "strings"
7 "sync"
8
9 bserv "github.com/ipfs/go-ipfs/blockservice"
@@ -16,6 +15,15 @@ import (
15 ipldcbor "gx/ipfs/QmemYymP73eVdTUUMZEiSpiHeZQKNJdT5dP2iuHssZh1sR/go-ipld-cbor"
16 )
17
18 +// TODO: We should move these registrations elsewhere. Really, most of the IPLD
19 +// functionality should go in a `go-ipld` repo but that will take a lot of work
20 +// and design.
21 +func init() {
22 + node.Register(cid.DagProtobuf, DecodeProtobufBlock)
23 + node.Register(cid.Raw, DecodeRawBlock)
24 + node.Register(cid.DagCBOR, ipldcbor.DecodeBlock)
25 +}
26 +
27 var ErrNotFound = fmt.Errorf("merkledag: not found")
28
29 // DAGService is an IPFS Merkle DAG service.
@@ -94,32 +102,7 @@ func (n *dagService) Get(ctx context.Context, c *cid.Cid) (node.Node, error) {
102 return nil, fmt.Errorf("Failed to get block for %s: %v", c, err)
103 }
104
97 - return decodeBlock(b)
98 -}
99 -
100 -func decodeBlock(b blocks.Block) (node.Node, error) {
101 - c := b.Cid()
102 -
103 - switch c.Type() {
104 - case cid.DagProtobuf:
105 - decnd, err := DecodeProtobuf(b.RawData())
106 - if err != nil {
107 - if strings.Contains(err.Error(), "Unmarshal failed") {
108 - return nil, fmt.Errorf("The block referred to by '%s' was not a valid merkledag node", c)
109 - }
110 - return nil, fmt.Errorf("Failed to decode Protocol Buffers: %v", err)
111 - }
112 -
113 - decnd.cached = b.Cid()
114 - decnd.Prefix = b.Cid().Prefix()
115 - return decnd, nil
116 - case cid.Raw:
117 - return NewRawNodeWPrefix(b.RawData(), b.Cid().Prefix())
118 - case cid.DagCBOR:
119 - return ipldcbor.Decode(b.RawData())
120 - default:
121 - return nil, fmt.Errorf("unrecognized object type: %s", c.Type())
122 - }
105 + return node.Decode(b)
106 }
107
108 // GetLinks return the links for the node, the node doesn't necessarily have
@@ -174,7 +157,7 @@ func (sg *sesGetter) Get(ctx context.Context, c *cid.Cid) (node.Node, error) {
157 return nil, err
158 }
159
177 - return decodeBlock(blk)
160 + return node.Decode(blk)
161 }
162
163 // FetchGraph fetches all nodes that are children of the given node
@@ -235,7 +218,7 @@ func (ds *dagService) GetMany(ctx context.Context, keys []*cid.Cid) <-chan *Node
218 return
219 }
220
238 - nd, err := decodeBlock(b)
221 + nd, err := node.Decode(b)
222 if err != nil {
223 out <- &NodeOption{Err: err}
224 return
merkledag/raw.go
+12
@@ -1,6 +1,7 @@
1 package merkledag
2
3 import (
4 + "fmt"
5 "gx/ipfs/QmVA4mafxbfH5aEvNz8fyoxC6J1xhAtw88B4GerPznSZBg/go-block-format"
6
7 u "gx/ipfs/QmSU6eubNdhXjFBJBSksTp8kv8YRub8mGAPv8tVJHmL2EU/go-ipfs-util"
@@ -22,6 +23,17 @@ func NewRawNode(data []byte) *RawNode {
23 return &RawNode{blk}
24 }
25
26 +// DecodeRawBlock is a block decoder for raw IPLD nodes conforming to `node.DecodeBlockFunc`.
27 +func DecodeRawBlock(block blocks.Block) (node.Node, error) {
28 + if block.Cid().Type() != cid.Raw {
29 + return nil, fmt.Errorf("raw nodes cannot be decoded from non-raw blocks: %d", block.Cid().Type())
30 + }
31 + // Once you "share" a block, it should be immutable. Therefore, we can just use this block as-is.
32 + return &RawNode{block}, nil
33 +}
34 +
35 +var _ node.DecodeBlockFunc = DecodeRawBlock
36 +
37 // NewRawNodeWPrefix creates a RawNode with the hash function
38 // specified in prefix.
39 func NewRawNodeWPrefix(data []byte, prefix cid.Prefix) (*RawNode, error) {