Skip to content

Commit

Permalink
Merge pull request #3443 from ipfs/feat/retain-cid-type
Browse files Browse the repository at this point in the history
merkledag: retain cid types when roundtripping through a ProtoNode
  • Loading branch information
whyrusleeping authored Dec 5, 2016
2 parents cdd5285 + 13f6528 commit 0814a99
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 6 deletions.
11 changes: 9 additions & 2 deletions merkledag/coding.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
pb "github.com/ipfs/go-ipfs/merkledag/pb"

node "gx/ipfs/QmRSU5EqqWVZSNdbU51yXmVoF1uNw3JgTNB6RaiL7DZM16/go-ipld-node"
u "gx/ipfs/Qmb912gdngC1UWwTkhuW8knyRbcWeu5kqkxBpveLmW8bSr/go-ipfs-util"
cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid"
)

Expand Down Expand Up @@ -84,7 +83,15 @@ func (n *ProtoNode) EncodeProtobuf(force bool) ([]byte, error) {
}

if n.cached == nil {
n.cached = cid.NewCidV0(u.Hash(n.encoded))
if n.Prefix.Codec == 0 { // unset
n.Prefix = defaultCidPrefix
}
c, err := n.Prefix.Sum(n.encoded)
if err != nil {
return nil, err
}

n.cached = c
}

return n.encoded, nil
Expand Down
1 change: 1 addition & 0 deletions merkledag/merkledag.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ func decodeBlock(b blocks.Block) (node.Node, error) {
}

decnd.cached = b.Cid()
decnd.Prefix = b.Cid().Prefix()
return decnd, nil
case cid.Raw:
return NewRawNode(b.RawData()), nil
Expand Down
35 changes: 35 additions & 0 deletions merkledag/merkledag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"sync"
"testing"

blocks "github.com/ipfs/go-ipfs/blocks"
bserv "github.com/ipfs/go-ipfs/blockservice"
bstest "github.com/ipfs/go-ipfs/blockservice/test"
offline "github.com/ipfs/go-ipfs/exchange/offline"
Expand Down Expand Up @@ -450,3 +451,37 @@ func TestProtoNodeResolve(t *testing.T) {
t.Fatal("expected tree to return []{\"foo\"}")
}
}

func TestCidRetention(t *testing.T) {
nd := new(ProtoNode)
nd.SetData([]byte("fooooo"))

pref := nd.Cid().Prefix()
pref.Version = 1

c2, err := pref.Sum(nd.RawData())
if err != nil {
t.Fatal(err)
}

blk, err := blocks.NewBlockWithCid(nd.RawData(), c2)
if err != nil {
t.Fatal(err)
}

bs := dstest.Bserv()
_, err = bs.AddBlock(blk)
if err != nil {
t.Fatal(err)
}

ds := NewDAGService(bs)
out, err := ds.Get(context.Background(), c2)
if err != nil {
t.Fatal(err)
}

if !out.Cid().Equals(c2) {
t.Fatal("output cid didnt match")
}
}
27 changes: 25 additions & 2 deletions merkledag/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ type ProtoNode struct {
encoded []byte

cached *cid.Cid

// Prefix specifies cid version and hashing function
Prefix cid.Prefix
}

var defaultCidPrefix = cid.Prefix{
Codec: cid.DagProtobuf,
MhLength: -1,
MhType: mh.SHA2_256,
Version: 0,
}

type LinkSlice []*node.Link
Expand Down Expand Up @@ -219,9 +229,22 @@ func (n *ProtoNode) Loggable() map[string]interface{} {
}

func (n *ProtoNode) Cid() *cid.Cid {
h := n.Multihash()
if n.encoded != nil && n.cached != nil {
return n.cached
}

if n.Prefix.Codec == 0 {
n.Prefix = defaultCidPrefix
}

c, err := n.Prefix.Sum(n.RawData())
if err != nil {
// programmer error
panic(err)
}

return cid.NewCidV0(h)
n.cached = c
return c
}

func (n *ProtoNode) String() string {
Expand Down
7 changes: 5 additions & 2 deletions merkledag/test/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import (
)

func Mock() dag.DAGService {
return dag.NewDAGService(Bserv())
}

func Bserv() bsrv.BlockService {
bstore := blockstore.NewBlockstore(dssync.MutexWrap(ds.NewMapDatastore()))
bserv := bsrv.New(bstore, offline.Exchange(bstore))
return dag.NewDAGService(bserv)
return bsrv.New(bstore, offline.Exchange(bstore))
}

0 comments on commit 0814a99

Please sign in to comment.