Commit 1268b9cc authored by Jeromy's avatar Jeromy

integrate CIDv0

License: MIT
Signed-off-by: default avatarJeromy <why@ipfs.io>
parent 113e2390
......@@ -4,10 +4,11 @@ import (
"fmt"
"sort"
mh "gx/ipfs/QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku/go-multihash"
pb "github.com/ipfs/go-ipfs/merkledag/pb"
mh "gx/ipfs/QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku/go-multihash"
u "gx/ipfs/QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1/go-ipfs-util"
cid "gx/ipfs/QmfSc2xehWmWLnwwYR91Y8QF4xdASypTFVknutoKQS3GHp/go-cid"
)
// for now, we use a PBNode intermediate thing.
......@@ -83,7 +84,7 @@ func (n *Node) EncodeProtobuf(force bool) ([]byte, error) {
}
if n.cached == nil {
n.cached = u.Hash(n.encoded)
n.cached = cid.NewCidV0(u.Hash(n.encoded))
}
return n.encoded, nil
......
......@@ -6,11 +6,12 @@ import (
"strings"
"sync"
blocks "github.com/ipfs/go-ipfs/blocks"
key "github.com/ipfs/go-ipfs/blocks/key"
bserv "github.com/ipfs/go-ipfs/blockservice"
logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
"gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context"
cid "gx/ipfs/QmfSc2xehWmWLnwwYR91Y8QF4xdASypTFVknutoKQS3GHp/go-cid"
)
var log = logging.Logger("merkledag")
......@@ -18,13 +19,13 @@ var ErrNotFound = fmt.Errorf("merkledag: not found")
// DAGService is an IPFS Merkle DAG service.
type DAGService interface {
Add(*Node) (key.Key, error)
Get(context.Context, key.Key) (*Node, error)
Add(*Node) (*cid.Cid, error)
Get(context.Context, *cid.Cid) (*Node, error)
Remove(*Node) error
// GetDAG returns, in order, all the single leve child
// nodes of the passed in node.
GetMany(context.Context, []key.Key) <-chan *NodeOption
GetMany(context.Context, []*cid.Cid) <-chan *NodeOption
Batch() *Batch
}
......@@ -43,24 +44,12 @@ type dagService struct {
}
// Add adds a node to the dagService, storing the block in the BlockService
func (n *dagService) Add(nd *Node) (key.Key, error) {
func (n *dagService) Add(nd *Node) (*cid.Cid, error) {
if n == nil { // FIXME remove this assertion. protect with constructor invariant
return "", fmt.Errorf("dagService is nil")
}
d, err := nd.EncodeProtobuf(false)
if err != nil {
return "", err
}
mh, err := nd.Multihash()
if err != nil {
return "", err
return nil, fmt.Errorf("dagService is nil")
}
b, _ := blocks.NewBlockWithHash(d, mh)
return n.Blocks.AddBlock(b)
return n.Blocks.AddObject(nd)
}
func (n *dagService) Batch() *Batch {
......@@ -68,56 +57,57 @@ func (n *dagService) Batch() *Batch {
}
// Get retrieves a node from the dagService, fetching the block in the BlockService
func (n *dagService) Get(ctx context.Context, k key.Key) (*Node, error) {
if k == "" {
return nil, ErrNotFound
}
func (n *dagService) Get(ctx context.Context, c *cid.Cid) (*Node, error) {
if n == nil {
return nil, fmt.Errorf("dagService is nil")
}
ctx, cancel := context.WithCancel(ctx)
defer cancel()
b, err := n.Blocks.GetBlock(ctx, k)
b, err := n.Blocks.GetBlock(ctx, c)
if err != nil {
if err == bserv.ErrNotFound {
return nil, ErrNotFound
}
return nil, fmt.Errorf("Failed to get block for %s: %v", k.B58String(), err)
return nil, fmt.Errorf("Failed to get block for %s: %v", c, err)
}
res, err := DecodeProtobuf(b.Data())
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", k)
var res *Node
switch c.Type() {
case cid.Protobuf:
out, 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)
}
return nil, fmt.Errorf("Failed to decode Protocol Buffers: %v", err)
res = out
default:
return nil, fmt.Errorf("unrecognized formatting type")
}
res.cached = k.ToMultihash()
res.cached = c
return res, nil
}
func (n *dagService) Remove(nd *Node) error {
k, err := nd.Key()
if err != nil {
return err
}
return n.Blocks.DeleteBlock(k)
return n.Blocks.DeleteObject(nd)
}
// FetchGraph fetches all nodes that are children of the given node
func FetchGraph(ctx context.Context, root *Node, serv DAGService) error {
return EnumerateChildrenAsync(ctx, serv, root, key.NewKeySet())
return EnumerateChildrenAsync(ctx, serv, root, cid.NewSet().Visit)
}
// FindLinks searches this nodes links for the given key,
// returns the indexes of any links pointing to it
func FindLinks(links []key.Key, k key.Key, start int) []int {
func FindLinks(links []*cid.Cid, c *cid.Cid, start int) []int {
var out []int
for i, lnk_k := range links[start:] {
if k == lnk_k {
for i, lnk_c := range links[start:] {
if c.Equals(lnk_c) {
out = append(out, i+start)
}
}
......@@ -129,11 +119,21 @@ type NodeOption struct {
Err error
}
func (ds *dagService) GetMany(ctx context.Context, keys []key.Key) <-chan *NodeOption {
func cidsToKeyMapping(cids []*cid.Cid) map[key.Key]*cid.Cid {
mapping := make(map[key.Key]*cid.Cid)
for _, c := range cids {
mapping[key.Key(c.Hash())] = c
}
return mapping
}
func (ds *dagService) GetMany(ctx context.Context, keys []*cid.Cid) <-chan *NodeOption {
out := make(chan *NodeOption, len(keys))
blocks := ds.Blocks.GetBlocks(ctx, keys)
var count int
mapping := cidsToKeyMapping(keys)
go func() {
defer close(out)
for {
......@@ -145,12 +145,23 @@ func (ds *dagService) GetMany(ctx context.Context, keys []key.Key) <-chan *NodeO
}
return
}
nd, err := DecodeProtobuf(b.Data())
if err != nil {
out <- &NodeOption{Err: err}
c := mapping[b.Key()]
var nd *Node
switch c.Type() {
case cid.Protobuf:
decnd, err := DecodeProtobuf(b.RawData())
if err != nil {
out <- &NodeOption{Err: err}
return
}
decnd.cached = cid.NewCidV0(b.Multihash())
nd = decnd
default:
out <- &NodeOption{Err: fmt.Errorf("unrecognized object type: %s", c.Type())}
return
}
nd.cached = b.Key().ToMultihash()
// buffered, no need to select
out <- &NodeOption{Node: nd}
......@@ -169,17 +180,17 @@ func (ds *dagService) GetMany(ctx context.Context, keys []key.Key) <-chan *NodeO
// It returns a channel of nodes, which the caller can receive
// all the child nodes of 'root' on, in proper order.
func GetDAG(ctx context.Context, ds DAGService, root *Node) []NodeGetter {
var keys []key.Key
var cids []*cid.Cid
for _, lnk := range root.Links {
keys = append(keys, key.Key(lnk.Hash))
cids = append(cids, cid.NewCidV0(lnk.Hash))
}
return GetNodes(ctx, ds, keys)
return GetNodes(ctx, ds, cids)
}
// GetNodes returns an array of 'NodeGetter' promises, with each corresponding
// to the key with the same index as the passed in keys
func GetNodes(ctx context.Context, ds DAGService, keys []key.Key) []NodeGetter {
func GetNodes(ctx context.Context, ds DAGService, keys []*cid.Cid) []NodeGetter {
// Early out if no work to do
if len(keys) == 0 {
......@@ -216,14 +227,7 @@ func GetNodes(ctx context.Context, ds DAGService, keys []key.Key) []NodeGetter {
}
nd := opt.Node
k, err := nd.Key()
if err != nil {
log.Error("Failed to get node key: ", err)
continue
}
is := FindLinks(keys, k, 0)
is := FindLinks(keys, nd.Cid(), 0)
for _, i := range is {
count++
promises[i].Send(nd)
......@@ -237,16 +241,12 @@ func GetNodes(ctx context.Context, ds DAGService, keys []key.Key) []NodeGetter {
}
// Remove duplicates from a list of keys
func dedupeKeys(ks []key.Key) []key.Key {
kmap := make(map[key.Key]struct{})
var out []key.Key
for _, k := range ks {
if _, ok := kmap[k]; !ok {
kmap[k] = struct{}{}
out = append(out, k)
}
func dedupeKeys(cids []*cid.Cid) []*cid.Cid {
set := cid.NewSet()
for _, c := range cids {
set.Add(c)
}
return out
return set.Keys()
}
func newNodePromise(ctx context.Context) NodeGetter {
......@@ -327,50 +327,44 @@ func (np *nodePromise) Get(ctx context.Context) (*Node, error) {
type Batch struct {
ds *dagService
blocks []blocks.Block
objects []bserv.Object
size int
MaxSize int
}
func (t *Batch) Add(nd *Node) (key.Key, error) {
func (t *Batch) Add(nd *Node) (*cid.Cid, error) {
d, err := nd.EncodeProtobuf(false)
if err != nil {
return "", err
}
mh, err := nd.Multihash()
if err != nil {
return "", err
return nil, err
}
b, _ := blocks.NewBlockWithHash(d, mh)
k := key.Key(mh)
t.blocks = append(t.blocks, b)
t.size += len(b.Data())
t.objects = append(t.objects, nd)
t.size += len(d)
if t.size > t.MaxSize {
return k, t.Commit()
return nd.Cid(), t.Commit()
}
return k, nil
return nd.Cid(), nil
}
func (t *Batch) Commit() error {
_, err := t.ds.Blocks.AddBlocks(t.blocks)
t.blocks = nil
_, err := t.ds.Blocks.AddObjects(t.objects)
t.objects = nil
t.size = 0
return err
}
func legacyCidFromLink(lnk *Link) *cid.Cid {
return cid.NewCidV0(lnk.Hash)
}
// EnumerateChildren will walk the dag below the given root node and add all
// unseen children to the passed in set.
// TODO: parallelize to avoid disk latency perf hits?
func EnumerateChildren(ctx context.Context, ds DAGService, root *Node, set key.KeySet, bestEffort bool) error {
func EnumerateChildren(ctx context.Context, ds DAGService, root *Node, visit func(*cid.Cid) bool, bestEffort bool) error {
for _, lnk := range root.Links {
k := key.Key(lnk.Hash)
if !set.Has(k) {
set.Add(k)
child, err := ds.Get(ctx, k)
c := legacyCidFromLink(lnk)
if visit(c) {
child, err := ds.Get(ctx, c)
if err != nil {
if bestEffort && err == ErrNotFound {
continue
......@@ -378,7 +372,7 @@ func EnumerateChildren(ctx context.Context, ds DAGService, root *Node, set key.K
return err
}
}
err = EnumerateChildren(ctx, ds, child, set, bestEffort)
err = EnumerateChildren(ctx, ds, child, visit, bestEffort)
if err != nil {
return err
}
......@@ -387,8 +381,8 @@ func EnumerateChildren(ctx context.Context, ds DAGService, root *Node, set key.K
return nil
}
func EnumerateChildrenAsync(ctx context.Context, ds DAGService, root *Node, set key.KeySet) error {
toprocess := make(chan []key.Key, 8)
func EnumerateChildrenAsync(ctx context.Context, ds DAGService, root *Node, visit func(*cid.Cid) bool) error {
toprocess := make(chan []*cid.Cid, 8)
nodes := make(chan *NodeOption, 8)
ctx, cancel := context.WithCancel(ctx)
......@@ -416,13 +410,12 @@ func EnumerateChildrenAsync(ctx context.Context, ds DAGService, root *Node, set
// a node has been fetched
live--
var keys []key.Key
var cids []*cid.Cid
for _, lnk := range nd.Links {
k := key.Key(lnk.Hash)
if !set.Has(k) {
set.Add(k)
c := legacyCidFromLink(lnk)
if visit(c) {
live++
keys = append(keys, k)
cids = append(cids, c)
}
}
......@@ -430,9 +423,9 @@ func EnumerateChildrenAsync(ctx context.Context, ds DAGService, root *Node, set
return nil
}
if len(keys) > 0 {
if len(cids) > 0 {
select {
case toprocess <- keys:
case toprocess <- cids:
case <-ctx.Done():
return ctx.Err()
}
......@@ -443,7 +436,7 @@ func EnumerateChildrenAsync(ctx context.Context, ds DAGService, root *Node, set
}
}
func fetchNodes(ctx context.Context, ds DAGService, in <-chan []key.Key, out chan<- *NodeOption) {
func fetchNodes(ctx context.Context, ds DAGService, in <-chan []*cid.Cid, out chan<- *NodeOption) {
var wg sync.WaitGroup
defer func() {
// wait for all 'get' calls to complete so we don't accidentally send
......@@ -452,7 +445,7 @@ func fetchNodes(ctx context.Context, ds DAGService, in <-chan []key.Key, out cha
close(out)
}()
get := func(ks []key.Key) {
get := func(ks []*cid.Cid) {
defer wg.Done()
nodes := ds.GetMany(ctx, ks)
for opt := range nodes {
......
......@@ -20,8 +20,10 @@ import (
mdpb "github.com/ipfs/go-ipfs/merkledag/pb"
dstest "github.com/ipfs/go-ipfs/merkledag/test"
uio "github.com/ipfs/go-ipfs/unixfs/io"
u "gx/ipfs/QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1/go-ipfs-util"
"gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context"
cid "gx/ipfs/QmfSc2xehWmWLnwwYR91Y8QF4xdASypTFVknutoKQS3GHp/go-cid"
)
func TestNode(t *testing.T) {
......@@ -52,17 +54,9 @@ func TestNode(t *testing.T) {
fmt.Println("encoded:", e)
}
h, err := n.Multihash()
if err != nil {
t.Error(err)
} else {
fmt.Println("hash:", h)
}
k, err := n.Key()
if err != nil {
t.Error(err)
} else if k != key.Key(h) {
h := n.Multihash()
k := n.Key()
if k != key.Key(h) {
t.Error("Key is not equivalent to multihash")
} else {
fmt.Println("key: ", k)
......@@ -89,11 +83,7 @@ func SubtestNodeStat(t *testing.T, n *Node) {
return
}
k, err := n.Key()
if err != nil {
t.Error("n.Key() failed")
return
}
k := n.Key()
expected := NodeStat{
NumLinks: len(n.Links),
......@@ -169,10 +159,7 @@ func runBatchFetchTest(t *testing.T, read io.Reader) {
t.Log("Added file to first node.")
k, err := root.Key()
if err != nil {
t.Fatal(err)
}
c := root.Cid()
wg := sync.WaitGroup{}
errs := make(chan error)
......@@ -181,7 +168,7 @@ func runBatchFetchTest(t *testing.T, read io.Reader) {
wg.Add(1)
go func(i int) {
defer wg.Done()
first, err := dagservs[i].Get(ctx, k)
first, err := dagservs[i].Get(ctx, c)
if err != nil {
errs <- err
}
......@@ -215,34 +202,17 @@ func runBatchFetchTest(t *testing.T, read io.Reader) {
}
func assertCanGet(t *testing.T, ds DAGService, n *Node) {
k, err := n.Key()
if err != nil {
t.Fatal(err)
}
if _, err := ds.Get(context.Background(), k); err != nil {
if _, err := ds.Get(context.Background(), n.Cid()); err != nil {
t.Fatal(err)
}
}
func TestEmptyKey(t *testing.T) {
ds := dstest.Mock()
_, err := ds.Get(context.Background(), key.Key(""))
if err != ErrNotFound {
t.Error("dag service should error when key is nil", err)
}
}
func TestCantGet(t *testing.T) {
ds := dstest.Mock()
a := NodeWithData([]byte("A"))
k, err := a.Key()
if err != nil {
t.Fatal(err)
}
_, err = ds.Get(context.Background(), k)
c := a.Cid()
_, err := ds.Get(context.Background(), c)
if !strings.Contains(err.Error(), "not found") {
t.Fatal("expected err not found, got: ", err)
}
......@@ -270,9 +240,8 @@ func TestFetchGraph(t *testing.T) {
bs := bserv.New(bsis[1].Blockstore, offline.Exchange(bsis[1].Blockstore))
offline_ds := NewDAGService(bs)
ks := key.NewKeySet()
err = EnumerateChildren(context.Background(), offline_ds, root, ks, false)
err = EnumerateChildren(context.Background(), offline_ds, root, func(_ *cid.Cid) bool { return true }, false)
if err != nil {
t.Fatal(err)
}
......@@ -288,8 +257,8 @@ func TestEnumerateChildren(t *testing.T) {
t.Fatal(err)
}
ks := key.NewKeySet()
err = EnumerateChildren(context.Background(), ds, root, ks, false)
set := cid.NewSet()
err = EnumerateChildren(context.Background(), ds, root, set.Visit, false)
if err != nil {
t.Fatal(err)
}
......@@ -298,11 +267,11 @@ func TestEnumerateChildren(t *testing.T) {
traverse = func(n *Node) {
// traverse dag and check
for _, lnk := range n.Links {
k := key.Key(lnk.Hash)
if !ks.Has(k) {
c := cid.NewCidV0(lnk.Hash)
if !set.Has(c) {
t.Fatal("missing key in set!")
}
child, err := ds.Get(context.Background(), k)
child, err := ds.Get(context.Background(), c)
if err != nil {
t.Fatal(err)
}
......@@ -379,3 +348,22 @@ func TestUnmarshalFailure(t *testing.T) {
n := &Node{}
n.Marshal()
}
func TestBasicAddGet(t *testing.T) {
ds := dstest.Mock()
nd := new(Node)
c, err := ds.Add(nd)
if err != nil {
t.Fatal(err)
}
out, err := ds.Get(context.Background(), c)
if err != nil {
t.Fatal(err)
}
if !nd.Cid().Equals(out.Cid()) {
t.Fatal("output didnt match input")
}
}
......@@ -7,6 +7,7 @@ import (
key "github.com/ipfs/go-ipfs/blocks/key"
mh "gx/ipfs/QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku/go-multihash"
cid "gx/ipfs/QmfSc2xehWmWLnwwYR91Y8QF4xdASypTFVknutoKQS3GHp/go-cid"
)
var ErrLinkNotFound = fmt.Errorf("no link by that name")
......@@ -20,7 +21,7 @@ type Node struct {
// cache encoded/marshaled value
encoded []byte
cached mh.Multihash
cached *cid.Cid
}
// NodeStat is a statistics object for a Node. Mostly sizes.
......@@ -63,10 +64,8 @@ func MakeLink(n *Node) (*Link, error) {
return nil, err
}
h, err := n.Multihash()
if err != nil {
return nil, err
}
h := n.Multihash()
return &Link{
Size: s,
Hash: h,
......@@ -75,7 +74,7 @@ func MakeLink(n *Node) (*Link, error) {
// GetNode returns the MDAG Node that this link points to
func (l *Link) GetNode(ctx context.Context, serv DAGService) (*Node, error) {
return serv.Get(ctx, key.Key(l.Hash))
return serv.Get(ctx, legacyCidFromLink(l))
}
func NodeWithData(d []byte) *Node {
......@@ -184,6 +183,11 @@ func (n *Node) Copy() *Node {
return nnode
}
func (n *Node) RawData() []byte {
out, _ := n.EncodeProtobuf(false)
return out
}
func (n *Node) Data() []byte {
return n.data
}
......@@ -231,13 +235,8 @@ func (n *Node) Stat() (*NodeStat, error) {
return nil, err
}
key, err := n.Key()
if err != nil {
return nil, err
}
return &NodeStat{
Hash: key.B58String(),
Hash: n.Key().B58String(),
NumLinks: len(n.Links),
BlockSize: len(enc),
LinksSize: len(enc) - len(n.data), // includes framing.
......@@ -246,19 +245,34 @@ func (n *Node) Stat() (*NodeStat, error) {
}, nil
}
func (n *Node) Key() key.Key {
return key.Key(n.Multihash())
}
func (n *Node) Loggable() map[string]interface{} {
return map[string]interface{}{
"node": n.String(),
}
}
func (n *Node) Cid() *cid.Cid {
h := n.Multihash()
return cid.NewCidV0(h)
}
func (n *Node) String() string {
return n.Cid().String()
}
// Multihash hashes the encoded data of this node.
func (n *Node) Multihash() (mh.Multihash, error) {
func (n *Node) Multihash() mh.Multihash {
// NOTE: EncodeProtobuf generates the hash and puts it in n.cached.
_, err := n.EncodeProtobuf(false)
if err != nil {
return nil, err
// Note: no possibility exists for an error to be returned through here
panic(err)
}
return n.cached, nil
}
// Key returns the Multihash as a key, for maps.
func (n *Node) Key() (key.Key, error) {
h, err := n.Multihash()
return key.Key(h), err
return n.cached.Hash()
}
......@@ -67,9 +67,9 @@ func TestFindLink(t *testing.T) {
nd := &Node{
Links: []*Link{
&Link{Name: "a", Hash: k.ToMultihash()},
&Link{Name: "c", Hash: k.ToMultihash()},
&Link{Name: "b", Hash: k.ToMultihash()},
&Link{Name: "a", Hash: k.Hash()},
&Link{Name: "c", Hash: k.Hash()},
&Link{Name: "b", Hash: k.Hash()},
},
}
......@@ -107,7 +107,7 @@ func TestFindLink(t *testing.T) {
t.Fatal(err)
}
if olnk.Hash.B58String() == k.B58String() {
if olnk.Hash.B58String() == k.String() {
t.Fatal("new link should have different hash")
}
}
......
......@@ -41,11 +41,7 @@ type traversal struct {
func (t *traversal) shouldSkip(n *mdag.Node) (bool, error) {
if t.opts.SkipDuplicates {
k, err := n.Key()
if err != nil {
return true, err
}
k := n.Key()
if _, found := t.seen[string(k)]; found {
return true, nil
}
......
......@@ -5,9 +5,10 @@ import (
"fmt"
"path"
key "github.com/ipfs/go-ipfs/blocks/key"
dag "github.com/ipfs/go-ipfs/merkledag"
context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context"
cid "gx/ipfs/QmfSc2xehWmWLnwwYR91Y8QF4xdASypTFVknutoKQS3GHp/go-cid"
)
const (
......@@ -19,18 +20,18 @@ const (
type Change struct {
Type int
Path string
Before key.Key
After key.Key
Before *cid.Cid
After *cid.Cid
}
func (c *Change) String() string {
switch c.Type {
case Add:
return fmt.Sprintf("Added %s at %s", c.After.B58String()[:6], c.Path)
return fmt.Sprintf("Added %s at %s", c.After.String(), c.Path)
case Remove:
return fmt.Sprintf("Removed %s from %s", c.Before.B58String()[:6], c.Path)
return fmt.Sprintf("Removed %s from %s", c.Before.String(), c.Path)
case Mod:
return fmt.Sprintf("Changed %s to %s at %s", c.Before.B58String()[:6], c.After.B58String()[:6], c.Path)
return fmt.Sprintf("Changed %s to %s at %s", c.Before.String(), c.After.String(), c.Path)
default:
panic("nope")
}
......@@ -77,21 +78,11 @@ func ApplyChange(ctx context.Context, ds dag.DAGService, nd *dag.Node, cs []*Cha
func Diff(ctx context.Context, ds dag.DAGService, a, b *dag.Node) ([]*Change, error) {
if len(a.Links) == 0 && len(b.Links) == 0 {
ak, err := a.Key()
if err != nil {
return nil, err
}
bk, err := b.Key()
if err != nil {
return nil, err
}
return []*Change{
&Change{
Type: Mod,
Before: ak,
After: bk,
Before: a.Cid(),
After: b.Cid(),
},
}, nil
}
......@@ -136,14 +127,14 @@ func Diff(ctx context.Context, ds dag.DAGService, a, b *dag.Node) ([]*Change, er
out = append(out, &Change{
Type: Remove,
Path: lnk.Name,
Before: key.Key(lnk.Hash),
Before: cid.NewCidV0(lnk.Hash),
})
}
for _, lnk := range clean_b.Links {
out = append(out, &Change{
Type: Add,
Path: lnk.Name,
After: key.Key(lnk.Hash),
After: cid.NewCidV0(lnk.Hash),
})
}
......
......@@ -3,12 +3,12 @@ package dagutils
import (
"testing"
key "github.com/ipfs/go-ipfs/blocks/key"
dag "github.com/ipfs/go-ipfs/merkledag"
mdtest "github.com/ipfs/go-ipfs/merkledag/test"
path "github.com/ipfs/go-ipfs/path"
context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context"
cid "gx/ipfs/QmfSc2xehWmWLnwwYR91Y8QF4xdASypTFVknutoKQS3GHp/go-cid"
)
func TestAddLink(t *testing.T) {
......@@ -31,17 +31,13 @@ func TestAddLink(t *testing.T) {
t.Fatal(err)
}
fnpkey, err := fnprime.Key()
if err != nil {
t.Fatal(err)
}
if fnpkey != fk {
fnpkey := fnprime.Cid()
if !fnpkey.Equals(fk) {
t.Fatal("wrong child node found!")
}
}
func assertNodeAtPath(t *testing.T, ds dag.DAGService, root *dag.Node, pth string, exp key.Key) {
func assertNodeAtPath(t *testing.T, ds dag.DAGService, root *dag.Node, pth string, exp *cid.Cid) {
parts := path.SplitList(pth)
cur := root
for _, e := range parts {
......@@ -53,12 +49,8 @@ func assertNodeAtPath(t *testing.T, ds dag.DAGService, root *dag.Node, pth strin
cur = nxt
}
curk, err := cur.Key()
if err != nil {
t.Fatal(err)
}
if curk != exp {
curc := cur.Cid()
if !curc.Equals(exp) {
t.Fatal("node not as expected at end of path")
}
}
......@@ -77,13 +69,10 @@ func TestInsertNode(t *testing.T) {
testInsert(t, e, "", "bar", true, "cannot create link with no name!")
testInsert(t, e, "////", "slashes", true, "cannot create link with no name!")
k, err := e.GetNode().Key()
if err != nil {
t.Fatal(err)
}
c := e.GetNode().Cid()
if k.B58String() != "QmZ8yeT9uD6ouJPNAYt62XffYuXBT6b4mP4obRSE9cJrSt" {
t.Fatal("output was different than expected: ", k)
if c.String() != "QmZ8yeT9uD6ouJPNAYt62XffYuXBT6b4mP4obRSE9cJrSt" {
t.Fatal("output was different than expected: ", c)
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment