Skip to content

Instantly share code, notes, and snippets.

@rvagg
Created August 2, 2022 00:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rvagg/bbd1544280faf26964d35760cff1489a to your computer and use it in GitHub Desktop.
Save rvagg/bbd1544280faf26964d35760cff1489a to your computer and use it in GitHub Desktop.
Inspect a dag-pb IPLD block and traverse the immediate links using various techniques to compare for consistency
package main
import (
"bytes"
"context"
"fmt"
"io"
"os"
"github.com/ipfs/go-cid"
format "github.com/ipfs/go-ipld-format"
"github.com/ipfs/go-merkledag"
dagpb "github.com/ipld/go-codec-dagpb"
"github.com/ipld/go-ipld-prime"
"github.com/ipld/go-ipld-prime/datamodel"
"github.com/ipld/go-ipld-prime/linking"
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
"github.com/ipld/go-ipld-prime/traversal"
"github.com/ipld/go-ipld-prime/traversal/selector"
selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse"
)
func main() {
root, err := cid.Decode("bafybeietzjzc4vudlevv6k6sxdixhp5nnmfblyjhqheyjyd4d3uluvqdgm")
if err != nil {
panic(err)
}
bin, err := os.ReadFile(os.Args[1])
if err != nil {
panic(err)
}
if os.Args[2] == "prime" {
node, err := ipld.DecodeUsingPrototype(bin, dagpb.Decode, dagpb.Type.PBNode)
if err != nil {
panic(err)
}
fmt.Println("go-ipld-prime links:")
links, err := node.LookupByString("Links")
if err != nil {
panic(err)
}
for ii := int64(0); ii < links.Length(); ii++ {
ln, err := links.LookupByIndex(ii)
if err != nil {
panic(err)
}
hash, err := ln.LookupByString("Hash")
if err != nil {
panic(err)
}
hl, err := hash.AsLink()
if err != nil {
panic(err)
}
fmt.Println(hl.String())
}
}
if os.Args[2] == "merkledag" {
fmt.Println("go-merkledag links:")
node, err := merkledag.DecodeProtobuf(bin)
if err != nil {
panic(err)
}
for _, lnk := range node.Links() {
fmt.Println(lnk.Cid.String())
}
}
if os.Args[2] == "merkledagwalk" {
fmt.Println("go-merkledag.Walk links:")
seen := cid.NewSet()
if err := merkledag.Walk(context.Background(), func(ctx context.Context, c cid.Cid) ([]*format.Link, error) {
fmt.Println(c.String())
if c.Equals(root) {
node, err := merkledag.DecodeProtobuf(bin)
if err != nil {
panic(err)
}
return node.Links(), nil
}
return []*format.Link{}, nil
}, root, seen.Visit); err != nil {
panic(err)
}
}
if os.Args[2] == "primetraverse" {
fmt.Println("go-ipld-prime/traversal/WalkAdv links:")
lsys := cidlink.DefaultLinkSystem()
lsys.StorageReadOpener = func(ctx ipld.LinkContext, lnk ipld.Link) (io.Reader, error) {
fmt.Println(lnk.String())
if lnk.(cidlink.Link).Cid.Equals(root) {
return bytes.NewReader(bin), nil
}
return nil, traversal.SkipMe{}
}
prog := traversal.Progress{
Cfg: &traversal.Config{
Ctx: context.TODO(),
LinkSystem: lsys,
LinkTargetNodePrototypeChooser: func(l datamodel.Link, lc linking.LinkContext) (datamodel.NodePrototype, error) {
return dagpb.Type.PBNode, nil
},
LinkVisitOnlyOnce: true,
},
}
node, err := ipld.DecodeUsingPrototype(bin, dagpb.Decode, dagpb.Type.PBNode)
if err != nil {
panic(err)
}
sel, err := selector.ParseSelector(selectorparse.CommonSelector_ExploreAllRecursively)
if err != nil {
panic(err)
}
err = prog.WalkAdv(node, sel, func(p traversal.Progress, n datamodel.Node, vr traversal.VisitReason) error { return nil })
if err != nil {
panic(err)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment