2019-08-26 10:04:57 +00:00
|
|
|
package sectorblocks
|
2019-08-26 08:02:26 +00:00
|
|
|
|
|
|
|
import (
|
2019-08-26 10:04:57 +00:00
|
|
|
"context"
|
2019-12-01 17:58:31 +00:00
|
|
|
"io/ioutil"
|
2019-11-22 16:20:56 +00:00
|
|
|
|
|
|
|
blocks "github.com/ipfs/go-block-format"
|
2019-08-26 08:02:26 +00:00
|
|
|
"github.com/ipfs/go-cid"
|
2019-08-27 18:45:21 +00:00
|
|
|
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
2020-01-08 19:10:57 +00:00
|
|
|
logging "github.com/ipfs/go-log/v2"
|
2019-12-01 20:07:42 +00:00
|
|
|
"golang.org/x/xerrors"
|
2020-01-15 20:49:11 +00:00
|
|
|
|
|
|
|
"github.com/filecoin-project/lotus/api"
|
|
|
|
"github.com/filecoin-project/lotus/storage/sealing"
|
2019-08-26 08:02:26 +00:00
|
|
|
)
|
|
|
|
|
2019-12-01 20:07:42 +00:00
|
|
|
var log = logging.Logger("sectorblocks")
|
|
|
|
|
2019-08-27 18:45:21 +00:00
|
|
|
type SectorBlockStore struct {
|
2019-08-27 23:03:22 +00:00
|
|
|
intermediate blockstore.Blockstore
|
2019-08-27 18:45:21 +00:00
|
|
|
sectorBlocks *SectorBlocks
|
2019-08-26 09:08:39 +00:00
|
|
|
|
2019-08-27 18:45:21 +00:00
|
|
|
approveUnseal func() error
|
2019-08-26 08:02:26 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 18:45:21 +00:00
|
|
|
func (s *SectorBlockStore) DeleteBlock(cid.Cid) error {
|
|
|
|
panic("not supported")
|
2019-08-26 09:08:39 +00:00
|
|
|
}
|
2019-08-27 18:45:21 +00:00
|
|
|
func (s *SectorBlockStore) GetSize(cid.Cid) (int, error) {
|
|
|
|
panic("not supported")
|
2019-08-26 08:02:26 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 18:45:21 +00:00
|
|
|
func (s *SectorBlockStore) Put(blocks.Block) error {
|
|
|
|
panic("not supported")
|
2019-08-26 08:02:26 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 18:45:21 +00:00
|
|
|
func (s *SectorBlockStore) PutMany([]blocks.Block) error {
|
|
|
|
panic("not supported")
|
2019-08-26 08:02:26 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 18:45:21 +00:00
|
|
|
func (s *SectorBlockStore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
|
|
|
|
panic("not supported")
|
|
|
|
}
|
2019-08-26 08:02:26 +00:00
|
|
|
|
2019-08-27 18:45:21 +00:00
|
|
|
func (s *SectorBlockStore) HashOnRead(enabled bool) {
|
|
|
|
panic("not supported")
|
2019-08-26 08:02:26 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 18:45:21 +00:00
|
|
|
func (s *SectorBlockStore) Has(c cid.Cid) (bool, error) {
|
2019-08-27 23:03:22 +00:00
|
|
|
has, err := s.intermediate.Has(c)
|
2019-08-26 08:02:26 +00:00
|
|
|
if err != nil {
|
2019-08-27 18:45:21 +00:00
|
|
|
return false, err
|
2019-08-26 08:02:26 +00:00
|
|
|
}
|
2019-08-27 18:45:21 +00:00
|
|
|
if has {
|
|
|
|
return true, nil
|
2019-08-27 23:03:22 +00:00
|
|
|
}
|
2019-08-26 08:02:26 +00:00
|
|
|
|
2019-08-27 18:45:21 +00:00
|
|
|
return s.sectorBlocks.Has(c)
|
2019-08-26 08:02:26 +00:00
|
|
|
}
|
2019-08-26 10:04:57 +00:00
|
|
|
|
2019-08-27 18:45:21 +00:00
|
|
|
func (s *SectorBlockStore) Get(c cid.Cid) (blocks.Block, error) {
|
2019-08-27 23:03:22 +00:00
|
|
|
val, err := s.intermediate.Get(c)
|
2019-08-27 18:45:21 +00:00
|
|
|
if err == nil {
|
|
|
|
return val, nil
|
2019-08-26 10:04:57 +00:00
|
|
|
}
|
2019-08-27 18:45:21 +00:00
|
|
|
if err != blockstore.ErrNotFound {
|
|
|
|
return nil, err
|
2019-08-27 23:03:22 +00:00
|
|
|
}
|
2019-08-26 10:04:57 +00:00
|
|
|
|
2019-08-27 18:45:21 +00:00
|
|
|
refs, err := s.sectorBlocks.GetRefs(c)
|
2019-08-26 10:04:57 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2019-08-27 18:45:21 +00:00
|
|
|
if len(refs) == 0 {
|
|
|
|
return nil, blockstore.ErrNotFound
|
2019-08-26 10:04:57 +00:00
|
|
|
}
|
|
|
|
|
2019-12-09 23:19:46 +00:00
|
|
|
// TODO: better strategy (e.g. look for already unsealed)
|
|
|
|
var best api.SealedRef
|
2020-01-15 20:49:11 +00:00
|
|
|
var bestSi sealing.SectorInfo
|
2019-12-09 23:19:46 +00:00
|
|
|
for _, r := range refs {
|
|
|
|
si, err := s.sectorBlocks.Miner.GetSectorInfo(r.SectorID)
|
|
|
|
if err != nil {
|
|
|
|
return nil, xerrors.Errorf("getting sector info: %w", err)
|
|
|
|
}
|
|
|
|
if si.State == api.Proving {
|
|
|
|
best = r
|
|
|
|
bestSi = si
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if bestSi.State == api.UndefinedSectorState {
|
|
|
|
return nil, xerrors.New("no sealed sector found")
|
2019-12-01 17:58:31 +00:00
|
|
|
}
|
|
|
|
|
2019-12-01 20:07:42 +00:00
|
|
|
log.Infof("reading block %s from sector %d(+%d;%d)", c, best.SectorID, best.Offset, best.Size)
|
|
|
|
|
2019-12-01 17:58:31 +00:00
|
|
|
r, err := s.sectorBlocks.sb.ReadPieceFromSealedSector(
|
2020-01-28 23:08:02 +00:00
|
|
|
context.TODO(),
|
2019-12-01 17:58:31 +00:00
|
|
|
best.SectorID,
|
|
|
|
best.Offset,
|
|
|
|
best.Size,
|
2019-12-09 23:19:46 +00:00
|
|
|
bestSi.Ticket.TicketBytes,
|
|
|
|
bestSi.CommD,
|
2019-12-01 17:58:31 +00:00
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return nil, xerrors.Errorf("unsealing block: %w", err)
|
|
|
|
}
|
|
|
|
defer r.Close()
|
|
|
|
|
|
|
|
data, err := ioutil.ReadAll(r)
|
|
|
|
if err != nil {
|
|
|
|
return nil, xerrors.Errorf("reading block data: %w", err)
|
2019-08-26 13:45:36 +00:00
|
|
|
}
|
2019-12-01 21:22:03 +00:00
|
|
|
if uint64(len(data)) != best.Size {
|
|
|
|
return nil, xerrors.Errorf("got wrong amount of data: %d != !d", len(data), best.Size)
|
|
|
|
}
|
|
|
|
|
|
|
|
b, err := blocks.NewBlockWithCid(data, c)
|
|
|
|
if err != nil {
|
|
|
|
return nil, xerrors.Errorf("sbs get (%d[%d:%d]): %w", best.SectorID, best.Offset, best.Offset+best.Size, err)
|
|
|
|
}
|
2019-08-26 13:45:36 +00:00
|
|
|
|
2019-12-01 21:22:03 +00:00
|
|
|
return b, nil
|
2019-08-26 13:45:36 +00:00
|
|
|
}
|
2019-08-27 18:45:21 +00:00
|
|
|
|
|
|
|
var _ blockstore.Blockstore = &SectorBlockStore{}
|