func FetchGraph(ctx context.Context, root cid.Cid, serv format.DAGService) error {
	return FetchGraphWithDepthLimit(ctx, root, -1, serv)
}
FetchGraph fetches all nodes that are children of the given node
package merkledag
import (
	"context"
	"fmt"
	"sync"
	blocks "github.com/ipfs/go-block-format"
	bserv "github.com/ipfs/go-blockservice"
	cid "github.com/ipfs/go-cid"
	ipldcbor "github.com/ipfs/go-ipld-cbor"
	format "github.com/ipfs/go-ipld-format"
	legacy "github.com/ipfs/go-ipld-legacy"
	dagpb "github.com/ipld/go-codec-dagpb"
	_ "github.com/ipld/go-ipld-prime/codec/raw"
	basicnode "github.com/ipld/go-ipld-prime/node/basic"
)
func init() {
	format.Register(cid.DagProtobuf, DecodeProtobufBlock)
	format.Register(cid.Raw, DecodeRawBlock)
	format.Register(cid.DagCBOR, ipldcbor.DecodeBlock)
	legacy.RegisterCodec(cid.DagProtobuf, dagpb.Type.PBNode, ProtoNodeConverter)
	legacy.RegisterCodec(cid.Raw, basicnode.Prototype.Bytes, RawNodeConverter)
}
type contextKey string
const progressContextKey contextKey = "progress"
func NewDAGService(bs bserv.BlockService) *dagService {
	return &dagService{Blocks: bs}
}
type dagService struct {
	Blocks bserv.BlockService
}
func (n *dagService) Add(ctx context.Context, nd format.Node) error {
	if n == nil {  
		return fmt.Errorf("dagService is nil")
	}
	return n.Blocks.AddBlock(nd)
}
func (n *dagService) AddMany(ctx context.Context, nds []format.Node) error {
	blks := make([]blocks.Block, len(nds))
	for i, nd := range nds {
		blks[i] = nd
	}
	return n.Blocks.AddBlocks(blks)
}
func (n *dagService) Get(ctx context.Context, c cid.Cid) (format.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, c)
	if err != nil {
		if err == bserv.ErrNotFound {
			return nil, format.ErrNotFound
		}
		return nil, fmt.Errorf("failed to get block for %s: %v", c, err)
	}
	return legacy.DecodeNode(ctx, b)
}
func (n *dagService) GetLinks(ctx context.Context, c cid.Cid) ([]*format.Link, error) {
	if c.Type() == cid.Raw {
		return nil, nil
	}
	node, err := n.Get(ctx, c)
	if err != nil {
		return nil, err
	}
	return node.Links(), nil
}
func (n *dagService) Remove(ctx context.Context, c cid.Cid) error {
	return n.Blocks.DeleteBlock(c)
}
func (n *dagService) RemoveMany(ctx context.Context, cids []cid.Cid) error {
	for _, c := range cids {
		if err := n.Blocks.DeleteBlock(c); err != nil {
			return err
		}
	}
	return nil
}
func GetLinksDirect(serv format.NodeGetter) GetLinks {
	return func(ctx context.Context, c cid.Cid) ([]*format.Link, error) {
		nd, err := serv.Get(ctx, c)
		if err != nil {
			if err == bserv.ErrNotFound {
				err = format.ErrNotFound
			}
			return nil, err
		}
		return nd.Links(), nil
	}
}
type sesGetter struct {
	bs *bserv.Session
}
func (sg *sesGetter) Get(ctx context.Context, c cid.Cid) (format.Node, error) {
	blk, err := sg.bs.GetBlock(ctx, c)
	switch err {
	case bserv.ErrNotFound:
		return nil, format.ErrNotFound
	case nil:
	default:
		return nil, err
	}
	return legacy.DecodeNode(ctx, blk)
}
func (sg *sesGetter) GetMany(ctx context.Context, keys []cid.Cid) <-chan *format.NodeOption {
	return getNodesFromBG(ctx, sg.bs, keys)
}
func WrapSession(s *bserv.Session) format.NodeGetter {
	return &sesGetter{s}
}
func (n *dagService) Session(ctx context.Context) format.NodeGetter {
	return WrapSession(bserv.NewSession(ctx, n.Blocks))
}