Skip to content

Instantly share code, notes, and snippets.

@kaloyan-raev
Last active June 22, 2022 13:36
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 kaloyan-raev/d4def01c818129a490eb8d4fe8b6fb68 to your computer and use it in GitHub Desktop.
Save kaloyan-raev/d4def01c818129a490eb8d4fe8b6fb68 to your computer and use it in GitHub Desktop.
Minimal code for calculating IPFS CID
package main
import (
"fmt"
"io"
"os"
"sync"
cid "github.com/ipfs/go-cid"
chunker "github.com/ipfs/go-ipfs-chunker"
dagtest "github.com/ipfs/go-merkledag/test"
balanced "github.com/ipfs/go-unixfs/importer/balanced"
ihelper "github.com/ipfs/go-unixfs/importer/helpers"
"golang.org/x/sync/errgroup"
)
func main() {
file, err := os.Open("/home/kaloyan/Videos/ben.mkv")
if err != nil {
panic(err)
}
defer file.Close()
reader := NewIpfsCidReader(file)
_, err = io.Copy(io.Discard, reader)
if err != nil {
panic(err)
}
fmt.Println(reader.Cid())
}
func IpfsCid(r io.Reader) (cid.Cid, error) {
params := ihelper.DagBuilderParams{
Dagserv: dagtest.Mock(),
Maxlinks: ihelper.DefaultLinksPerBlock,
}
db, err := params.New(chunker.DefaultSplitter(r))
if err != nil {
return cid.Cid{}, err
}
node, err := balanced.Layout(db)
if err != nil {
return cid.Cid{}, err
}
return node.Cid(), err
}
type IpfsCidReader struct {
reader io.Reader
pipeReader *io.PipeReader
pipeWriter *io.PipeWriter
once sync.Once
group errgroup.Group
cid cid.Cid
}
func NewIpfsCidReader(r io.Reader) *IpfsCidReader {
pipeReader, pipeWriter := io.Pipe()
return &IpfsCidReader{
reader: io.TeeReader(r, pipeWriter),
pipeReader: pipeReader,
pipeWriter: pipeWriter,
}
}
func (r *IpfsCidReader) Read(p []byte) (n int, err error) {
r.once.Do(func() {
r.group.Go(func() error {
cid, err := IpfsCid(r.pipeReader)
r.cid = cid
return err
})
})
n, err = r.reader.Read(p)
if err != nil {
r.pipeWriter.CloseWithError(err)
}
return n, err
}
func (r *IpfsCidReader) Cid() (cid.Cid, error) {
err := r.group.Wait()
return r.cid, err
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment