Storage miner API improvements

This commit is contained in:
Łukasz Magiera 2019-11-08 19:15:13 +01:00
parent e3288005a6
commit 071f05fa95
17 changed files with 247 additions and 89 deletions

View File

@ -95,8 +95,8 @@ type FullNode interface {
StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error)
StateReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*ActorState, error) StateReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*ActorState, error)
StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*SectorInfo, error) StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error)
StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*SectorInfo, error) StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error)
StateMinerPower(context.Context, address.Address, *types.TipSet) (MinerPower, error) StateMinerPower(context.Context, address.Address, *types.TipSet) (MinerPower, error)
StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error) StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error)
StateMinerPeerID(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error) StateMinerPeerID(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error)
@ -164,7 +164,7 @@ type Message struct {
Message *types.Message Message *types.Message
} }
type SectorInfo struct { type ChainSectorInfo struct {
SectorID uint64 SectorID uint64
CommD []byte CommD []byte
CommR []byte CommR []byte

View File

@ -58,12 +58,31 @@ type StorageMiner interface {
StoreGarbageData(context.Context) error StoreGarbageData(context.Context) error
// Get the status of a given sector by ID // Get the status of a given sector by ID
SectorsStatus(context.Context, uint64) (sectorbuilder.SectorSealingStatus, error) SectorsStatus(context.Context, uint64) (SectorInfo, error)
// List all staged sectors // List all staged sectors
SectorsList(context.Context) ([]uint64, error) SectorsList(context.Context) ([]uint64, error)
SectorsRefs(context.Context) (map[string][]SealedRef, error) SectorsRefs(context.Context) (map[string][]SealedRef, error)
WorkerStats(context.Context) (WorkerStats, error)
}
type WorkerStats struct {
Free int
Reserved int // for PoSt
Total int
}
type SectorInfo struct {
SectorID uint64
State SectorState
CommD []byte
CommR []byte
Proof []byte
Deals []uint64
Ticket sectorbuilder.SealTicket
Seed sectorbuilder.SealSeed
} }
type SealedRef struct { type SealedRef struct {

View File

@ -3,7 +3,6 @@ package api
import ( import (
"context" "context"
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peer"
@ -87,8 +86,8 @@ type FullNodeStruct struct {
ClientRetrieve func(ctx context.Context, order RetrievalOrder, path string) error `perm:"admin"` ClientRetrieve func(ctx context.Context, order RetrievalOrder, path string) error `perm:"admin"`
ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*types.SignedStorageAsk, error) `perm:"read"` ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*types.SignedStorageAsk, error) `perm:"read"`
StateMinerSectors func(context.Context, address.Address, *types.TipSet) ([]*SectorInfo, error) `perm:"read"` StateMinerSectors func(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error) `perm:"read"`
StateMinerProvingSet func(context.Context, address.Address, *types.TipSet) ([]*SectorInfo, error) `perm:"read"` StateMinerProvingSet func(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error) `perm:"read"`
StateMinerPower func(context.Context, address.Address, *types.TipSet) (MinerPower, error) `perm:"read"` StateMinerPower func(context.Context, address.Address, *types.TipSet) (MinerPower, error) `perm:"read"`
StateMinerWorker func(context.Context, address.Address, *types.TipSet) (address.Address, error) `perm:"read"` StateMinerWorker func(context.Context, address.Address, *types.TipSet) (address.Address, error) `perm:"read"`
StateMinerPeerID func(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error) `perm:"read"` StateMinerPeerID func(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error) `perm:"read"`
@ -133,10 +132,11 @@ type StorageMinerStruct struct {
StoreGarbageData func(context.Context) error `perm:"write"` StoreGarbageData func(context.Context) error `perm:"write"`
SectorsStatus func(context.Context, uint64) (sectorbuilder.SectorSealingStatus, error) `perm:"read"` SectorsStatus func(context.Context, uint64) (SectorInfo, error) `perm:"read"`
SectorsList func(context.Context) ([]uint64, error) `perm:"read"` SectorsList func(context.Context) ([]uint64, error) `perm:"read"`
SectorsRefs func(context.Context) (map[string][]SealedRef, error) `perm:"read"`
SectorsRefs func(context.Context) (map[string][]SealedRef, error) `perm:"read"` WorkerStats func(context.Context) (WorkerStats, error) `perm:"read"`
} }
} }
@ -345,11 +345,11 @@ func (c *FullNodeStruct) SyncSubmitBlock(ctx context.Context, blk *types.BlockMs
return c.Internal.SyncSubmitBlock(ctx, blk) return c.Internal.SyncSubmitBlock(ctx, blk)
} }
func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*SectorInfo, error) { func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*ChainSectorInfo, error) {
return c.Internal.StateMinerSectors(ctx, addr, ts) return c.Internal.StateMinerSectors(ctx, addr, ts)
} }
func (c *FullNodeStruct) StateMinerProvingSet(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*SectorInfo, error) { func (c *FullNodeStruct) StateMinerProvingSet(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*ChainSectorInfo, error) {
return c.Internal.StateMinerProvingSet(ctx, addr, ts) return c.Internal.StateMinerProvingSet(ctx, addr, ts)
} }
@ -481,7 +481,7 @@ func (c *StorageMinerStruct) StoreGarbageData(ctx context.Context) error {
} }
// Get the status of a given sector by ID // Get the status of a given sector by ID
func (c *StorageMinerStruct) SectorsStatus(ctx context.Context, sid uint64) (sectorbuilder.SectorSealingStatus, error) { func (c *StorageMinerStruct) SectorsStatus(ctx context.Context, sid uint64) (SectorInfo, error) {
return c.Internal.SectorsStatus(ctx, sid) return c.Internal.SectorsStatus(ctx, sid)
} }
@ -494,6 +494,10 @@ func (c *StorageMinerStruct) SectorsRefs(ctx context.Context) (map[string][]Seal
return c.Internal.SectorsRefs(ctx) return c.Internal.SectorsRefs(ctx)
} }
func (c *StorageMinerStruct) WorkerStats(ctx context.Context) (WorkerStats, error) {
return c.Internal.WorkerStats(ctx)
}
var _ Common = &CommonStruct{} var _ Common = &CommonStruct{}
var _ FullNode = &FullNodeStruct{} var _ FullNode = &FullNodeStruct{}
var _ StorageMiner = &StorageMinerStruct{} var _ StorageMiner = &StorageMinerStruct{}

View File

@ -1,7 +1,7 @@
package build package build
// Version is the local build version, set by build system // Version is the local build version, set by build system
const Version = "0.0.0" const Version = "0.7.0"
// APIVersion is a hex semver version of the rpc api exposed // APIVersion is a hex semver version of the rpc api exposed
// //
@ -12,7 +12,7 @@ const Version = "0.0.0"
// R R H // R R H
// |\vv/| // |\vv/|
// vv vv // vv vv
const APIVersion = 0x000001 const APIVersion = 0x000701
const ( const (
MajorMask = 0xff0000 MajorMask = 0xff0000

View File

@ -157,7 +157,7 @@ func GetMinerProvingPeriodEnd(ctx context.Context, sm *StateManager, ts *types.T
return mas.ProvingPeriodEnd, nil return mas.ProvingPeriodEnd, nil
} }
func GetMinerProvingSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]*api.SectorInfo, error) { func GetMinerProvingSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]*api.ChainSectorInfo, error) {
var mas actors.StorageMinerActorState var mas actors.StorageMinerActorState
_, err := sm.LoadActorState(ctx, maddr, &mas, ts) _, err := sm.LoadActorState(ctx, maddr, &mas, ts)
if err != nil { if err != nil {
@ -167,7 +167,7 @@ func GetMinerProvingSet(ctx context.Context, sm *StateManager, ts *types.TipSet,
return LoadSectorsFromSet(ctx, sm.ChainStore().Blockstore(), mas.ProvingSet) return LoadSectorsFromSet(ctx, sm.ChainStore().Blockstore(), mas.ProvingSet)
} }
func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]*api.SectorInfo, error) { func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]*api.ChainSectorInfo, error) {
var mas actors.StorageMinerActorState var mas actors.StorageMinerActorState
_, err := sm.LoadActorState(ctx, maddr, &mas, ts) _, err := sm.LoadActorState(ctx, maddr, &mas, ts)
if err != nil { if err != nil {
@ -213,20 +213,20 @@ func GetStorageDeal(ctx context.Context, sm *StateManager, dealId uint64, ts *ty
return &ocd, nil return &ocd, nil
} }
func LoadSectorsFromSet(ctx context.Context, bs blockstore.Blockstore, ssc cid.Cid) ([]*api.SectorInfo, error) { func LoadSectorsFromSet(ctx context.Context, bs blockstore.Blockstore, ssc cid.Cid) ([]*api.ChainSectorInfo, error) {
blks := amt.WrapBlockstore(bs) blks := amt.WrapBlockstore(bs)
a, err := amt.LoadAMT(blks, ssc) a, err := amt.LoadAMT(blks, ssc)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var sset []*api.SectorInfo var sset []*api.ChainSectorInfo
if err := a.ForEach(func(i uint64, v *cbg.Deferred) error { if err := a.ForEach(func(i uint64, v *cbg.Deferred) error {
var comms [][]byte var comms [][]byte
if err := cbor.DecodeInto(v.Raw, &comms); err != nil { if err := cbor.DecodeInto(v.Raw, &comms); err != nil {
return err return err
} }
sset = append(sset, &api.SectorInfo{ sset = append(sset, &api.ChainSectorInfo{
SectorID: i, SectorID: i,
CommR: comms[0], CommR: comms[0],
CommD: comms[1], CommD: comms[1],

View File

@ -44,17 +44,18 @@ var infoCmd = &cli.Command{
percI := types.BigDiv(types.BigMul(pow.MinerPower, types.NewInt(1000)), pow.TotalPower) percI := types.BigDiv(types.BigMul(pow.MinerPower, types.NewInt(1000)), pow.TotalPower)
fmt.Printf("Power: %s / %s (%0.2f%%)\n", pow.MinerPower, pow.TotalPower, float64(percI.Int64())/1000*100) fmt.Printf("Power: %s / %s (%0.2f%%)\n", pow.MinerPower, pow.TotalPower, float64(percI.Int64())/1000*100)
// TODO: indicate whether the post worker is in use
wstat, err := nodeApi.WorkerStats(ctx)
if err != nil {
return err
}
fmt.Printf("Worker use: %d / %d (+%d)", wstat.Total-wstat.Reserved-wstat.Free, wstat.Total, wstat.Reserved)
sinfo, err := sectorsInfo(ctx, nodeApi) sinfo, err := sectorsInfo(ctx, nodeApi)
if err != nil { if err != nil {
return err return err
} }
/*
fmt.Println("Sealed Sectors:\t", sinfo.SealedCount)
fmt.Println("Sealing Sectors:\t", sinfo.SealingCount)
fmt.Println("Pending Sectors:\t", sinfo.PendingCount)
fmt.Println("Failed Sectors:\t", sinfo.FailedCount)
*/
fmt.Println(sinfo) fmt.Println(sinfo)
// TODO: grab actr state / info // TODO: grab actr state / info
@ -80,7 +81,7 @@ func sectorsInfo(ctx context.Context, napi api.StorageMiner) (map[string]int, er
return nil, err return nil, err
} }
out[st.State.String()]++ out[api.SectorStateStr(st.State)]++
} }
return out, nil return out, nil

View File

@ -2,6 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/filecoin-project/lotus/api"
"strconv" "strconv"
"gopkg.in/urfave/cli.v2" "gopkg.in/urfave/cli.v2"
@ -60,14 +61,15 @@ var sectorsStatusCmd = &cli.Command{
} }
fmt.Printf("SectorID:\t%d\n", status.SectorID) fmt.Printf("SectorID:\t%d\n", status.SectorID)
fmt.Printf("Status:\t%s\n", status.State.String()) fmt.Printf("Status:\t%s\n", api.SectorStateStr(status.State))
fmt.Printf("SealErrorMsg:\t%q\n", status.SealErrorMsg)
fmt.Printf("CommD:\t\t%x\n", status.CommD) fmt.Printf("CommD:\t\t%x\n", status.CommD)
fmt.Printf("CommR:\t\t%x\n", status.CommR) fmt.Printf("CommR:\t\t%x\n", status.CommR)
fmt.Printf("Ticket:\t\t%x\n", status.Ticket.TicketBytes) fmt.Printf("Ticket:\t\t%x\n", status.Ticket.TicketBytes)
fmt.Printf("TicketH:\t\t%d\n", status.Ticket.BlockHeight) fmt.Printf("TicketH:\t\t%d\n", status.Ticket.BlockHeight)
fmt.Printf("Seed:\t\t%x\n", status.Seed.TicketBytes)
fmt.Printf("SeedH:\t\t%d\n", status.Seed.BlockHeight)
fmt.Printf("Proof:\t\t%x\n", status.Proof) fmt.Printf("Proof:\t\t%x\n", status.Proof)
fmt.Printf("Pieces:\t\t%v\n", status.Pieces) fmt.Printf("Deals:\t\t%v\n", status.Deals)
return nil return nil
}, },
} }

View File

@ -152,6 +152,7 @@ func main() {
err = gen.WriteTupleEncodersToFile("./storage/cbor_gen.go", "storage", err = gen.WriteTupleEncodersToFile("./storage/cbor_gen.go", "storage",
storage.SealTicket{}, storage.SealTicket{},
storage.SealSeed{},
storage.Piece{}, storage.Piece{},
storage.SectorInfo{}, storage.SectorInfo{},
) )

View File

@ -110,6 +110,10 @@ func (sb *SectorBuilder) rlimit() func() {
} }
} }
func (sb *SectorBuilder) WorkerStats() (free, reserved, total int) {
return cap(sb.rateLimit) - len(sb.rateLimit), PoStReservedWorkers, cap(sb.rateLimit) + PoStReservedWorkers
}
func addressToProverID(a address.Address) [32]byte { func addressToProverID(a address.Address) [32]byte {
var proverId [32]byte var proverId [32]byte
copy(proverId[:], a.Payload()) copy(proverId[:], a.Payload())

View File

@ -38,11 +38,11 @@ type StateAPI struct {
Chain *store.ChainStore Chain *store.ChainStore
} }
func (a *StateAPI) StateMinerSectors(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*api.SectorInfo, error) { func (a *StateAPI) StateMinerSectors(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*api.ChainSectorInfo, error) {
return stmgr.GetMinerSectorSet(ctx, a.StateManager, ts, addr) return stmgr.GetMinerSectorSet(ctx, a.StateManager, ts, addr)
} }
func (a *StateAPI) StateMinerProvingSet(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*api.SectorInfo, error) { func (a *StateAPI) StateMinerProvingSet(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*api.ChainSectorInfo, error) {
return stmgr.GetMinerProvingSet(ctx, a.StateManager, ts, addr) return stmgr.GetMinerProvingSet(ctx, a.StateManager, ts, addr)
} }

View File

@ -21,6 +21,15 @@ type StorageMinerAPI struct {
Full api.FullNode Full api.FullNode
} }
func (sm *StorageMinerAPI) WorkerStats(context.Context) (api.WorkerStats, error) {
free, reserved, total := sm.SectorBuilder.WorkerStats()
return api.WorkerStats{
Free: free,
Reserved: reserved,
Total: total,
}, nil
}
func (sm *StorageMinerAPI) ActorAddress(context.Context) (address.Address, error) { func (sm *StorageMinerAPI) ActorAddress(context.Context) (address.Address, error) {
return sm.SectorBuilderConfig.Miner, nil return sm.SectorBuilderConfig.Miner, nil
} }
@ -29,13 +38,41 @@ func (sm *StorageMinerAPI) StoreGarbageData(ctx context.Context) error {
return sm.Miner.StoreGarbageData(ctx) return sm.Miner.StoreGarbageData(ctx)
} }
func (sm *StorageMinerAPI) SectorsStatus(ctx context.Context, sid uint64) (sectorbuilder.SectorSealingStatus, error) { func (sm *StorageMinerAPI) SectorsStatus(ctx context.Context, sid uint64) (api.SectorInfo, error) {
return sm.SectorBuilder.SealStatus(sid) info, err := sm.Miner.GetSectorInfo(sid)
if err != nil {
return api.SectorInfo{}, err
}
deals := make([]uint64, len(info.Pieces))
for i, piece := range info.Pieces {
deals[i] = piece.DealID
}
return api.SectorInfo{
SectorID: sid,
State: info.State,
CommD: info.CommD,
CommR: info.CommR,
Proof: info.Proof,
Deals: deals,
Ticket: info.Ticket.SB(),
Seed: info.Seed.SB(),
}, nil
} }
// List all staged sectors // List all staged sectors
func (sm *StorageMinerAPI) SectorsList(context.Context) ([]uint64, error) { func (sm *StorageMinerAPI) SectorsList(context.Context) ([]uint64, error) {
return sm.SectorBuilder.GetAllStagedSectors() sectors, err := sm.Miner.ListSectors()
if err != nil {
return nil, err
}
out := make([]uint64, len(sectors))
for i, sector := range sectors {
out[i] = sector.SectorID
}
return out, nil
} }
func (sm *StorageMinerAPI) SectorsRefs(context.Context) (map[string][]api.SealedRef, error) { func (sm *StorageMinerAPI) SectorsRefs(context.Context) (map[string][]api.SealedRef, error) {

View File

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/filecoin-project/lotus/chain/types"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
xerrors "golang.org/x/xerrors" xerrors "golang.org/x/xerrors"
) )
@ -82,6 +81,75 @@ func (t *SealTicket) UnmarshalCBOR(r io.Reader) error {
return nil return nil
} }
func (t *SealSeed) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
if _, err := w.Write([]byte{130}); err != nil {
return err
}
// t.t.BlockHeight (uint64) (uint64)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.BlockHeight))); err != nil {
return err
}
// t.t.TicketBytes ([]uint8) (slice)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.TicketBytes)))); err != nil {
return err
}
if _, err := w.Write(t.TicketBytes); err != nil {
return err
}
return nil
}
func (t *SealSeed) UnmarshalCBOR(r io.Reader) error {
br := cbg.GetPeeker(r)
maj, extra, err := cbg.CborReadHeader(br)
if err != nil {
return err
}
if maj != cbg.MajArray {
return fmt.Errorf("cbor input should be of type array")
}
if extra != 2 {
return fmt.Errorf("cbor input had wrong number of fields")
}
// t.t.BlockHeight (uint64) (uint64)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field")
}
t.BlockHeight = uint64(extra)
// t.t.TicketBytes ([]uint8) (slice)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if extra > 8192 {
return fmt.Errorf("t.TicketBytes: array too large (%d)", extra)
}
if maj != cbg.MajByteString {
return fmt.Errorf("expected byte array")
}
t.TicketBytes = make([]byte, extra)
if _, err := io.ReadFull(br, t.TicketBytes); err != nil {
return err
}
return nil
}
func (t *Piece) MarshalCBOR(w io.Writer) error { func (t *Piece) MarshalCBOR(w io.Writer) error {
if t == nil { if t == nil {
_, err := w.Write(cbg.CborNull) _, err := w.Write(cbg.CborNull)
@ -245,6 +313,14 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
return err return err
} }
// t.t.Proof ([]uint8) (slice)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil {
return err
}
if _, err := w.Write(t.Proof); err != nil {
return err
}
// t.t.Ticket (storage.SealTicket) (struct) // t.t.Ticket (storage.SealTicket) (struct)
if err := t.Ticket.MarshalCBOR(w); err != nil { if err := t.Ticket.MarshalCBOR(w); err != nil {
return err return err
@ -262,13 +338,8 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
} }
} }
// t.t.RandHeight (uint64) (uint64) // t.t.Seed (storage.SealSeed) (struct)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.RandHeight))); err != nil { if err := t.Seed.MarshalCBOR(w); err != nil {
return err
}
// t.t.RandTs (types.TipSet) (struct)
if err := t.RandTs.MarshalCBOR(w); err != nil {
return err return err
} }
@ -416,6 +487,23 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error {
if _, err := io.ReadFull(br, t.CommRLast); err != nil { if _, err := io.ReadFull(br, t.CommRLast); err != nil {
return err return err
} }
// t.t.Proof ([]uint8) (slice)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if extra > 8192 {
return fmt.Errorf("t.Proof: array too large (%d)", extra)
}
if maj != cbg.MajByteString {
return fmt.Errorf("expected byte array")
}
t.Proof = make([]byte, extra)
if _, err := io.ReadFull(br, t.Proof); err != nil {
return err
}
// t.t.Ticket (storage.SealTicket) (struct) // t.t.Ticket (storage.SealTicket) (struct)
{ {
@ -449,35 +537,13 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error {
} }
} }
// t.t.RandHeight (uint64) (uint64) // t.t.Seed (storage.SealSeed) (struct)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field")
}
t.RandHeight = uint64(extra)
// t.t.RandTs (types.TipSet) (struct)
{ {
pb, err := br.PeekByte() if err := t.Seed.UnmarshalCBOR(br); err != nil {
if err != nil {
return err return err
} }
if pb == cbg.CborNull[0] {
var nbuf [1]byte
if _, err := br.Read(nbuf[:]); err != nil {
return err
}
} else {
t.RandTs = new(types.TipSet)
if err := t.RandTs.UnmarshalCBOR(br); err != nil {
return err
}
}
} }
// t.t.CommitMessage (cid.Cid) (struct) // t.t.CommitMessage (cid.Cid) (struct)

View File

@ -56,8 +56,8 @@ type storageMinerApi interface {
StateCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) StateCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error)
StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error) StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error)
StateMinerProvingPeriodEnd(context.Context, address.Address, *types.TipSet) (uint64, error) StateMinerProvingPeriodEnd(context.Context, address.Address, *types.TipSet) (uint64, error)
StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*api.SectorInfo, error) StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error)
StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*api.SectorInfo, error) StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error)
StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (uint64, error) StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (uint64, error)
StateWaitMsg(context.Context, cid.Cid) (*api.MsgWait, error) StateWaitMsg(context.Context, cid.Cid) (*api.MsgWait, error)

View File

@ -107,7 +107,7 @@ type post struct {
ts *types.TipSet ts *types.TipSet
// prep // prep
sset []*api.SectorInfo sset []*api.ChainSectorInfo
r []byte r []byte
// run // run
@ -277,7 +277,7 @@ func (m *Miner) computePost(ppe uint64) func(ctx context.Context, ts *types.TipS
} }
} }
func sectorIdList(si []*api.SectorInfo) []uint64 { func sectorIdList(si []*api.ChainSectorInfo) []uint64 {
out := make([]uint64, len(si)) out := make([]uint64, len(si))
for i, s := range si { for i, s := range si {
out[i] = s.SectorID out[i] = s.SectorID

View File

@ -8,7 +8,6 @@ import (
xerrors "golang.org/x/xerrors" xerrors "golang.org/x/xerrors"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/sectorbuilder" "github.com/filecoin-project/lotus/lib/sectorbuilder"
) )
@ -19,12 +18,23 @@ type SealTicket struct {
TicketBytes []byte TicketBytes []byte
} }
func (t *SealTicket) sb() sectorbuilder.SealTicket { func (t *SealTicket) SB() sectorbuilder.SealTicket {
out := sectorbuilder.SealTicket{BlockHeight: t.BlockHeight} out := sectorbuilder.SealTicket{BlockHeight: t.BlockHeight}
copy(out.TicketBytes[:], t.TicketBytes) copy(out.TicketBytes[:], t.TicketBytes)
return out return out
} }
type SealSeed struct {
BlockHeight uint64
TicketBytes []byte
}
func (t *SealSeed) SB() sectorbuilder.SealSeed {
out := sectorbuilder.SealSeed{BlockHeight: t.BlockHeight}
copy(out.TicketBytes[:], t.TicketBytes)
return out
}
type Piece struct { type Piece struct {
DealID uint64 DealID uint64
Ref string Ref string
@ -52,13 +62,13 @@ type SectorInfo struct {
CommD []byte CommD []byte
CommR []byte CommR []byte
CommRLast []byte CommRLast []byte
Proof []byte
Ticket SealTicket Ticket SealTicket
PreCommitMessage *cid.Cid PreCommitMessage *cid.Cid
// PreCommitted // PreCommitted
RandHeight uint64 Seed SealSeed
RandTs *types.TipSet
// Committing // Committing
CommitMessage *cid.Cid CommitMessage *cid.Cid

View File

@ -18,3 +18,17 @@ func fillersFromRem(toFill uint64) ([]uint64, error) {
} }
return out, nil return out, nil
} }
func (m *Miner) ListSectors() ([]SectorInfo, error) {
var sectors []SectorInfo
if err := m.sectors.List(&sectors); err != nil {
return nil, err
}
return sectors, nil
}
func (m *Miner) GetSectorInfo(sid uint64) (SectorInfo, error) {
var out SectorInfo
err := m.sectors.Get(sid, &out)
return out, err
}

View File

@ -145,12 +145,19 @@ func (m *Miner) preCommitted(ctx context.Context, sector SectorInfo) (func(*Sect
log.Infof("precommit for sector %d made it on chain, will start proof computation at height %d", sector.SectorID, randHeight) log.Infof("precommit for sector %d made it on chain, will start proof computation at height %d", sector.SectorID, randHeight)
err = m.events.ChainAt(func(ctx context.Context, ts *types.TipSet, curH uint64) error { err = m.events.ChainAt(func(ctx context.Context, ts *types.TipSet, curH uint64) error {
rand, err := m.api.ChainGetRandomness(ctx, ts, nil, int(ts.Height()-randHeight))
if err != nil {
return xerrors.Errorf("failed to get randomness for computing seal proof: %w", err)
}
m.sectorUpdated <- sectorUpdate{ m.sectorUpdated <- sectorUpdate{
newState: api.Committing, newState: api.Committing,
id: sector.SectorID, id: sector.SectorID,
mut: func(info *SectorInfo) { mut: func(info *SectorInfo) {
info.RandHeight = randHeight info.Seed = SealSeed{
info.RandTs = ts BlockHeight: randHeight,
TicketBytes: rand,
}
}, },
} }
@ -169,21 +176,13 @@ func (m *Miner) preCommitted(ctx context.Context, sector SectorInfo) (func(*Sect
func (m *Miner) committing(ctx context.Context, sector SectorInfo) (func(*SectorInfo), error) { func (m *Miner) committing(ctx context.Context, sector SectorInfo) (func(*SectorInfo), error) {
log.Info("scheduling seal proof computation...") log.Info("scheduling seal proof computation...")
rand, err := m.api.ChainGetRandomness(ctx, sector.RandTs, nil, int(sector.RandTs.Height()-sector.RandHeight)) proof, err := m.sb.SealCommit(sector.SectorID, sector.Ticket.SB(), sector.Seed.SB(), sector.pieceInfos(), sector.refs(), sector.rspco())
if err != nil {
return nil, xerrors.Errorf("failed to get randomness for computing seal proof: %w", err)
}
seed := sectorbuilder.SealSeed{
BlockHeight: sector.RandHeight,
}
copy(seed.TicketBytes[:], rand)
proof, err := m.sb.SealCommit(sector.SectorID, sector.Ticket.sb(), seed, sector.pieceInfos(), sector.refs(), sector.rspco())
if err != nil { if err != nil {
return nil, xerrors.Errorf("computing seal proof failed: %w", err) return nil, xerrors.Errorf("computing seal proof failed: %w", err)
} }
// TODO: Consider splitting states and persist proof for faster recovery
params := &actors.SectorProveCommitInfo{ params := &actors.SectorProveCommitInfo{
Proof: proof, Proof: proof,
SectorID: sector.SectorID, SectorID: sector.SectorID,
@ -218,7 +217,7 @@ func (m *Miner) committing(ctx context.Context, sector SectorInfo) (func(*Sector
} }
if mw.Receipt.ExitCode != 0 { if mw.Receipt.ExitCode != 0 {
log.Errorf("UNHANDLED: submitting sector proof failed (t:%x; s:%x(%d); p:%x)", sector.Ticket.TicketBytes, rand, sector.RandHeight, params.Proof) log.Errorf("UNHANDLED: submitting sector proof failed (t:%x; s:%x(%d); p:%x)", sector.Ticket.TicketBytes, sector.Seed.TicketBytes, sector.Seed.BlockHeight, params.Proof)
return nil, xerrors.New("UNHANDLED: submitting sector proof failed") return nil, xerrors.New("UNHANDLED: submitting sector proof failed")
} }
@ -227,5 +226,6 @@ func (m *Miner) committing(ctx context.Context, sector SectorInfo) (func(*Sector
return func(info *SectorInfo) { return func(info *SectorInfo) {
mcid := smsg.Cid() mcid := smsg.Cid()
info.CommitMessage = &mcid info.CommitMessage = &mcid
info.Proof = proof
}, nil }, nil
} }