2020-04-06 18:07:26 +00:00
|
|
|
package storage
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"context"
|
2020-09-07 06:08:53 +00:00
|
|
|
|
2020-09-07 03:49:10 +00:00
|
|
|
"github.com/filecoin-project/go-bitfield"
|
2020-04-06 18:07:26 +00:00
|
|
|
|
|
|
|
"github.com/ipfs/go-cid"
|
|
|
|
cbg "github.com/whyrusleeping/cbor-gen"
|
|
|
|
"golang.org/x/xerrors"
|
|
|
|
|
|
|
|
"github.com/filecoin-project/go-address"
|
2020-09-07 03:49:10 +00:00
|
|
|
"github.com/filecoin-project/go-state-types/abi"
|
|
|
|
"github.com/filecoin-project/go-state-types/big"
|
|
|
|
"github.com/filecoin-project/go-state-types/crypto"
|
2020-04-06 18:07:26 +00:00
|
|
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
|
|
|
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
|
|
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
|
|
|
|
2020-08-20 04:49:10 +00:00
|
|
|
"github.com/filecoin-project/lotus/api"
|
2020-04-06 18:07:26 +00:00
|
|
|
"github.com/filecoin-project/lotus/api/apibstore"
|
2020-06-04 13:54:37 +00:00
|
|
|
"github.com/filecoin-project/lotus/build"
|
2020-04-06 18:07:26 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/actors"
|
2020-09-12 03:07:52 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
2020-04-06 18:07:26 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/store"
|
|
|
|
"github.com/filecoin-project/lotus/chain/types"
|
2020-08-17 13:39:33 +00:00
|
|
|
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
2020-04-06 18:07:26 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var _ sealing.SealingAPI = new(SealingAPIAdapter)
|
|
|
|
|
|
|
|
type SealingAPIAdapter struct {
|
|
|
|
delegate storageMinerApi
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewSealingAPIAdapter(api storageMinerApi) SealingAPIAdapter {
|
|
|
|
return SealingAPIAdapter{delegate: api}
|
|
|
|
}
|
|
|
|
|
2020-04-06 20:23:37 +00:00
|
|
|
func (s SealingAPIAdapter) StateMinerSectorSize(ctx context.Context, maddr address.Address, tok sealing.TipSetToken) (abi.SectorSize, error) {
|
|
|
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
|
|
|
if err != nil {
|
|
|
|
return 0, xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err)
|
|
|
|
}
|
|
|
|
|
2020-04-16 17:36:36 +00:00
|
|
|
// TODO: update storage-fsm to just StateMinerInfo
|
|
|
|
mi, err := s.delegate.StateMinerInfo(ctx, maddr, tsk)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
return mi.SectorSize, nil
|
2020-04-06 20:23:37 +00:00
|
|
|
}
|
|
|
|
|
2020-07-28 18:55:20 +00:00
|
|
|
func (s SealingAPIAdapter) StateMinerPreCommitDepositForPower(ctx context.Context, a address.Address, pci miner.SectorPreCommitInfo, tok sealing.TipSetToken) (big.Int, error) {
|
|
|
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
|
|
|
if err != nil {
|
|
|
|
return big.Zero(), xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return s.delegate.StateMinerPreCommitDepositForPower(ctx, a, pci, tsk)
|
|
|
|
}
|
|
|
|
|
2020-06-26 15:59:34 +00:00
|
|
|
func (s SealingAPIAdapter) StateMinerInitialPledgeCollateral(ctx context.Context, a address.Address, pci miner.SectorPreCommitInfo, tok sealing.TipSetToken) (big.Int, error) {
|
2020-04-23 19:39:34 +00:00
|
|
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
|
|
|
if err != nil {
|
|
|
|
return big.Zero(), xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err)
|
|
|
|
}
|
|
|
|
|
2020-06-26 15:59:34 +00:00
|
|
|
return s.delegate.StateMinerInitialPledgeCollateral(ctx, a, pci, tsk)
|
2020-04-23 19:39:34 +00:00
|
|
|
}
|
|
|
|
|
2020-04-10 21:29:05 +00:00
|
|
|
func (s SealingAPIAdapter) StateMinerWorkerAddress(ctx context.Context, maddr address.Address, tok sealing.TipSetToken) (address.Address, error) {
|
|
|
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
|
|
|
if err != nil {
|
|
|
|
return address.Undef, xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err)
|
|
|
|
}
|
|
|
|
|
2020-04-16 17:36:36 +00:00
|
|
|
// TODO: update storage-fsm to just StateMinerInfo
|
|
|
|
mi, err := s.delegate.StateMinerInfo(ctx, maddr, tsk)
|
|
|
|
if err != nil {
|
|
|
|
return address.Undef, err
|
|
|
|
}
|
|
|
|
return mi.Worker, nil
|
2020-04-10 21:29:05 +00:00
|
|
|
}
|
|
|
|
|
2020-07-14 17:10:31 +00:00
|
|
|
func (s SealingAPIAdapter) StateMinerDeadlines(ctx context.Context, maddr address.Address, tok sealing.TipSetToken) ([]*miner.Deadline, error) {
|
2020-04-15 20:22:58 +00:00
|
|
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
|
|
|
if err != nil {
|
|
|
|
return nil, xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return s.delegate.StateMinerDeadlines(ctx, maddr, tsk)
|
|
|
|
}
|
|
|
|
|
2020-04-06 18:07:26 +00:00
|
|
|
func (s SealingAPIAdapter) StateWaitMsg(ctx context.Context, mcid cid.Cid) (sealing.MsgLookup, error) {
|
2020-06-03 21:42:06 +00:00
|
|
|
wmsg, err := s.delegate.StateWaitMsg(ctx, mcid, build.MessageConfidence)
|
2020-04-06 18:07:26 +00:00
|
|
|
if err != nil {
|
|
|
|
return sealing.MsgLookup{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return sealing.MsgLookup{
|
|
|
|
Receipt: sealing.MessageReceipt{
|
|
|
|
ExitCode: wmsg.Receipt.ExitCode,
|
|
|
|
Return: wmsg.Receipt.Return,
|
|
|
|
GasUsed: wmsg.Receipt.GasUsed,
|
|
|
|
},
|
2020-07-12 03:54:25 +00:00
|
|
|
TipSetTok: wmsg.TipSet.Bytes(),
|
|
|
|
Height: wmsg.Height,
|
2020-04-06 18:07:26 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2020-08-18 16:02:13 +00:00
|
|
|
func (s SealingAPIAdapter) StateSearchMsg(ctx context.Context, c cid.Cid) (*sealing.MsgLookup, error) {
|
|
|
|
wmsg, err := s.delegate.StateSearchMsg(ctx, c)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if wmsg == nil {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return &sealing.MsgLookup{
|
|
|
|
Receipt: sealing.MessageReceipt{
|
|
|
|
ExitCode: wmsg.Receipt.ExitCode,
|
|
|
|
Return: wmsg.Receipt.Return,
|
|
|
|
GasUsed: wmsg.Receipt.GasUsed,
|
|
|
|
},
|
|
|
|
TipSetTok: wmsg.TipSet.Bytes(),
|
|
|
|
Height: wmsg.Height,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2020-06-15 16:30:49 +00:00
|
|
|
func (s SealingAPIAdapter) StateComputeDataCommitment(ctx context.Context, maddr address.Address, sectorType abi.RegisteredSealProof, deals []abi.DealID, tok sealing.TipSetToken) (cid.Cid, error) {
|
2020-04-06 18:07:26 +00:00
|
|
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
|
|
|
if err != nil {
|
|
|
|
return cid.Undef, xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
ccparams, err := actors.SerializeParams(&market.ComputeDataCommitmentParams{
|
|
|
|
DealIDs: deals,
|
|
|
|
SectorType: sectorType,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return cid.Undef, xerrors.Errorf("computing params for ComputeDataCommitment: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
ccmt := &types.Message{
|
2020-08-01 14:23:13 +00:00
|
|
|
To: builtin.StorageMarketActorAddr,
|
|
|
|
From: maddr,
|
|
|
|
Value: types.NewInt(0),
|
|
|
|
Method: builtin.MethodsMarket.ComputeDataCommitment,
|
|
|
|
Params: ccparams,
|
2020-04-06 18:07:26 +00:00
|
|
|
}
|
|
|
|
r, err := s.delegate.StateCall(ctx, ccmt, tsk)
|
|
|
|
if err != nil {
|
|
|
|
return cid.Undef, xerrors.Errorf("calling ComputeDataCommitment: %w", err)
|
|
|
|
}
|
|
|
|
if r.MsgRct.ExitCode != 0 {
|
|
|
|
return cid.Undef, xerrors.Errorf("receipt for ComputeDataCommitment had exit code %d", r.MsgRct.ExitCode)
|
|
|
|
}
|
|
|
|
|
|
|
|
var c cbg.CborCid
|
|
|
|
if err := c.UnmarshalCBOR(bytes.NewReader(r.MsgRct.Return)); err != nil {
|
|
|
|
return cid.Undef, xerrors.Errorf("failed to unmarshal CBOR to CborCid: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return cid.Cid(c), nil
|
|
|
|
}
|
|
|
|
|
2020-04-06 21:03:47 +00:00
|
|
|
func (s SealingAPIAdapter) StateSectorPreCommitInfo(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok sealing.TipSetToken) (*miner.SectorPreCommitOnChainInfo, error) {
|
2020-04-06 18:07:26 +00:00
|
|
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
|
|
|
if err != nil {
|
|
|
|
return nil, xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
act, err := s.delegate.StateGetActor(ctx, maddr, tsk)
|
|
|
|
if err != nil {
|
|
|
|
return nil, xerrors.Errorf("handleSealFailed(%d): temp error: %+v", sectorNumber, err)
|
|
|
|
}
|
|
|
|
|
2020-09-12 03:07:52 +00:00
|
|
|
stor := store.ActorStore(ctx, apibstore.NewAPIBlockstore(s.delegate))
|
2020-04-06 18:07:26 +00:00
|
|
|
|
2020-09-12 03:07:52 +00:00
|
|
|
state, err := miner.Load(stor, act)
|
|
|
|
if err != nil {
|
|
|
|
return nil, xerrors.Errorf("handleSealFailed(%d): temp error: loading miner state: %+v", sectorNumber, err)
|
2020-04-06 18:07:26 +00:00
|
|
|
}
|
2020-08-05 01:35:40 +00:00
|
|
|
stor := store.ActorStore(ctx, apibstore.NewAPIBlockstore(s.delegate))
|
|
|
|
precommits, err := adt.AsMap(stor, state.PreCommittedSectors)
|
2020-04-13 21:05:34 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2020-04-06 18:07:26 +00:00
|
|
|
var pci miner.SectorPreCommitOnChainInfo
|
2020-09-14 20:31:03 +00:00
|
|
|
ok, err := precommits.Get(abi.UIntKey(uint64(sectorNumber)), &pci)
|
2020-06-04 13:54:36 +00:00
|
|
|
if err != nil {
|
2020-04-06 18:07:26 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
2020-06-04 13:54:36 +00:00
|
|
|
if !ok {
|
2020-09-07 03:49:10 +00:00
|
|
|
var allocated bitfield.BitField
|
2020-08-05 01:35:40 +00:00
|
|
|
if err := stor.Get(ctx, state.AllocatedSectors, &allocated); err != nil {
|
|
|
|
return nil, xerrors.Errorf("loading allocated sector bitfield: %w", err)
|
|
|
|
}
|
|
|
|
set, err := allocated.IsSet(uint64(sectorNumber))
|
|
|
|
if err != nil {
|
|
|
|
return nil, xerrors.Errorf("checking if sector is allocated: %w", err)
|
|
|
|
}
|
|
|
|
if set {
|
2020-08-18 16:02:13 +00:00
|
|
|
return nil, sealing.ErrSectorAllocated
|
2020-08-05 01:35:40 +00:00
|
|
|
}
|
|
|
|
|
2020-06-04 13:54:36 +00:00
|
|
|
return nil, nil
|
|
|
|
}
|
2020-04-06 18:07:26 +00:00
|
|
|
|
|
|
|
return &pci, nil
|
|
|
|
}
|
|
|
|
|
2020-05-28 00:06:29 +00:00
|
|
|
func (s SealingAPIAdapter) StateSectorGetInfo(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok sealing.TipSetToken) (*miner.SectorOnChainInfo, error) {
|
|
|
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
|
|
|
if err != nil {
|
|
|
|
return nil, xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return s.delegate.StateSectorGetInfo(ctx, maddr, sectorNumber, tsk)
|
|
|
|
}
|
|
|
|
|
2020-07-14 12:32:17 +00:00
|
|
|
func (s SealingAPIAdapter) StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok sealing.TipSetToken) (*sealing.SectorLocation, error) {
|
|
|
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
|
|
|
if err != nil {
|
|
|
|
return nil, xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
l, err := s.delegate.StateSectorPartition(ctx, maddr, sectorNumber, tsk)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if l != nil {
|
|
|
|
return &sealing.SectorLocation{
|
|
|
|
Deadline: l.Deadline,
|
|
|
|
Partition: l.Partition,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, nil // not found
|
|
|
|
}
|
|
|
|
|
2020-05-22 16:26:14 +00:00
|
|
|
func (s SealingAPIAdapter) StateMarketStorageDeal(ctx context.Context, dealID abi.DealID, tok sealing.TipSetToken) (market.DealProposal, error) {
|
2020-04-06 18:07:26 +00:00
|
|
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
|
|
|
if err != nil {
|
2020-05-22 16:26:14 +00:00
|
|
|
return market.DealProposal{}, err
|
2020-04-06 18:07:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
deal, err := s.delegate.StateMarketStorageDeal(ctx, dealID, tsk)
|
|
|
|
if err != nil {
|
2020-05-22 16:26:14 +00:00
|
|
|
return market.DealProposal{}, err
|
2020-04-06 18:07:26 +00:00
|
|
|
}
|
|
|
|
|
2020-05-22 16:26:14 +00:00
|
|
|
return deal.Proposal, nil
|
2020-04-06 18:07:26 +00:00
|
|
|
}
|
|
|
|
|
2020-08-12 17:47:00 +00:00
|
|
|
func (s SealingAPIAdapter) SendMsg(ctx context.Context, from, to address.Address, method abi.MethodNum, value, maxFee abi.TokenAmount, params []byte) (cid.Cid, error) {
|
2020-04-06 18:07:26 +00:00
|
|
|
msg := types.Message{
|
2020-08-12 17:47:00 +00:00
|
|
|
To: to,
|
|
|
|
From: from,
|
|
|
|
Value: value,
|
|
|
|
Method: method,
|
|
|
|
Params: params,
|
2020-04-06 18:07:26 +00:00
|
|
|
}
|
|
|
|
|
2020-08-12 20:17:21 +00:00
|
|
|
smsg, err := s.delegate.MpoolPushMessage(ctx, &msg, &api.MessageSendSpec{MaxFee: maxFee})
|
2020-04-06 18:07:26 +00:00
|
|
|
if err != nil {
|
|
|
|
return cid.Undef, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return smsg.Cid(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s SealingAPIAdapter) ChainHead(ctx context.Context) (sealing.TipSetToken, abi.ChainEpoch, error) {
|
|
|
|
head, err := s.delegate.ChainHead(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return nil, 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return head.Key().Bytes(), head.Height(), nil
|
|
|
|
}
|
|
|
|
|
2020-08-11 23:58:35 +00:00
|
|
|
func (s SealingAPIAdapter) ChainGetRandomnessFromBeacon(ctx context.Context, tok sealing.TipSetToken, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) {
|
2020-04-06 18:07:26 +00:00
|
|
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2020-08-11 23:58:35 +00:00
|
|
|
return s.delegate.ChainGetRandomnessFromBeacon(ctx, tsk, personalization, randEpoch, entropy)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s SealingAPIAdapter) ChainGetRandomnessFromTickets(ctx context.Context, tok sealing.TipSetToken, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) {
|
|
|
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return s.delegate.ChainGetRandomnessFromTickets(ctx, tsk, personalization, randEpoch, entropy)
|
2020-04-06 18:07:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s SealingAPIAdapter) ChainReadObj(ctx context.Context, ocid cid.Cid) ([]byte, error) {
|
|
|
|
return s.delegate.ChainReadObj(ctx, ocid)
|
|
|
|
}
|