Add GetMiningBaseInfo api and use it for mining
This commit is contained in:
parent
7bbc8a4652
commit
5b9ee1dea9
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user