Skip to content

Commit

Permalink
Change IPFS to use the new pluggable Block to IPLD decoding framework.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Stebalien committed Jul 12, 2017
1 parent e8477b5 commit 35984c2
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 29 deletions.
27 changes: 27 additions & 0 deletions merkledag/coding.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package merkledag
import (
"fmt"
"sort"
"strings"

"gx/ipfs/QmVA4mafxbfH5aEvNz8fyoxC6J1xhAtw88B4GerPznSZBg/go-block-format"

pb "github.com/ipfs/go-ipfs/merkledag/pb"

Expand Down Expand Up @@ -108,3 +111,27 @@ func DecodeProtobuf(encoded []byte) (*ProtoNode, error) {
}
return n, nil
}

// DecodeProtobufBlock is a block decoder for protobuf IPLD nodes conforming to
// node.DecodeBlockFunc
func DecodeProtobufBlock(b blocks.Block) (node.Node, error) {
c := b.Cid()
if c.Type() != cid.DagProtobuf {
return nil, fmt.Errorf("this function can only decode protobuf nodes")
}

decnd, err := DecodeProtobuf(b.RawData())
if err != nil {
if strings.Contains(err.Error(), "Unmarshal failed") {
return nil, fmt.Errorf("The block referred to by '%s' was not a valid merkledag node", c)
}
return nil, fmt.Errorf("Failed to decode Protocol Buffers: %v", err)
}

decnd.cached = c
decnd.Prefix = c.Prefix()
return decnd, nil
}

// Type assertion
var _ node.DecodeBlockFunc = DecodeProtobufBlock
41 changes: 12 additions & 29 deletions merkledag/merkledag.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package merkledag
import (
"context"
"fmt"
"strings"
"sync"

bserv "github.com/ipfs/go-ipfs/blockservice"
Expand All @@ -16,6 +15,15 @@ import (
ipldcbor "gx/ipfs/QmemYymP73eVdTUUMZEiSpiHeZQKNJdT5dP2iuHssZh1sR/go-ipld-cbor"
)

// TODO: We should move these registrations elsewhere. Really, most of the IPLD
// functionality should go in a `go-ipld` repo but that will take a lot of work
// and design.
func init() {
node.Register(cid.DagProtobuf, DecodeProtobufBlock)
node.Register(cid.Raw, DecodeRawBlock)
node.Register(cid.DagCBOR, ipldcbor.DecodeBlock)
}

var ErrNotFound = fmt.Errorf("merkledag: not found")

// DAGService is an IPFS Merkle DAG service.
Expand Down Expand Up @@ -94,32 +102,7 @@ func (n *dagService) Get(ctx context.Context, c *cid.Cid) (node.Node, error) {
return nil, fmt.Errorf("Failed to get block for %s: %v", c, err)
}

return decodeBlock(b)
}

func decodeBlock(b blocks.Block) (node.Node, error) {
c := b.Cid()

switch c.Type() {
case cid.DagProtobuf:
decnd, err := DecodeProtobuf(b.RawData())
if err != nil {
if strings.Contains(err.Error(), "Unmarshal failed") {
return nil, fmt.Errorf("The block referred to by '%s' was not a valid merkledag node", c)
}
return nil, fmt.Errorf("Failed to decode Protocol Buffers: %v", err)
}

decnd.cached = b.Cid()
decnd.Prefix = b.Cid().Prefix()
return decnd, nil
case cid.Raw:
return NewRawNodeWPrefix(b.RawData(), b.Cid().Prefix())
case cid.DagCBOR:
return ipldcbor.Decode(b.RawData())
default:
return nil, fmt.Errorf("unrecognized object type: %s", c.Type())
}
return node.Decode(b)
}

// GetLinks return the links for the node, the node doesn't necessarily have
Expand Down Expand Up @@ -174,7 +157,7 @@ func (sg *sesGetter) Get(ctx context.Context, c *cid.Cid) (node.Node, error) {
return nil, err
}

return decodeBlock(blk)
return node.Decode(blk)
}

// FetchGraph fetches all nodes that are children of the given node
Expand Down Expand Up @@ -235,7 +218,7 @@ func (ds *dagService) GetMany(ctx context.Context, keys []*cid.Cid) <-chan *Node
return
}

nd, err := decodeBlock(b)
nd, err := node.Decode(b)
if err != nil {
out <- &NodeOption{Err: err}
return
Expand Down
12 changes: 12 additions & 0 deletions merkledag/raw.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package merkledag

import (
"fmt"
"gx/ipfs/QmVA4mafxbfH5aEvNz8fyoxC6J1xhAtw88B4GerPznSZBg/go-block-format"

u "gx/ipfs/QmSU6eubNdhXjFBJBSksTp8kv8YRub8mGAPv8tVJHmL2EU/go-ipfs-util"
Expand All @@ -22,6 +23,17 @@ func NewRawNode(data []byte) *RawNode {
return &RawNode{blk}
}

// DecodeRawBlock is a block decoder for raw IPLD nodes conforming to `node.DecodeBlockFunc`.
func DecodeRawBlock(block blocks.Block) (node.Node, error) {
if block.Cid().Type() != cid.Raw {
return nil, fmt.Errorf("raw nodes cannot be decoded from non-raw blocks: %d", block.Cid().Type())
}
// Once you "share" a block, it should be immutable. Therefore, we can just use this block as-is.
return &RawNode{block}, nil
}

var _ node.DecodeBlockFunc = DecodeRawBlock

// NewRawNodeWPrefix creates a RawNode with the hash function
// specified in prefix.
func NewRawNodeWPrefix(data []byte, prefix cid.Prefix) (*RawNode, error) {
Expand Down

0 comments on commit 35984c2

Please sign in to comment.