> An implementation of the [graphsync protocol](https://github.com/ipld/specs/blob/master/graphsync/graphsync.md) in go!
## Table of Contents
-[Background](#background)
-[Install](#install)
-[Usage](#usage)
-[Implementation](#implementation)
-[Contribute](#contribute)
-[License](#license)
## Background
[GraphSync](https://github.com/ipld/specs/blob/master/graphsync/graphsync.md) 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](https://github.com/ipld/specs/blob/master/selectors/selectors.md) on the remote peer's local IPLD graph.
`go-graphsync` provides an implementation of the Graphsync protocol in go.
### Go-IPLD-Prime
`go-graphsync` relies on `go-ipld-prime` to traverse IPLD Selectors in an IPLD graph. `go-ipld-prime` implements the [IPLD specification](https://github.com/ipld/specs) 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, `go-graphsync` provide translation layers so you can largely use it without switching to `go-ipld-prime` across your codebase.
## Install
`go-graphsync` requires Go >= 1.11 and can be installed using Go modules
1.`context` is just the parent context for all of GraphSync
2.`host` is any libp2p host
2.`loader` is used to load blocks from the local block store when RESPONDING to requests from other clients. See the IPLD loader interface: https://github.com/ipld/go-ipld-prime/blob/master/linking.go
### Write A Loader From The Stuff You Know
Coming from a pre-`go-ipld-prime` world, you probably expect a link loading function signature to look like this:
```
type Cid2BlockFn func (lnk cid.Cid) (blocks.Block, error)
```
in `go-ipld-prime`, the signature for a link loader is as follows:
```
type Loader func(lnk Link, lnkCtx LinkContext) (io.Reader, error)
```
`go-ipld-prime` intentionally keeps its interfaces as abstract as possible to limit dependencies on other ipfs/filecoin specific packages. An IPLD Link is an abstraction for a CID, and IPLD expects io.Reader's rather than an actual block. IPLD provides a `cidLink` package for working with Links that use CIDs as the underlying data, and it's safe to assume that's the type in use if your code deals only with CIDs. Anyway, a conversion would look something like this:
1.`ctx` is the context for this request. To cancel an in progress request, cancel the context.
2.`p` is the peer you will send this request to
3.`rootedSelector` is the a go-ipld-prime node the specifies a rooted selector
### Building a path selector
A rooted selector is a `go-ipld-prime` node that follows the spec outlined here: https://github.com/ipld/specs/pull/95
`go-ipld-prime` provides a series of builder interfaces for building this kind of structured data into a node. If your library simply wants to make a selector from CID and a path, represented by an array of strings, you could construct the node as follows:
Nodeipld.Node// a node which matched the graphsync query
Pathipld.Path// the path of that node relative to the traversal start
LastBlockstruct{// 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`
## Compatibility: Block Requests
While the above is extremely useful if your library already uses `go-ipld-prime`, if your library uses an older version of go ipld libraries, you won't be able to use this data.
To support these clients, Graphsync provides a compatibility version of the above function that returns just blocks that were traversed:
```
var blocksChan <-chan blocks.Block
var errors <-chan error
blocksChan, errors = exchange.GetBlocks(ctx context.Context, p peer.ID, rootedSelector Node)
```
This is provided as a transitional layer and it's unclear how long go-graphsync will continue to support this format.
## Contribute
PRs are welcome!
Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.