package retrievalstoremgr import ( "errors" "github.com/filecoin-project/go-multistore" "github.com/filecoin-project/lotus/lib/blockstore" "github.com/filecoin-project/lotus/node/repo/importmgr" "github.com/ipfs/go-blockservice" offline "github.com/ipfs/go-ipfs-exchange-offline" ipldformat "github.com/ipfs/go-ipld-format" "github.com/ipfs/go-merkledag" ) // RetrievalStore references a store for a retrieval deal // which may or may not have a multistore ID associated with it type RetrievalStore interface { StoreID() *multistore.StoreID DAGService() ipldformat.DAGService } // RetrievalStoreManager manages stores for retrieval deals, abstracting // the underlying storage mechanism type RetrievalStoreManager interface { NewStore() (RetrievalStore, error) ReleaseStore(RetrievalStore) error } // MultiStoreRetrievalStoreManager manages stores on top of the import manager type MultiStoreRetrievalStoreManager struct { imgr *importmgr.Mgr } var _ RetrievalStoreManager = &MultiStoreRetrievalStoreManager{} // NewMultiStoreRetrievalStoreManager returns a new multstore based RetrievalStoreManager func NewMultiStoreRetrievalStoreManager(imgr *importmgr.Mgr) RetrievalStoreManager { return &MultiStoreRetrievalStoreManager{ imgr: imgr, } } // NewStore creates a new store (uses multistore) func (mrsm *MultiStoreRetrievalStoreManager) NewStore() (RetrievalStore, error) { storeID, store, err := mrsm.imgr.NewStore() if err != nil { return nil, err } return &multiStoreRetrievalStore{storeID, store}, nil } // ReleaseStore releases a store (uses multistore remove) func (mrsm *MultiStoreRetrievalStoreManager) ReleaseStore(retrievalStore RetrievalStore) error { mrs, ok := retrievalStore.(*multiStoreRetrievalStore) if !ok { return errors.New("Cannot release this store type") } return mrsm.imgr.Remove(mrs.storeID) } type multiStoreRetrievalStore struct { storeID multistore.StoreID store *multistore.Store } func (mrs *multiStoreRetrievalStore) StoreID() *multistore.StoreID { return &mrs.storeID } func (mrs *multiStoreRetrievalStore) DAGService() ipldformat.DAGService { return mrs.store.DAG } // BlockstoreRetrievalStoreManager manages a single blockstore as if it were multiple stores type BlockstoreRetrievalStoreManager struct { bs blockstore.Blockstore } var _ RetrievalStoreManager = &BlockstoreRetrievalStoreManager{} // NewBlockstoreRetrievalStoreManager returns a new blockstore based RetrievalStoreManager func NewBlockstoreRetrievalStoreManager(bs blockstore.Blockstore) RetrievalStoreManager { return &BlockstoreRetrievalStoreManager{ bs: bs, } } // NewStore creates a new store (just uses underlying blockstore) func (brsm *BlockstoreRetrievalStoreManager) NewStore() (RetrievalStore, error) { return &blockstoreRetrievalStore{ dagService: merkledag.NewDAGService(blockservice.New(brsm.bs, offline.Exchange(brsm.bs))), }, nil } // ReleaseStore for this implementation does nothing func (brsm *BlockstoreRetrievalStoreManager) ReleaseStore(RetrievalStore) error { return nil } type blockstoreRetrievalStore struct { dagService ipldformat.DAGService } func (brs *blockstoreRetrievalStore) StoreID() *multistore.StoreID { return nil } func (brs *blockstoreRetrievalStore) DAGService() ipldformat.DAGService { return brs.dagService }