An implementation of the graphsync protocol in go!
GraphSync is a protocol for synchronizing IPLD graphs among peers. It allows a host to make a single request to a remote peer for all of the results of traversing an IPLD selector on the remote peer's local IPLD graph.
go-graphsync
provides an implementation of the Graphsync protocol in go.
go-graphsync
relies on go-ipld-prime
to traverse IPLD Selectors in an IPLD graph. go-ipld-prime
implements the IPLD specification in go and is an alternative to older implementations such as go-ipld-format
and go-ipld-cbor
. In order to use go-graphsync
, some understanding and use of go-ipld-prime
concepts is necessary.
If your existing library (i.e. go-ipfs
or go-filecoin
) uses these other older libraries, you can largely use go-graphsync without switching to go-ipld-prime
across your codebase, but it will require some translations
go-graphsync
requires Go >= 1.13 and can be installed using Go modules
import (
graphsync "github.com/ipfs/go-graphsync/impl"
gsnet "github.com/ipfs/go-graphsync/network"
ipld "github.com/ipld/go-ipld-prime"
)
var ctx context.Context
var host libp2p.Host
var lsys ipld.LinkSystem
network := gsnet.NewFromLibp2pHost(host)
exchange := graphsync.New(ctx, network, lsys)
Parameter Notes:
context
is just the parent context for all of GraphSyncnetwork
is a network abstraction provided to Graphsync on top of libp2p. This allows graphsync to be tested without the actual networklsys
is an go-ipld-prime LinkSystem, which provides mechanisms loading and constructing go-ipld-prime nodes from a link, and saving ipld prime nodes to serialized data
GraphSync provides a convenience function in the storeutil
package for
integrating with BlockStore's from IPFS.
import (
graphsync "github.com/ipfs/go-graphsync/impl"
gsnet "github.com/ipfs/go-graphsync/network"
storeutil "github.com/ipfs/go-graphsync/storeutil"
ipld "github.com/ipld/go-ipld-prime"
blockstore "github.com/ipfs/go-ipfs-blockstore"
)
var ctx context.Context
var host libp2p.Host
var bs blockstore.Blockstore
network := gsnet.NewFromLibp2pHost(host)
lsys := storeutil.LinkSystemForBlockstore(bs)
exchange := graphsync.New(ctx, network, lsys)
var exchange graphsync.GraphSync
var ctx context.Context
var p peer.ID
var selector ipld.Node
var rootLink ipld.Link
var responseProgress <-chan graphsync.ResponseProgress
var errors <-chan error
responseProgress, errors = exchange.Request(ctx context.Context, p peer.ID, root ipld.Link, selector ipld.Node)
Paramater Notes:
ctx
is the context for this request. To cancel an in progress request, cancel the context.p
is the peer you will send this request tolink
is an IPLD Link, i.e. a CID (cidLink.Link{Cid})selector
is an IPLD selector node. Recommend using selector builders from go-ipld-prime to construct these
type ResponseProgress struct {
Node ipld.Node // a node which matched the graphsync query
Path ipld.Path // the path of that node relative to the traversal start
LastBlock struct { // LastBlock stores the Path and Link of the last block edge we had to load.
ipld.Path
ipld.Link
}
}
The above provides both immediate and relevant metadata for matching nodes in a traversal, and is very similar to the information provided by a local IPLD selector traversal in go-ipld-prime
PRs are welcome!
Before doing anything heavy, checkout the Graphsync Architecture
See our Contributing Guidelines for more info.
This library is dual-licensed under Apache 2.0 and MIT terms.
Copyright 2019. Protocol Labs, Inc.