Add GetMiningBaseInfo api and use it for mining

This commit is contained in:
Jeromy 2020-04-01 18:10:28 -07:00
parent 7bbc8a4652
commit 5b9ee1dea9
5 changed files with 84 additions and 66 deletions

View File

@ -72,6 +72,7 @@ type FullNode interface {
// miner
MinerGetBaseInfo(context.Context, address.Address, types.TipSetKey) (*MiningBaseInfo, error)
MinerCreateBlock(context.Context, address.Address, types.TipSetKey, *types.Ticket, *types.EPostProof, []*types.SignedMessage, abi.ChainEpoch, uint64) (*types.BlockMsg, error)
// // UX ?
@ -376,3 +377,11 @@ type ComputeStateOutput struct {
Root cid.Cid
Trace []*InvocResult
}
type MiningBaseInfo struct {
MinerPower types.BigInt
NetworkPower types.BigInt
Sectors []*ChainSectorInfo
Worker address.Address
SectorSize abi.SectorSize
}

View File

@ -22,7 +22,7 @@ import (
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/sector-storage"
sectorstorage "github.com/filecoin-project/sector-storage"
"github.com/filecoin-project/sector-storage/sealtasks"
"github.com/filecoin-project/sector-storage/stores"
)
@ -87,6 +87,7 @@ type FullNodeStruct struct {
MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"`
MpoolSub func(context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"`
MinerGetBaseInfo func(context.Context, address.Address, types.TipSetKey) (*api.MiningBaseInfo, error) `perm:"read"`
MinerCreateBlock func(context.Context, address.Address, types.TipSetKey, *types.Ticket, *types.EPostProof, []*types.SignedMessage, abi.ChainEpoch, uint64) (*types.BlockMsg, error) `perm:"write"`
WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"`
@ -323,6 +324,10 @@ func (c *FullNodeStruct) MpoolSub(ctx context.Context) (<-chan api.MpoolUpdate,
return c.Internal.MpoolSub(ctx)
}
func (c *FullNodeStruct) MinerGetBaseInfo(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (*api.MiningBaseInfo, error) {
return c.Internal.MinerGetBaseInfo(ctx, maddr, tsk)
}
func (c *FullNodeStruct) MinerCreateBlock(ctx context.Context, addr address.Address, base types.TipSetKey, ticket *types.Ticket, eproof *types.EPostProof, msgs []*types.SignedMessage, height abi.ChainEpoch, ts uint64) (*types.BlockMsg, error) {
return c.Internal.MinerCreateBlock(ctx, addr, base, ticket, eproof, msgs, height, ts)
}

View File

@ -446,13 +446,7 @@ func (cg *ChainGen) YieldRepo() (repo.Repo, error) {
type MiningCheckAPI interface {
ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error)
StateMinerWorker(context.Context, address.Address, types.TipSetKey) (address.Address, error)
StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (abi.SectorSize, error)
StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error)
MinerGetBaseInfo(context.Context, address.Address, types.TipSetKey) (*api.MiningBaseInfo, error)
WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error)
}
@ -471,44 +465,8 @@ func (mca mca) ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, pers
return mca.sm.ChainStore().GetRandomness(ctx, pts.Cids(), personalization, int64(randEpoch), entropy)
}
func (mca mca) StateMinerPower(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (*api.MinerPower, error) {
ts, err := mca.sm.ChainStore().LoadTipSet(tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
mpow, tpow, err := stmgr.GetPower(ctx, mca.sm, ts, maddr)
if err != nil {
return nil, err
}
return &api.MinerPower{
MinerPower: mpow,
TotalPower: tpow,
}, err
}
func (mca mca) StateMinerWorker(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (address.Address, error) {
ts, err := mca.sm.ChainStore().LoadTipSet(tsk)
if err != nil {
return address.Undef, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
return stmgr.GetMinerWorkerRaw(ctx, mca.sm, ts.ParentState(), maddr)
}
func (mca mca) StateMinerSectorSize(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (abi.SectorSize, error) {
ts, err := mca.sm.ChainStore().LoadTipSet(tsk)
if err != nil {
return 0, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
return stmgr.GetMinerSectorSize(ctx, mca.sm, ts, maddr)
}
func (mca mca) StateMinerProvingSet(ctx context.Context, maddr address.Address, tsk types.TipSetKey) ([]*api.ChainSectorInfo, error) {
ts, err := mca.sm.ChainStore().LoadTipSet(tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
return stmgr.GetMinerProvingSet(ctx, mca.sm, ts, maddr)
func (mca mca) MinerGetBaseInfo(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (*api.MiningBaseInfo, error) {
return stmgr.MinerGetBaseInfo(ctx, mca.sm, tsk, maddr)
}
func (mca mca) WalletSign(ctx context.Context, a address.Address, v []byte) (*crypto.Signature, error) {
@ -560,26 +518,22 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round int64, miner add
return nil, xerrors.Errorf("chain get randomness: %w", err)
}
mworker, err := a.StateMinerWorker(ctx, miner, ts.Key())
mbi, err := a.MinerGetBaseInfo(ctx, miner, ts.Key())
if err != nil {
return nil, xerrors.Errorf("failed to get miner worker: %w", err)
return nil, xerrors.Errorf("failed to get mining base info: %w", err)
}
vrfout, err := ComputeVRF(ctx, a.WalletSign, mworker, epostRand)
vrfout, err := ComputeVRF(ctx, a.WalletSign, mbi.Worker, epostRand)
if err != nil {
return nil, xerrors.Errorf("failed to compute VRF: %w", err)
}
pset, err := a.StateMinerProvingSet(ctx, miner, ts.Key())
if err != nil {
return nil, xerrors.Errorf("failed to load proving set for miner: %w", err)
}
if len(pset) == 0 {
if len(mbi.Sectors) == 0 {
return nil, nil
}
var sinfos []abi.SectorInfo
for _, s := range pset {
for _, s := range mbi.Sectors {
if s.Info.Info.RegisteredProof == 0 {
return nil, xerrors.Errorf("sector %d in proving set had registered type of zero", s.ID)
}
@ -596,19 +550,9 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round int64, miner add
return nil, xerrors.Errorf("failed to generate electionPoSt candidates: %w", err)
}
pow, err := a.StateMinerPower(ctx, miner, ts.Key())
if err != nil {
return nil, xerrors.Errorf("failed to check power: %w", err)
}
ssize, err := a.StateMinerSectorSize(ctx, miner, ts.Key())
if err != nil {
return nil, xerrors.Errorf("failed to look up miners sector size: %w", err)
}
var winners []storage.PoStCandidateWithTicket
for _, c := range candidates {
if types.IsTicketWinner(c.Candidate.PartialTicket, ssize, uint64(len(sinfos)), pow.TotalPower) {
if types.IsTicketWinner(c.Candidate.PartialTicket, mbi.SectorSize, uint64(len(sinfos)), mbi.NetworkPower) {
winners = append(winners, c)
}
}

View File

@ -357,3 +357,58 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
return root, trace, nil
}
func MinerGetBaseInfo(ctx context.Context, sm *StateManager, tsk types.TipSetKey, maddr address.Address) (*api.MiningBaseInfo, error) {
ts, err := sm.ChainStore().LoadTipSet(tsk)
if err != nil {
return nil, xerrors.Errorf("failed to load tipset for mining base: %w", err)
}
st, mr, err := sm.TipSetState(ctx, ts)
if err != nil {
return nil, err
}
// HAXX: we want to use this tipsets evaluated state for all the information
nb := &types.BlockHeader{
Miner: maddr,
Parents: ts.Cids(),
ParentStateRoot: st,
ParentMessageReceipts: mr,
Messages: ts.Blocks()[0].Messages, // TODO: horribly wrong, can't take a cid without it though
Height: ts.Height() + 1,
}
nts, err := types.NewTipSet([]*types.BlockHeader{nb})
if err != nil {
return nil, xerrors.Errorf("failed to make 'next' tipset for getting base info: %w", err)
}
provset, err := GetMinerProvingSet(ctx, sm, nts, maddr)
if err != nil {
return nil, xerrors.Errorf("failed to get proving set: %w", err)
}
mpow, tpow, err := GetPower(ctx, sm, nts, maddr)
if err != nil {
return nil, xerrors.Errorf("failed to get power: %w", err)
}
worker, err := GetMinerWorker(ctx, sm, nts, maddr)
if err != nil {
return nil, xerrors.Errorf("failed to get miner worker: %w", err)
}
ssize, err := GetMinerSectorSize(ctx, sm, nts, maddr)
if err != nil {
return nil, xerrors.Errorf("failed to get miner sector size: %w", err)
}
return &api.MiningBaseInfo{
MinerPower: mpow,
NetworkPower: tpow,
Sectors: provset,
Worker: worker,
SectorSize: ssize,
}, nil
}

View File

@ -263,6 +263,11 @@ func (a *StateAPI) StateReadState(ctx context.Context, act *types.Actor, tsk typ
}, nil
}
// This is on StateAPI because miner.Miner requires this, and MinerAPI requires miner.Miner
func (a *StateAPI) MinerGetBaseInfo(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (*api.MiningBaseInfo, error) {
return stmgr.MinerGetBaseInfo(ctx, a.StateManager, tsk, maddr)
}
// This is on StateAPI because miner.Miner requires this, and MinerAPI requires miner.Miner
func (a *StateAPI) MinerCreateBlock(ctx context.Context, addr address.Address, parentsTSK types.TipSetKey, ticket *types.Ticket, proof *types.EPostProof, msgs []*types.SignedMessage, height abi.ChainEpoch, ts uint64) (*types.BlockMsg, error) {
parents, err := a.Chain.GetTipSetFromKey(parentsTSK)