lotus/node/impl/full/state.go
2019-08-20 18:48:33 +02:00

140 lines
3.0 KiB
Go

package full
import (
"context"
"fmt"
"strconv"
"github.com/filecoin-project/go-lotus/api"
"github.com/filecoin-project/go-lotus/chain/actors"
"github.com/filecoin-project/go-lotus/chain/address"
"github.com/filecoin-project/go-lotus/chain/state"
"github.com/filecoin-project/go-lotus/chain/store"
"github.com/ipfs/go-hamt-ipld"
cbor "github.com/ipfs/go-ipld-cbor"
"go.uber.org/fx"
)
type StateAPI struct {
fx.In
Chain *store.ChainStore
}
func (a *StateAPI) StateMinerSectors(ctx context.Context, addr address.Address) ([]*api.SectorInfo, error) {
ts := a.Chain.GetHeaviestTipSet()
stc, err := a.Chain.TipSetState(ts.Cids())
if err != nil {
return nil, err
}
cst := hamt.CSTFromBstore(a.Chain.Blockstore())
st, err := state.LoadStateTree(cst, stc)
if err != nil {
return nil, err
}
act, err := st.GetActor(addr)
if err != nil {
return nil, err
}
var minerState actors.StorageMinerActorState
if err := cst.Get(ctx, act.Head, &minerState); err != nil {
return nil, err
}
nd, err := hamt.LoadNode(ctx, cst, minerState.Sectors)
if err != nil {
return nil, err
}
var sinfos []*api.SectorInfo
// Note to self: the hamt isnt a great data structure to use here... need to implement the sector set
err = nd.ForEach(ctx, func(k string, val interface{}) error {
sid, err := strconv.ParseUint(k, 10, 64)
if err != nil {
return err
}
bval, ok := val.([]byte)
if !ok {
return fmt.Errorf("expected to get bytes in sector set hamt")
}
var comms [][]byte
if err := cbor.DecodeInto(bval, &comms); err != nil {
return err
}
sinfos = append(sinfos, &api.SectorInfo{
SectorID: sid,
CommR: comms[0],
CommD: comms[1],
})
return nil
})
return sinfos, nil
}
func (a *StateAPI) StateMinerProvingSet(ctx context.Context, addr address.Address) ([]*api.SectorInfo, error) {
ts := a.Chain.GetHeaviestTipSet()
stc, err := a.Chain.TipSetState(ts.Cids())
if err != nil {
return nil, err
}
cst := hamt.CSTFromBstore(a.Chain.Blockstore())
st, err := state.LoadStateTree(cst, stc)
if err != nil {
return nil, err
}
act, err := st.GetActor(addr)
if err != nil {
return nil, err
}
var minerState actors.StorageMinerActorState
if err := cst.Get(ctx, act.Head, &minerState); err != nil {
return nil, err
}
nd, err := hamt.LoadNode(ctx, cst, minerState.ProvingSet)
if err != nil {
return nil, err
}
var sinfos []*api.SectorInfo
// Note to self: the hamt isnt a great data structure to use here... need to implement the sector set
err = nd.ForEach(ctx, func(k string, val interface{}) error {
sid, err := strconv.ParseUint(k, 10, 64)
if err != nil {
return err
}
bval, ok := val.([]byte)
if !ok {
return fmt.Errorf("expected to get bytes in sector set hamt")
}
var comms [][]byte
if err := cbor.DecodeInto(bval, &comms); err != nil {
return err
}
sinfos = append(sinfos, &api.SectorInfo{
SectorID: sid,
CommR: comms[0],
CommD: comms[1],
})
return nil
})
return sinfos, nil
}