From 7a1c164d16461fc7684a49259271ba463e7e4156 Mon Sep 17 00:00:00 2001 From: Nate Maninger Date: Mon, 9 Oct 2023 11:52:49 -0600 Subject: [PATCH 1/4] cmd: support changing log level --- cmd/fsd/main.go | 21 +++++++++++++++++++++ config/config.go | 5 +++++ 2 files changed, 26 insertions(+) diff --git a/cmd/fsd/main.go b/cmd/fsd/main.go index 9d3b63c..2f05f38 100644 --- a/cmd/fsd/main.go +++ b/cmd/fsd/main.go @@ -40,6 +40,9 @@ var ( API: config.API{ Address: ":8081", }, + Log: config.Log{ + Level: "info", + }, } ) @@ -91,6 +94,24 @@ func main() { mustLoadConfig(dir, log) + var level zap.AtomicLevel + switch cfg.Log.Level { + case "debug": + level = zap.NewAtomicLevelAt(zap.DebugLevel) + case "info": + level = zap.NewAtomicLevelAt(zap.InfoLevel) + case "warn": + level = zap.NewAtomicLevelAt(zap.WarnLevel) + case "error": + level = zap.NewAtomicLevelAt(zap.ErrorLevel) + default: + log.Fatal("invalid log level", zap.String("level", cfg.Log.Level)) + } + + log = log.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core { + return zapcore.NewCore(consoleEncoder, zapcore.Lock(os.Stdout), level) + })) + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM, syscall.SIGINT) defer cancel() diff --git a/config/config.go b/config/config.go index 58e7207..d7c85ed 100644 --- a/config/config.go +++ b/config/config.go @@ -23,10 +23,15 @@ type ( Password string `yaml:"password"` } + Log struct { + Level string `yaml:"level"` + } + // Config contains the configuration for fsd Config struct { Renterd Renterd `yaml:"renterd"` IPFS IPFS `yaml:"ipfs"` API API `yaml:"api"` + Log Log `yaml:"log"` } ) From 26f3da76197590fe6529159c2f87810e4ef1d050 Mon Sep 17 00:00:00 2001 From: Nate Maninger Date: Mon, 9 Oct 2023 11:53:32 -0600 Subject: [PATCH 2/4] ipfs, http: support downloading directory files --- http/api.go | 2 +- http/ipfs.go | 22 +++++++++++++++++++--- ipfs/node.go | 33 +++++++++++++++++++++++++++++++-- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/http/api.go b/http/api.go index 3074b62..cf664a4 100644 --- a/http/api.go +++ b/http/api.go @@ -55,7 +55,7 @@ func (as *apiServer) handlePin(jc jape.Context) { return } - r, err := as.node.DownloadCID(ctx, cid) + r, err := as.node.DownloadCID(ctx, cid, nil) if err != nil { jc.Error(err, http.StatusInternalServerError) return diff --git a/http/ipfs.go b/http/ipfs.go index 2c09ea1..6e82027 100644 --- a/http/ipfs.go +++ b/http/ipfs.go @@ -1,8 +1,10 @@ package http import ( + "errors" "io" "net/http" + "strings" "github.com/ipfs/go-cid" format "github.com/ipfs/go-ipld-format" @@ -24,9 +26,23 @@ type ipfsServer struct { func (is *ipfsServer) handleIPFS(jc jape.Context) { ctx := jc.Request.Context() + var pathStr string + if err := jc.DecodeParam("path", &pathStr); err != nil { + return + } + var cidStr string - if err := jc.DecodeParam("cid", &cidStr); err != nil { + is.log.Debug("downloading file", zap.String("path", pathStr)) + pathStr = strings.TrimPrefix(pathStr, "/") // remove leading slash + path := strings.Split(pathStr, "/") + if len(path) == 0 || path[0] == "" { + jc.Error(errors.New("bad path"), http.StatusBadRequest) return + } else if len(path) == 1 { + cidStr = path[0] + } else { + cidStr = path[0] + path = path[1:] } cid, err := cid.Parse(cidStr) @@ -38,7 +54,7 @@ func (is *ipfsServer) handleIPFS(jc jape.Context) { block, err := is.store.GetBlock(ctx, cid) if format.IsNotFound(err) && is.ipfs.FetchRemote { is.log.Info("downloading from ipfs", zap.String("cid", cid.Hash().B58String())) - r, err := is.node.DownloadCID(ctx, cid) + r, err := is.node.DownloadCID(ctx, cid, path) if err != nil { jc.Error(err, http.StatusInternalServerError) is.log.Error("failed to download cid", zap.Error(err)) @@ -81,6 +97,6 @@ func NewIPFSHandler(node *ipfs.Node, store Store, cfg config.Config, log *zap.Lo } return jape.Mux(map[string]jape.Handler{ - "GET /ipfs/:cid": s.handleIPFS, + "GET /ipfs/*path": s.handleIPFS, }) } diff --git a/ipfs/node.go b/ipfs/node.go index 0f06c6a..68ad656 100644 --- a/ipfs/node.go +++ b/ipfs/node.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "io" + "strings" "github.com/ipfs/boxo/bitswap" bnetwork "github.com/ipfs/boxo/bitswap/network" @@ -55,14 +56,42 @@ func (n *Node) Close() error { } // DownloadCID downloads the CID -func (n *Node) DownloadCID(ctx context.Context, c cid.Cid) (io.ReadSeekCloser, error) { +func (n *Node) DownloadCID(ctx context.Context, c cid.Cid, path []string) (io.ReadSeekCloser, error) { dagSess := merkledag.NewSession(ctx, n.dagService) rootNode, err := dagSess.Get(ctx, c) if err != nil { return nil, fmt.Errorf("failed to get root node: %w", err) } - dr, err := fsio.NewDagReader(ctx, rootNode, dagSess) + var traverse func(context.Context, format.Node, []string) (format.Node, error) + traverse = func(ctx context.Context, parent format.Node, path []string) (format.Node, error) { + if len(path) == 0 { + return parent, nil + } + + childLink, rem, err := parent.Resolve(path) + if err != nil { + return nil, fmt.Errorf("failed to resolve path %q: %w", strings.Join(path, "/"), err) + } + + switch v := childLink.(type) { + case *format.Link: + childNode, err := dagSess.Get(ctx, v.Cid) + if err != nil { + return nil, fmt.Errorf("failed to get child node %q: %w", v.Cid, err) + } + return traverse(ctx, childNode, rem) + default: + return nil, fmt.Errorf("expected link node, got %T", childLink) + } + } + + node, err := traverse(ctx, rootNode, path) + if err != nil { + return nil, fmt.Errorf("failed to traverse path: %w", err) + } + + dr, err := fsio.NewDagReader(ctx, node, dagSess) return dr, err } From 24865cb3baaa3cb90099dfaf8d945c450fd08aed Mon Sep 17 00:00:00 2001 From: Nate Maninger Date: Mon, 9 Oct 2023 11:57:56 -0600 Subject: [PATCH 3/4] config: fix lint --- config/config.go | 1 + 1 file changed, 1 insertion(+) diff --git a/config/config.go b/config/config.go index d7c85ed..7a624fe 100644 --- a/config/config.go +++ b/config/config.go @@ -23,6 +23,7 @@ type ( Password string `yaml:"password"` } + // Log contains the log settings Log struct { Level string `yaml:"level"` } From 0992f0aaafe3d3aea2b1c7e4d2e0aa1fcc4bb761 Mon Sep 17 00:00:00 2001 From: Nate Maninger Date: Fri, 17 Nov 2023 16:12:21 -0800 Subject: [PATCH 4/4] major refactor --- .gitignore | 3 +- ape0.png | Bin 133270 -> 0 bytes cmd/fsd/main.go | 15 ++- go.mod | 4 +- http/api.go | 84 +++----------- http/ipfs.go | 50 +++------ http/renterd.go | 36 ------ ipfs/cid.go | 160 -------------------------- ipfs/node.go | 2 +- ipfs/node_test.go | 236 +++++++++++++++++++++++++++++++++++++++ persist/badger/cids.go | 9 +- {ipfs => sia}/renterd.go | 2 +- sia/sia.go | 179 +++++++++++++++++++++++++++++ {ipfs => sia}/store.go | 118 +++++++++++++++----- sia/types.go | 39 +++++++ sia/uploader.go | 171 ++++++++++++++++++++++++++++ 16 files changed, 765 insertions(+), 343 deletions(-) delete mode 100644 ape0.png delete mode 100644 http/renterd.go delete mode 100644 ipfs/cid.go create mode 100644 ipfs/node_test.go rename {ipfs => sia}/renterd.go (98%) create mode 100644 sia/sia.go rename {ipfs => sia}/store.go (52%) create mode 100644 sia/types.go create mode 100644 sia/uploader.go diff --git a/.gitignore b/.gitignore index 19eb4cc..cbab71d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ filestore config.yml data -bin \ No newline at end of file +bin +.DS_Store \ No newline at end of file diff --git a/ape0.png b/ape0.png deleted file mode 100644 index b205e8a5aaf9cd66388cfabded7d8bb27f46d38b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133270 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

d;&EZry)kyL6_Ehd{Yt;=RpZE*CBWc^cQS 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 G1pgm&ek>UP diff --git a/cmd/fsd/main.go b/cmd/fsd/main.go index 2f05f38..33285dc 100644 --- a/cmd/fsd/main.go +++ b/cmd/fsd/main.go @@ -19,6 +19,7 @@ import ( shttp "go.sia.tech/fsd/http" "go.sia.tech/fsd/ipfs" "go.sia.tech/fsd/persist/badger" + "go.sia.tech/fsd/sia" "go.sia.tech/jape" "go.uber.org/zap" "go.uber.org/zap/zapcore" @@ -139,13 +140,15 @@ func main() { log.Fatal("failed to generate private key", zap.Error(err)) } } - store := ipfs.NewRenterdBlockStore(db, cfg.Renterd, log.Named("blockstore")) + store := sia.NewBlockStore(db, cfg.Renterd, log.Named("blockstore")) - node, err := ipfs.NewNode(ctx, privateKey, cfg.IPFS, store) + inode, err := ipfs.NewNode(ctx, privateKey, cfg.IPFS, store) if err != nil { log.Fatal("failed to start ipfs node", zap.Error(err)) } - defer node.Close() + defer inode.Close() + + snode := sia.New(db, cfg.Renterd, log.Named("sia")) apiListener, err := net.Listen("tcp", cfg.API.Address) if err != nil { @@ -160,12 +163,12 @@ func main() { defer gatewayListener.Close() apiServer := &http.Server{ - Handler: jape.BasicAuth(cfg.API.Password)(shttp.NewAPIHandler(node, db, cfg, log.Named("api"))), + Handler: jape.BasicAuth(cfg.API.Password)(shttp.NewAPIHandler(inode, snode, cfg, log.Named("api"))), } defer apiServer.Close() gatewayServer := &http.Server{ - Handler: shttp.NewIPFSHandler(node, db, cfg, log.Named("gateway")), + Handler: shttp.NewIPFSGatewayHandler(inode, snode, cfg, log.Named("gateway")), } defer gatewayServer.Close() @@ -188,7 +191,7 @@ func main() { prettyKey := "ed25519:" + hex.EncodeToString(buf) log.Info("fsd started", - zap.Stringer("peerID", node.PeerID()), + zap.Stringer("peerID", inode.PeerID()), zap.String("privateKey", prettyKey), zap.String("apiAddress", apiListener.Addr().String()), zap.String("gatewayAddress", gatewayListener.Addr().String()), diff --git a/go.mod b/go.mod index 6998d31..7695899 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.21 require ( github.com/dgraph-io/badger/v4 v4.2.0 + github.com/gogo/protobuf v1.3.2 github.com/ipfs/boxo v0.13.2-0.20231005100652-b3886904df5d github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 @@ -11,7 +12,6 @@ require ( github.com/libp2p/go-libp2p v0.31.0 github.com/libp2p/go-libp2p-kad-dht v0.24.4 github.com/multiformats/go-multiaddr v0.11.0 - github.com/multiformats/go-multihash v0.2.3 go.sia.tech/jape v0.9.1-0.20230525021720-ecf031ecbffb go.sia.tech/renterd v0.6.1-0.20231005151658-e450d5902e31 go.uber.org/zap v1.25.0 @@ -46,7 +46,6 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/mock v1.6.0 // indirect @@ -115,6 +114,7 @@ require ( github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multibase v0.2.0 // indirect github.com/multiformats/go-multicodec v0.9.0 // indirect + github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/onsi/ginkgo/v2 v2.11.0 // indirect diff --git a/http/api.go b/http/api.go index cf664a4..8de5c60 100644 --- a/http/api.go +++ b/http/api.go @@ -1,30 +1,22 @@ package http import ( - "context" - "io" "net/http" "github.com/ipfs/go-cid" "go.sia.tech/fsd/config" "go.sia.tech/fsd/ipfs" + "go.sia.tech/fsd/sia" "go.sia.tech/jape" - "go.sia.tech/renterd/api" "go.sia.tech/renterd/worker" "go.uber.org/zap" ) type ( - // A Store is a persistent store for IPFS blocks - Store interface { - GetBlock(context.Context, cid.Cid) (ipfs.Block, error) - AddBlocks(context.Context, []ipfs.Block) error - } - apiServer struct { - node *ipfs.Node + ipfs *ipfs.Node + sia *sia.Node worker *worker.Client - store Store log *zap.Logger renterd config.Renterd @@ -32,10 +24,12 @@ type ( ) func (as *apiServer) handleCalculate(jc jape.Context) { + ctx := jc.Request.Context() + body := jc.Request.Body defer body.Close() - blocks, err := ipfs.BuildBalancedCID("test", body) + blocks, err := as.sia.CalculateBlocks(ctx, body) if err != nil { jc.Error(err, http.StatusInternalServerError) return @@ -55,39 +49,14 @@ func (as *apiServer) handlePin(jc jape.Context) { return } - r, err := as.node.DownloadCID(ctx, cid, nil) + r, err := as.ipfs.DownloadCID(ctx, cid, nil) if err != nil { jc.Error(err, http.StatusInternalServerError) return } defer r.Close() - pr, pw := io.Pipe() - tr := io.TeeReader(r, pw) - uploadErr := make(chan error, 1) - - go func() { - defer pw.Close() - defer close(uploadErr) - - _, err = as.worker.UploadObject(ctx, tr, cid.Hash().B58String(), api.UploadWithBucket(as.renterd.Bucket)) - if err != nil { - uploadErr <- err - } - }() - - blocks, err := ipfs.BuildBalancedCID(cidStr, pr) - if err != nil { - jc.Error(err, http.StatusInternalServerError) - return - } - - if err := <-uploadErr; err != nil { - jc.Error(err, http.StatusInternalServerError) - return - } - - if err := as.store.AddBlocks(ctx, blocks); err != nil { + if err := as.sia.UploadCID(ctx, cid, r); err != nil { jc.Error(err, http.StatusInternalServerError) return } @@ -108,50 +77,25 @@ func (as *apiServer) handleUpload(jc jape.Context) { body := jc.Request.Body defer body.Close() - pr, pw := io.Pipe() - r := io.TeeReader(body, pw) - uploadErr := make(chan error, 1) - - go func() { - defer pw.Close() - defer close(uploadErr) - - _, err = as.worker.UploadObject(ctx, r, cid.Hash().B58String(), api.UploadWithBucket(as.renterd.Bucket)) - if err != nil { - uploadErr <- err - } - }() - - blocks, err := ipfs.BuildBalancedCID(cidStr, pr) + err = as.sia.UploadCID(ctx, cid, body) if err != nil { jc.Error(err, http.StatusInternalServerError) return } - if err := <-uploadErr; err != nil { - jc.Error(err, http.StatusInternalServerError) - return - } - - if err := as.store.AddBlocks(ctx, blocks); err != nil { - jc.Error(err, http.StatusInternalServerError) - return - } // the root cid is the first block - rootCID := blocks[0].CID - jc.Encode(rootCID.Hash().B58String()) - as.log.Info("uploaded cid", zap.String("rootCID", rootCID.Hash().B58String()), zap.Int("blocks", len(blocks))) + jc.Encode(cid.Hash().B58String()) } // NewAPIHandler returns a new http.Handler that handles requests to the api -func NewAPIHandler(node *ipfs.Node, store Store, cfg config.Config, log *zap.Logger) http.Handler { +func NewAPIHandler(ipfs *ipfs.Node, sia *sia.Node, cfg config.Config, log *zap.Logger) http.Handler { s := &apiServer{ worker: worker.NewClient(cfg.Renterd.Address, cfg.Renterd.Password), renterd: cfg.Renterd, - node: node, - store: store, - log: log, + ipfs: ipfs, + sia: sia, + log: log, } return jape.Mux(map[string]jape.Handler{ "POST /api/cid/calculate": s.handleCalculate, diff --git a/http/ipfs.go b/http/ipfs.go index 6e82027..4d72943 100644 --- a/http/ipfs.go +++ b/http/ipfs.go @@ -7,23 +7,22 @@ import ( "strings" "github.com/ipfs/go-cid" - format "github.com/ipfs/go-ipld-format" "go.sia.tech/fsd/config" "go.sia.tech/fsd/ipfs" + "go.sia.tech/fsd/sia" "go.sia.tech/jape" "go.uber.org/zap" ) -type ipfsServer struct { - store Store - node *ipfs.Node - log *zap.Logger +type ipfsGatewayServer struct { + ipfs *ipfs.Node + sia *sia.Node + log *zap.Logger - ipfs config.IPFS - renterd config.Renterd + config config.Config } -func (is *ipfsServer) handleIPFS(jc jape.Context) { +func (is *ipfsGatewayServer) handleIPFS(jc jape.Context) { ctx := jc.Request.Context() var pathStr string @@ -51,10 +50,10 @@ func (is *ipfsServer) handleIPFS(jc jape.Context) { return } - block, err := is.store.GetBlock(ctx, cid) - if format.IsNotFound(err) && is.ipfs.FetchRemote { + err = is.sia.ProxyHTTPDownload(cid, jc.Request, jc.ResponseWriter) + if errors.Is(err, sia.ErrNotFound) && is.config.IPFS.FetchRemote { is.log.Info("downloading from ipfs", zap.String("cid", cid.Hash().B58String())) - r, err := is.node.DownloadCID(ctx, cid, path) + r, err := is.ipfs.DownloadCID(ctx, cid, path) if err != nil { jc.Error(err, http.StatusInternalServerError) is.log.Error("failed to download cid", zap.Error(err)) @@ -69,31 +68,16 @@ func (is *ipfsServer) handleIPFS(jc jape.Context) { is.log.Error("failed to get block", zap.Error(err)) return } - - is.log.Info("downloading from renterd", zap.String("cid", cid.Hash().B58String()), zap.String("key", block.Key), zap.Uint64("offset", block.Offset), zap.Uint64("length", block.Length)) - reader, err := downloadObject(ctx, is.renterd, block.Key, block.Offset, block.Length) - if err != nil { - jc.Error(err, http.StatusInternalServerError) - is.log.Error("failed to download object", zap.Error(err)) - return - } - defer reader.Close() - - if _, err := io.Copy(jc.ResponseWriter, reader); err != nil { - is.log.Error("failed to copy file", zap.Error(err)) - return - } } -// NewIPFSHandler creates a new http.Handler for the IPFS gateway. -func NewIPFSHandler(node *ipfs.Node, store Store, cfg config.Config, log *zap.Logger) http.Handler { - s := &ipfsServer{ - node: node, - store: store, - log: log, +// NewIPFSGatewayHandler creates a new http.Handler for the IPFS gateway. +func NewIPFSGatewayHandler(ipfs *ipfs.Node, sia *sia.Node, cfg config.Config, log *zap.Logger) http.Handler { + s := &ipfsGatewayServer{ + ipfs: ipfs, + sia: sia, + log: log, - ipfs: cfg.IPFS, - renterd: cfg.Renterd, + config: cfg, } return jape.Mux(map[string]jape.Handler{ diff --git a/http/renterd.go b/http/renterd.go deleted file mode 100644 index 43b5324..0000000 --- a/http/renterd.go +++ /dev/null @@ -1,36 +0,0 @@ -package http - -import ( - "context" - "errors" - "fmt" - "io" - "net/http" - "net/url" - - "go.sia.tech/fsd/config" -) - -func downloadObject(ctx context.Context, renterd config.Renterd, key string, offset, length uint64) (io.ReadCloser, error) { - values := url.Values{} - values.Set("bucket", url.QueryEscape(renterd.Bucket)) - url := fmt.Sprintf("%s/objects/%s?%s", renterd.Address, key, values.Encode()) - - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) - if err != nil { - return nil, err - } - req.SetBasicAuth("", renterd.Password) - req.Header.Add("Range", fmt.Sprintf("bytes=%d-%d", offset, offset+length)) - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return nil, err - } - if resp.StatusCode != 200 && resp.StatusCode != 206 { - err, _ := io.ReadAll(resp.Body) - _ = resp.Body.Close() - return nil, errors.New(string(err)) - } - return resp.Body, err -} diff --git a/ipfs/cid.go b/ipfs/cid.go deleted file mode 100644 index 47b8ef0..0000000 --- a/ipfs/cid.go +++ /dev/null @@ -1,160 +0,0 @@ -package ipfs - -import ( - "fmt" - "io" - "sort" - - chunker "github.com/ipfs/boxo/chunker" - "github.com/ipfs/boxo/ipld/merkledag" - "github.com/ipfs/boxo/ipld/merkledag/dagutils" - "github.com/ipfs/boxo/ipld/unixfs" - ihelpers "github.com/ipfs/boxo/ipld/unixfs/importer/helpers" - "github.com/ipfs/go-cid" - ipld "github.com/ipfs/go-ipld-format" - multihash "github.com/multiformats/go-multihash/core" -) - -// A Block is an IPFS chunk with metadata -// for renterd -type Block struct { - CID cid.Cid `json:"cid"` - Key string `json:"key"` - Offset uint64 `json:"offset"` - Length uint64 `json:"length"` - Links []cid.Cid `json:"links"` -} - -// BuildBalancedCID builds a balanced CID from the given reader It returns a -// slice of Block which contains the CID, the renterd object key, the offset, -// the length and the links of each block. -func BuildBalancedCID(key string, r io.Reader) ([]Block, error) { - prefix, err := merkledag.PrefixForCidVersion(0) - if err != nil { - return nil, fmt.Errorf("failed to get prefix: %w", err) - } - - prefix.MhType = multihash.SHA2_256 - - spl := chunker.NewSizeSplitter(r, chunker.DefaultBlockSize) - dbp := ihelpers.DagBuilderParams{ - Maxlinks: ihelpers.DefaultLinksPerBlock, - Dagserv: dagutils.NewMemoryDagService(), - } - db, err := dbp.New(spl) - if err != nil { - return nil, fmt.Errorf("failed to create dag builder: %w", err) - } - - var offset uint64 - blocks := make(map[string]Block) - - var fillNode func(db *ihelpers.DagBuilderHelper, node *ihelpers.FSNodeOverDag, depth int) (ipld.Node, uint64, error) - fillNode = func(db *ihelpers.DagBuilderHelper, node *ihelpers.FSNodeOverDag, depth int) (ipld.Node, uint64, error) { - if node == nil { - node = db.NewFSNodeOverDag(unixfs.TFile) - } - - var child ipld.Node - var childSize uint64 - - for node.NumChildren() < db.Maxlinks() && !db.Done() { - if depth == 1 { - child, childSize, err = db.NewLeafDataNode(unixfs.TFile) - if err != nil { - return nil, 0, fmt.Errorf("failed to create new leaf node: %w", err) - } - cid := child.Cid() - blocks[cid.String()] = Block{ - CID: cid, - Key: key, - Offset: offset, - Length: childSize, - } - offset += childSize - } else { - child, childSize, err = fillNode(db, nil, depth-1) - if err != nil { - return nil, 0, fmt.Errorf("failed to fill node: %w", err) - } - cc := child.Cid() - var links []cid.Cid - for _, link := range child.Links() { - links = append(links, link.Cid) - } - size, err := child.Size() - if err != nil { - return nil, 0, fmt.Errorf("failed to get size: %w", err) - } - blocks[cc.String()] = Block{ - CID: cc, - Key: key, - Offset: offset, - Length: size, - Links: links, - } - } - - if err = node.AddChild(child, childSize, db); err != nil { - return nil, 0, fmt.Errorf("failed to add child: %w", err) - } - } - - nodeSize := node.FileSize() - filledNode, err := node.Commit() - return filledNode, nodeSize, err - } - - root, size, err := db.NewLeafDataNode(unixfs.TFile) - if err != nil { - return nil, fmt.Errorf("failed to create new leaf node: %w", err) - } - rc := root.Cid() - blocks[rc.String()] = Block{ - CID: rc, - Key: key, - Offset: 0, - Length: size, - } - offset += size - - for depth := 1; !db.Done(); depth++ { - newRoot := db.NewFSNodeOverDag(unixfs.TFile) - if err := newRoot.AddChild(root, size, db); err != nil { - return nil, fmt.Errorf("failed to add child: %w", err) - } - - root, size, err = fillNode(db, newRoot, depth) - if err != nil { - return nil, fmt.Errorf("failed to fill node: %w", err) - } - } - - var links []cid.Cid - for _, link := range root.Links() { - links = append(links, link.Cid) - } - rc = root.Cid() - blocks[rc.String()] = Block{ - CID: rc, - Key: key, - Offset: 0, - Length: size, - Links: links, - } - - var blockSlice = make([]Block, 0, len(blocks)) - for _, block := range blocks { - blockSlice = append(blockSlice, block) - } - sort.Slice(blockSlice, func(i, j int) bool { - if blockSlice[i].Offset < blockSlice[j].Offset { - return true - } - if blockSlice[i].Offset > blockSlice[j].Offset { - return false - } - return len(blockSlice[j].Links) < len(blockSlice[i].Links) - }) - return blockSlice, nil -} diff --git a/ipfs/node.go b/ipfs/node.go index 68ad656..3288a49 100644 --- a/ipfs/node.go +++ b/ipfs/node.go @@ -55,7 +55,7 @@ func (n *Node) Close() error { return nil } -// DownloadCID downloads the CID +// DownloadCID downloads a CID from IPFS func (n *Node) DownloadCID(ctx context.Context, c cid.Cid, path []string) (io.ReadSeekCloser, error) { dagSess := merkledag.NewSession(ctx, n.dagService) rootNode, err := dagSess.Get(ctx, c) diff --git a/ipfs/node_test.go b/ipfs/node_test.go new file mode 100644 index 0000000..3819f05 --- /dev/null +++ b/ipfs/node_test.go @@ -0,0 +1,236 @@ +package ipfs_test + +import ( + "context" + "crypto/sha256" + "encoding/hex" + "io" + "path/filepath" + "strings" + "sync" + "testing" + "time" + + blocks "github.com/ipfs/go-block-format" + "github.com/ipfs/go-cid" + format "github.com/ipfs/go-ipld-format" + "github.com/libp2p/go-libp2p/core/crypto" + "go.sia.tech/fsd/config" + "go.sia.tech/fsd/ipfs" + "go.sia.tech/fsd/persist/badger" + "go.uber.org/zap" + "go.uber.org/zap/zaptest" + "lukechampine.com/frand" +) + +type memoryBlockStore struct { + mu sync.Mutex + blocks map[cid.Cid][]byte +} + +// DeleteBlock removes a given block from the blockstore. +// note: this is not implemented +func (ms *memoryBlockStore) DeleteBlock(ctx context.Context, c cid.Cid) error { + ms.mu.Lock() + defer ms.mu.Unlock() + delete(ms.blocks, c) + return nil +} + +// Has returns whether or not a given block is in the blockstore. +func (ms *memoryBlockStore) Has(ctx context.Context, c cid.Cid) (bool, error) { + ms.mu.Lock() + defer ms.mu.Unlock() + _, ok := ms.blocks[c] + return ok, nil +} + +// Get returns a block by CID +func (ms *memoryBlockStore) Get(ctx context.Context, c cid.Cid) (blocks.Block, error) { + ms.mu.Lock() + defer ms.mu.Unlock() + if b, ok := ms.blocks[c]; ok { + return blocks.NewBlockWithCid(b, c) + } + return nil, format.ErrNotFound{Cid: c} +} + +// GetSize returns the CIDs mapped BlockSize +func (ms *memoryBlockStore) GetSize(ctx context.Context, c cid.Cid) (int, error) { + ms.mu.Lock() + defer ms.mu.Unlock() + if b, ok := ms.blocks[c]; ok { + return len(b), nil + } + return 0, format.ErrNotFound{Cid: c} +} + +// Put puts a given block to the underlying datastore +func (ms *memoryBlockStore) Put(ctx context.Context, b blocks.Block) error { + ms.mu.Lock() + defer ms.mu.Unlock() + ms.blocks[b.Cid()] = b.RawData() + return nil +} + +// PutMany puts a slice of blocks at the same time using batching +// capabilities of the underlying datastore whenever possible. +func (ms *memoryBlockStore) PutMany(ctx context.Context, blocks []blocks.Block) error { + for _, b := range blocks { + if err := ms.Put(ctx, b); err != nil { + return err + } + } + return nil +} + +// AllKeysChan returns a channel from which +// the CIDs in the Blockstore can be read. It should respect +// the given context, closing the channel if it becomes Done. +// +// AllKeysChan treats the underlying blockstore as a set, and returns that +// set in full. The only guarantee is that the consumer of AKC will +// encounter every CID in the underlying set, at least once. If the +// underlying blockstore supports duplicate CIDs it is up to the +// implementation to elect to return such duplicates or not. Similarly no +// guarantees are made regarding CID ordering. +// +// When underlying blockstore is operating on Multihash and codec information +// is not preserved, returned CIDs will use Raw (0x55) codec. +func (ms *memoryBlockStore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) { + ch := make(chan cid.Cid) + + go func() { + var keys []cid.Cid + ms.mu.Lock() + for c := range ms.blocks { + keys = append(keys, c) + } + ms.mu.Unlock() + + for _, c := range keys { + select { + case <-ctx.Done(): + return + case ch <- c: + } + } + close(ch) + }() + + return ch, nil +} + +// HashOnRead specifies if every read block should be +// rehashed to make sure it matches its CID. +func (ms *memoryBlockStore) HashOnRead(enabled bool) { + // TODO: implement +} + +func TestDownload(t *testing.T) { + log := zaptest.NewLogger(t) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + privateKey, _, err := crypto.GenerateEd25519Key(frand.Reader) + if err != nil { + t.Fatal(err) + } + + store, err := badger.OpenDatabase(filepath.Join(t.TempDir(), "fsd.badgerdb"), log.Named("badger")) + if err != nil { + log.Fatal("failed to open badger database", zap.Error(err)) + } + defer store.Close() + + memBlockStore := &memoryBlockStore{ + blocks: make(map[cid.Cid][]byte), + } + + node, err := ipfs.NewNode(ctx, privateKey, config.IPFS{}, memBlockStore) + if err != nil { + t.Fatal(err) + } + defer node.Close() + + time.Sleep(time.Second) + + t.Log(node.PeerID()) + t.Log(node.Peers()) + + path := strings.Split("1002 - Game AIs/1002 - Game AIs.png", "/") + c := cid.MustParse("QmdmQXB2mzChmMeKY47C43LxUdg1NDJ5MWcKMKxDu7RgQm") + + downloadCtx, cancel := context.WithTimeout(ctx, 15*time.Second) + defer cancel() + + r, err := node.DownloadCID(downloadCtx, c, path) + if err != nil { + t.Fatal(err) + } + defer r.Close() + + h := sha256.New() + if _, err := io.Copy(h, r); err != nil { + t.Fatal(err) + } + + shaChecksum := hex.EncodeToString(h.Sum(nil)) + if shaChecksum != "bb783b7b53f4a36fd6076fbc8384ca860c20aecd6e57f29cb23ea06409808f31" { + t.Fatalf("unexpected hash: %x", h.Sum(nil)) + } +} + +/* +func TestPin(t *testing.T) { + log := zaptest.NewLogger(t) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + privateKey, _, err := crypto.GenerateEd25519Key(frand.Reader) + if err != nil { + t.Fatal(err) + } + + store, err := badger.OpenDatabase(filepath.Join(t.TempDir(), "fsd.badgerdb"), log.Named("badger")) + if err != nil { + log.Fatal("failed to open badger database", zap.Error(err)) + } + defer store.Close() + + memBlockStore := &memoryBlockStore{ + blocks: make(map[cid.Cid][]byte), + } + + node, err := ipfs.NewNode(ctx, privateKey, config.IPFS{}, memBlockStore) + if err != nil { + t.Fatal(err) + } + defer node.Close() + + time.Sleep(time.Second) + + c := cid.MustParse("QmdmQXB2mzChmMeKY47C43LxUdg1NDJ5MWcKMKxDu7RgQm") + + _, err = node.PinCID(ctx, c, func(c cid.Cid, path string) error { + r, err := node.DownloadCID(ctx, c, nil) + if err != nil { + return err + } + defer r.Close() + h := sha256.New() + if _, err := io.Copy(h, r); err != nil { + return err + } + shaChecksum := hex.EncodeToString(h.Sum(nil)) + t.Log("pinned", c, path, shaChecksum) + return nil + }) + if err != nil { + t.Fatal(err) + } + t.Fail() +} +*/ diff --git a/persist/badger/cids.go b/persist/badger/cids.go index c3988c0..651b3dd 100644 --- a/persist/badger/cids.go +++ b/persist/badger/cids.go @@ -6,8 +6,7 @@ import ( "github.com/dgraph-io/badger/v4" "github.com/ipfs/go-cid" - format "github.com/ipfs/go-ipld-format" - "go.sia.tech/fsd/ipfs" + "go.sia.tech/fsd/sia" ) // HasBlock returns true if the CID is in the store @@ -27,12 +26,12 @@ func (s *Store) HasBlock(_ context.Context, c cid.Cid) (ok bool, err error) { } // GetBlock returns the block metadata for a given CID -func (s *Store) GetBlock(_ context.Context, c cid.Cid) (cm ipfs.Block, err error) { +func (s *Store) GetBlock(_ context.Context, c cid.Cid) (cm sia.Block, err error) { err = s.db.View(func(txn *badger.Txn) error { item, err := txn.Get([]byte(c.Bytes())) if err != nil { if err == badger.ErrKeyNotFound { - return format.ErrNotFound{Cid: c} + return sia.ErrNotFound } return err } @@ -44,7 +43,7 @@ func (s *Store) GetBlock(_ context.Context, c cid.Cid) (cm ipfs.Block, err error } // AddBlocks adds blocks to the store -func (s *Store) AddBlocks(_ context.Context, blocks []ipfs.Block) error { +func (s *Store) AddBlocks(_ context.Context, blocks []sia.Block) error { return s.db.Update(func(txn *badger.Txn) error { for _, block := range blocks { buf, err := json.Marshal(block) diff --git a/ipfs/renterd.go b/sia/renterd.go similarity index 98% rename from ipfs/renterd.go rename to sia/renterd.go index 3e24e5d..761088b 100644 --- a/ipfs/renterd.go +++ b/sia/renterd.go @@ -1,4 +1,4 @@ -package ipfs +package sia import ( "context" diff --git a/sia/sia.go b/sia/sia.go new file mode 100644 index 0000000..87a96f2 --- /dev/null +++ b/sia/sia.go @@ -0,0 +1,179 @@ +package sia + +import ( + "context" + "errors" + "fmt" + "io" + "net/http" + "net/http/httputil" + "net/url" + "sync" + + chunker "github.com/ipfs/boxo/chunker" + "github.com/ipfs/boxo/ipld/unixfs/importer/balanced" + ihelpers "github.com/ipfs/boxo/ipld/unixfs/importer/helpers" + "github.com/ipfs/go-cid" + "go.sia.tech/fsd/config" + "go.sia.tech/renterd/api" + "go.sia.tech/renterd/worker" + "go.uber.org/zap" +) + +type ( + // A Store is a persistent store for IPFS blocks + Store interface { + AddBlocks(context.Context, []Block) error + GetBlock(ctx context.Context, c cid.Cid) (Block, error) + HasBlock(ctx context.Context, c cid.Cid) (bool, error) + AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) + } + + // A Node is a specialized IPFS gateway that retrieves data from a renterd + // node + Node struct { + store Store + log *zap.Logger + + renterd config.Renterd + } +) + +// ErrNotFound is returned when a CID is not found in the store +var ErrNotFound = errors.New("not found") + +// UploadCID uploads a CID to the renterd node +func (n *Node) UploadCID(ctx context.Context, c cid.Cid, r io.Reader) error { + log := n.log.Named("upload").With(zap.String("cid", c.Hash().B58String()), zap.String("bucket", n.renterd.Bucket)) + + dataKey := c.Hash().B58String() + metaKey := dataKey + ".meta" + + metaR, metaW := io.Pipe() + dataR, dataW := io.Pipe() + + client := worker.NewClient(n.renterd.Address, n.renterd.Password) + dagSvc := NewUnixFileUploader(c.Hash().B58String(), dataW, metaW, log) + + errCh := make(chan error, 2) + + var wg sync.WaitGroup + wg.Add(2) + go func() { + defer wg.Done() + defer metaW.Close() + + if _, err := client.UploadObject(ctx, dataR, dataKey, api.UploadWithBucket(n.renterd.Bucket)); err != nil { + errCh <- fmt.Errorf("failed to upload data: %w", err) + return + } + }() + + go func() { + defer wg.Done() + defer dataW.Close() + + if _, err := client.UploadObject(ctx, metaR, metaKey, api.UploadWithBucket(n.renterd.Bucket)); err != nil { + errCh <- fmt.Errorf("failed to upload metadata: %w", err) + return + } + }() + + spl := chunker.NewSizeSplitter(r, chunker.DefaultBlockSize) + + dbp := ihelpers.DagBuilderParams{ + Maxlinks: ihelpers.DefaultLinksPerBlock, + Dagserv: dagSvc, + } + db, err := dbp.New(spl) + if err != nil { + return fmt.Errorf("failed to create dag builder: %w", err) + } + + rootNode, err := balanced.Layout(db) + if err != nil { + return fmt.Errorf("failed to build dag: %w", err) + } + + // close the pipes to signal the uploaders that we're done + metaW.Close() + dataW.Close() + // wait for uploads to finish + wg.Wait() + + select { + case err := <-errCh: + return err + default: + } + + if rootNode.Cid().Hash().B58String() != c.Hash().B58String() { + return fmt.Errorf("unexpected root cid: %s", rootNode.Cid().Hash().B58String()) + } + return n.store.AddBlocks(ctx, dagSvc.Blocks()) +} + +// ProxyHTTPDownload proxies an http download request to the renterd node +func (n *Node) ProxyHTTPDownload(cid cid.Cid, r *http.Request, w http.ResponseWriter) error { + block, err := n.store.GetBlock(r.Context(), cid) + if err != nil { + return err + } else if block.Data.Offset != 0 { + return errors.New("cannot proxy partial downloads") + } + + target, err := url.Parse(n.renterd.Address + "/objects/" + cid.Hash().B58String()) + if err != nil { + panic(err) + } + target.RawQuery = url.Values{ + "bucket": []string{n.renterd.Bucket}, + }.Encode() + + rp := &httputil.ReverseProxy{ + Rewrite: func(r *httputil.ProxyRequest) { + r.Out.Method = http.MethodGet + r.Out.URL = target + r.Out.SetBasicAuth("", n.renterd.Password) + r.Out.Header.Set("Range", r.In.Header.Get("Range")) + + n.log.Debug("proxying request to", zap.Stringer("url", r.Out.URL)) + }, + } + + rp.ServeHTTP(w, r) + return nil +} + +// CalculateBlocks calculates the blocks for a given reader and returns them +func (n *Node) CalculateBlocks(ctx context.Context, r io.Reader) ([]Block, error) { + dagSvc := NewUnixFileUploader("", io.Discard, io.Discard, n.log.Named("calculate")) + + spl := chunker.NewSizeSplitter(r, chunker.DefaultBlockSize) + + dbp := ihelpers.DagBuilderParams{ + Maxlinks: ihelpers.DefaultLinksPerBlock, + Dagserv: dagSvc, + } + db, err := dbp.New(spl) + if err != nil { + return nil, fmt.Errorf("failed to create dag builder: %w", err) + } + + _, err = balanced.Layout(db) + if err != nil { + return nil, fmt.Errorf("failed to build dag: %w", err) + } + + return dagSvc.Blocks(), nil +} + +// New creates a new Sia IPFS store +func New(store Store, cfg config.Renterd, log *zap.Logger) *Node { + return &Node{ + store: store, + log: log, + + renterd: cfg, + } +} diff --git a/ipfs/store.go b/sia/store.go similarity index 52% rename from ipfs/store.go rename to sia/store.go index 532c465..2ae0be1 100644 --- a/ipfs/store.go +++ b/sia/store.go @@ -1,30 +1,29 @@ -package ipfs +package sia import ( "bytes" "context" + "errors" "fmt" "io" + "sync" + "github.com/gogo/protobuf/proto" + "github.com/ipfs/boxo/ipld/merkledag" + pb "github.com/ipfs/boxo/ipld/unixfs/pb" blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" + format "github.com/ipfs/go-ipld-format" "go.sia.tech/fsd/config" "go.uber.org/zap" ) type ( - // A Store is a persistent store for IPFS blocks - Store interface { - GetBlock(ctx context.Context, c cid.Cid) (Block, error) - HasBlock(ctx context.Context, c cid.Cid) (bool, error) - AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) - } - - // A RenterdBlockStore is a blockstore backed by a renterd node IPFS blocks - // are stored in a local database and backed by a renterd node. The primary - // difference between this and a normal IPFS blockstore is that an object is - // stored on the renterd node in one piece and the offsets for each block - // are stored in the database. + // A RenterdBlockStore is a blockstore backed by a renterd node. IPFS blocks + // are stored in a local database and uploaded to a renterd node. The + // primary difference between this and a normal IPFS blockstore is that a + // file is stored on the renterd node in one piece and the offsets for + // rebuilding the block are stored in the database. RenterdBlockStore struct { store Store log *zap.Logger @@ -48,31 +47,94 @@ func (bs *RenterdBlockStore) Has(ctx context.Context, c cid.Cid) (bool, error) { func (bs *RenterdBlockStore) Get(ctx context.Context, c cid.Cid) (blocks.Block, error) { bs.log.Debug("get block", zap.String("cid", c.Hash().B58String())) cm, err := bs.store.GetBlock(ctx, c) - if err != nil { + if errors.Is(err, ErrNotFound) { + return nil, format.ErrNotFound{Cid: c} + } else if err != nil { return nil, fmt.Errorf("failed to get cid: %w", err) } - var buf bytes.Buffer - r, err := downloadObject(ctx, bs.renterd, cm.Key, cm.Offset, cm.Length) - if err != nil { - return nil, fmt.Errorf("failed to download object: %w", err) + errCh := make(chan error, 2) + defer close(errCh) + + var metaBuf, dataBuf bytes.Buffer + + var wg sync.WaitGroup + wg.Add(2) + go func() { + defer wg.Done() + + if cm.Data.BlockSize == 0 { + return + } + + r, err := downloadObject(ctx, bs.renterd, cm.Data.Key, cm.Data.Offset, cm.Data.BlockSize) + if err != nil { + errCh <- fmt.Errorf("failed to download object: %w", err) + return + } + defer r.Close() + + if _, err := io.Copy(&dataBuf, r); err != nil { + errCh <- fmt.Errorf("failed to copy object: %w", err) + return + } + }() + + go func() { + defer wg.Done() + + if cm.Metadata.Length == 0 { + return + } + + r, err := downloadObject(ctx, bs.renterd, cm.Metadata.Key, cm.Metadata.Offset, cm.Metadata.Length) + if err != nil { + errCh <- fmt.Errorf("failed to download object: %w", err) + return + } + defer r.Close() + + if _, err := io.Copy(&metaBuf, r); err != nil { + errCh <- fmt.Errorf("failed to copy object: %w", err) + return + } + }() + + wg.Wait() + select { + case err := <-errCh: + return nil, err + default: } - defer r.Close() - if n, err := io.Copy(&buf, r); err != nil { - return nil, fmt.Errorf("failed to copy object: %w", err) - } else if n != int64(cm.Length) { - return nil, fmt.Errorf("failed to copy object: expected %d bytes, got %d", cm.Length, n) + var meta pb.Data + if err := proto.Unmarshal(metaBuf.Bytes(), &meta); err != nil { + return nil, fmt.Errorf("failed to unmarshal metadata: %w", err) } + meta.Data = dataBuf.Bytes() - return blocks.NewBlockWithCid(buf.Bytes(), c) + buf, err := proto.Marshal(&meta) + if err != nil { + return nil, fmt.Errorf("failed to marshal metadata: %w", err) + } + + node := merkledag.NodeWithData(buf) + if !node.Cid().Equals(c) { + panic("unexpected cid") // developer error + } + return node, nil } // GetSize returns the CIDs mapped BlockSize func (bs *RenterdBlockStore) GetSize(ctx context.Context, c cid.Cid) (int, error) { - bs.log.Debug("get size", zap.String("cid", c.Hash().B58String())) cm, err := bs.store.GetBlock(ctx, c) - return int(cm.Length), err + if errors.Is(err, ErrNotFound) { + return 0, format.ErrNotFound{Cid: c} + } else if err != nil { + return 0, fmt.Errorf("failed to get cid: %w", err) + } + bs.log.Debug("get block size", zap.String("cid", c.Hash().B58String()), zap.Uint64("size", cm.Data.BlockSize)) + return int(cm.Data.BlockSize + cm.Metadata.Length), nil } // Put puts a given block to the underlying datastore @@ -109,9 +171,9 @@ func (bs *RenterdBlockStore) HashOnRead(enabled bool) { // TODO: implement } -// NewRenterdBlockStore creates a new blockstore backed by the given +// NewBlockStore creates a new blockstore backed by the given // badger.Store and a renterd node -func NewRenterdBlockStore(store Store, renterd config.Renterd, log *zap.Logger) *RenterdBlockStore { +func NewBlockStore(store Store, renterd config.Renterd, log *zap.Logger) *RenterdBlockStore { return &RenterdBlockStore{ store: store, renterd: renterd, diff --git a/sia/types.go b/sia/types.go new file mode 100644 index 0000000..fec52e2 --- /dev/null +++ b/sia/types.go @@ -0,0 +1,39 @@ +package sia + +import ( + "github.com/ipfs/go-cid" +) + +type ( + // A RenterdData links IPFS block data to an object stored on a renterd node + RenterdData struct { + Key string + Offset uint64 + FileSize uint64 + BlockSize uint64 + } + + // RenterdMeta links IPFS block metadata to an object stored on a renterd + // node + RenterdMeta struct { + Key string + Offset uint64 + Length uint64 + } + + // A Link is a link to another IPFS node + Link struct { + CID cid.Cid + Name string + Size uint64 + } + + // A Block is an IPFS chunk with metadata for efficient storage and + // retrieval from renterd + Block struct { + CID cid.Cid `json:"cid"` + Data RenterdData `json:"data"` + Metadata RenterdMeta `json:"metadata"` + Links []Link `json:"links"` + } +) diff --git a/sia/uploader.go b/sia/uploader.go new file mode 100644 index 0000000..1bff630 --- /dev/null +++ b/sia/uploader.go @@ -0,0 +1,171 @@ +package sia + +import ( + "context" + "fmt" + "io" + + "github.com/gogo/protobuf/proto" + "github.com/ipfs/boxo/ipld/unixfs" + pb "github.com/ipfs/boxo/ipld/unixfs/pb" + "github.com/ipfs/go-cid" + format "github.com/ipfs/go-ipld-format" + "go.uber.org/zap" +) + +// A UnixFileUploader uploads a UnixFS DAG to a renterd node +type UnixFileUploader struct { + dataOffset uint64 + metaOffset uint64 + + key string + + data io.Writer + metadata io.Writer + + blocks []Block + + log *zap.Logger +} + +// Get retrieves nodes by CID. Depending on the NodeGetter +// implementation, this may involve fetching the Node from a remote +// machine; consider setting a deadline in the context. +func (ufs *UnixFileUploader) Get(ctx context.Context, c cid.Cid) (format.Node, error) { + panic("not implemented") +} + +// GetMany returns a channel of NodeOptions given a set of CIDs. +func (ufs *UnixFileUploader) GetMany(ctx context.Context, c []cid.Cid) <-chan *format.NodeOption { + panic("not implemented") +} + +// Add adds a node to this DAG. +func (ufs *UnixFileUploader) Add(ctx context.Context, node format.Node) error { + fsNode, err := unixfs.ExtractFSNode(node) + if err != nil { + return fmt.Errorf("failed to extract fs node: %w", err) + } + + switch fsNode.Type() { + case unixfs.TFile: + dataSize := uint64(len(fsNode.Data())) + fileSize := fsNode.FileSize() + dataOffset := ufs.dataOffset + dataSize - fileSize + + ufs.log.Debug("adding node", + zap.String("cid", node.Cid().Hash().B58String()), + zap.Stringer("type", fsNode.Type()), + zap.Uint64("filesize", fileSize), + zap.Uint64("dataOffset", dataOffset), + zap.Uint64("metaOffset", ufs.metaOffset), + zap.Uint64("datasize", dataSize), + zap.Int("links", len(node.Links()))) + + var links []Link + for _, link := range node.Links() { + links = append(links, Link{ + CID: link.Cid, + Name: link.Name, + Size: link.Size, + }) + } + + buf, err := fsNode.GetBytes() + if err != nil { + return fmt.Errorf("failed to get bytes: %w", err) + } + + var meta pb.Data + if err := proto.Unmarshal(buf, &meta); err != nil { + return fmt.Errorf("failed to unmarshal metadata: %w", err) + } + meta.Data = nil + metaBytes, err := proto.Marshal(&meta) + if err != nil { + return fmt.Errorf("failed to marshal metadata: %w", err) + } + + metaLen, err := ufs.metadata.Write(metaBytes) + if err != nil { + return fmt.Errorf("failed to write metadata: %w", err) + } + + _, err = ufs.data.Write(fsNode.Data()) + if err != nil { + return fmt.Errorf("failed to write data: %w", err) + } + + block := Block{ + CID: node.Cid(), + Links: links, + Data: RenterdData{ + Key: ufs.key, + Offset: dataOffset, + FileSize: fileSize, + BlockSize: dataSize, + }, + Metadata: RenterdMeta{ + Key: ufs.key + ".meta", + Offset: ufs.metaOffset, + Length: uint64(metaLen), + }, + } + ufs.dataOffset += dataSize + ufs.metaOffset += block.Metadata.Length + ufs.blocks = append(ufs.blocks, block) + default: + return fmt.Errorf("unsupported node type: %v", fsNode.Type()) + } + return nil +} + +// AddMany adds many nodes to this DAG. +// +// Consider using the Batch NodeAdder (`NewBatch`) if you make +// extensive use of this function. +func (ufs *UnixFileUploader) AddMany(ctx context.Context, nodes []format.Node) error { + for _, node := range nodes { + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + if err := ufs.Add(ctx, node); err != nil { + return err + } + } + return nil +} + +// Remove removes a node from this DAG. +// +// Remove returns no error if the requested node is not present in this DAG. +func (ufs *UnixFileUploader) Remove(context.Context, cid.Cid) error { + panic("not implemented") +} + +// RemoveMany removes many nodes from this DAG. +// +// It returns success even if the nodes were not present in the DAG. +func (ufs *UnixFileUploader) RemoveMany(context.Context, []cid.Cid) error { + panic("not implemented") +} + +// Blocks returns all blocks that were added to this DAG. They should be added +// to the blockstore +func (ufs *UnixFileUploader) Blocks() []Block { + return ufs.blocks +} + +// NewUnixFileUploader creates a new UnixFileUploader that uploads a UnixFS DAG +// to a renterd node. +func NewUnixFileUploader(key string, data, metadata io.Writer, log *zap.Logger) *UnixFileUploader { + return &UnixFileUploader{ + log: log, + + key: key, + data: data, + metadata: metadata, + } +}