Merge pull request #152 from filecoin-project/fix/pond-mining
Fix pond mining logic
This commit is contained in:
commit
ad058d05e8
@ -67,6 +67,7 @@ type FullNode interface {
|
|||||||
|
|
||||||
MinerRegister(context.Context, address.Address) error
|
MinerRegister(context.Context, address.Address) error
|
||||||
MinerUnregister(context.Context, address.Address) error
|
MinerUnregister(context.Context, address.Address) error
|
||||||
|
MinerAddresses(context.Context) ([]address.Address, error)
|
||||||
MinerCreateBlock(context.Context, address.Address, *types.TipSet, []*types.Ticket, types.ElectionProof, []*types.SignedMessage) (*chain.BlockMsg, error)
|
MinerCreateBlock(context.Context, address.Address, *types.TipSet, []*types.Ticket, types.ElectionProof, []*types.SignedMessage) (*chain.BlockMsg, error)
|
||||||
|
|
||||||
// // UX ?
|
// // UX ?
|
||||||
@ -97,6 +98,7 @@ type FullNode interface {
|
|||||||
|
|
||||||
StateMinerSectors(context.Context, address.Address) ([]*SectorInfo, error)
|
StateMinerSectors(context.Context, address.Address) ([]*SectorInfo, error)
|
||||||
StateMinerProvingSet(context.Context, address.Address) ([]*SectorInfo, error)
|
StateMinerProvingSet(context.Context, address.Address) ([]*SectorInfo, error)
|
||||||
|
StateMinerPower(context.Context, address.Address, *types.TipSet) (MinerPower, error)
|
||||||
|
|
||||||
PaychCreate(ctx context.Context, from, to address.Address, amt types.BigInt) (address.Address, error)
|
PaychCreate(ctx context.Context, from, to address.Address, amt types.BigInt) (address.Address, error)
|
||||||
PaychList(context.Context) ([]address.Address, error)
|
PaychList(context.Context) ([]address.Address, error)
|
||||||
@ -171,3 +173,8 @@ type ActorState struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PaychStatus struct{}
|
type PaychStatus struct{}
|
||||||
|
|
||||||
|
type MinerPower struct {
|
||||||
|
MinerPower types.BigInt
|
||||||
|
TotalPower types.BigInt
|
||||||
|
}
|
||||||
|
@ -56,6 +56,7 @@ type FullNodeStruct struct {
|
|||||||
|
|
||||||
MinerRegister func(context.Context, address.Address) error `perm:"admin"`
|
MinerRegister func(context.Context, address.Address) error `perm:"admin"`
|
||||||
MinerUnregister func(context.Context, address.Address) error `perm:"admin"`
|
MinerUnregister func(context.Context, address.Address) error `perm:"admin"`
|
||||||
|
MinerAddresses func(context.Context) ([]address.Address, error) `perm:"write"`
|
||||||
MinerCreateBlock func(context.Context, address.Address, *types.TipSet, []*types.Ticket, types.ElectionProof, []*types.SignedMessage) (*chain.BlockMsg, error) `perm:"write"`
|
MinerCreateBlock func(context.Context, address.Address, *types.TipSet, []*types.Ticket, types.ElectionProof, []*types.SignedMessage) (*chain.BlockMsg, error) `perm:"write"`
|
||||||
|
|
||||||
WalletNew func(context.Context, string) (address.Address, error) `perm:"write"`
|
WalletNew func(context.Context, string) (address.Address, error) `perm:"write"`
|
||||||
@ -71,8 +72,9 @@ type FullNodeStruct struct {
|
|||||||
ClientListImports func(ctx context.Context) ([]Import, error) `perm:"read"`
|
ClientListImports func(ctx context.Context) ([]Import, error) `perm:"read"`
|
||||||
ClientStartDeal func(ctx context.Context, data cid.Cid, miner address.Address, price types.BigInt, blocksDuration uint64) (*cid.Cid, error) `perm:"admin"`
|
ClientStartDeal func(ctx context.Context, data cid.Cid, miner address.Address, price types.BigInt, blocksDuration uint64) (*cid.Cid, error) `perm:"admin"`
|
||||||
|
|
||||||
StateMinerSectors func(context.Context, address.Address) ([]*SectorInfo, error) `perm:"read"`
|
StateMinerSectors func(context.Context, address.Address) ([]*SectorInfo, error) `perm:"read"`
|
||||||
StateMinerProvingSet func(context.Context, address.Address) ([]*SectorInfo, error) `perm:"read"`
|
StateMinerProvingSet func(context.Context, address.Address) ([]*SectorInfo, error) `perm:"read"`
|
||||||
|
StateMinerPower func(context.Context, address.Address, *types.TipSet) (MinerPower, error) `perm:"read"`
|
||||||
|
|
||||||
PaychCreate func(ctx context.Context, from, to address.Address, amt types.BigInt) (address.Address, error) `perm:"sign"`
|
PaychCreate func(ctx context.Context, from, to address.Address, amt types.BigInt) (address.Address, error) `perm:"sign"`
|
||||||
PaychList func(context.Context) ([]address.Address, error) `perm:"read"`
|
PaychList func(context.Context) ([]address.Address, error) `perm:"read"`
|
||||||
@ -168,6 +170,10 @@ func (c *FullNodeStruct) MinerUnregister(ctx context.Context, addr address.Addre
|
|||||||
return c.Internal.MinerUnregister(ctx, addr)
|
return c.Internal.MinerUnregister(ctx, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *FullNodeStruct) MinerAddresses(ctx context.Context) ([]address.Address, error) {
|
||||||
|
return c.Internal.MinerAddresses(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) MinerCreateBlock(ctx context.Context, addr address.Address, base *types.TipSet, tickets []*types.Ticket, eproof types.ElectionProof, msgs []*types.SignedMessage) (*chain.BlockMsg, error) {
|
func (c *FullNodeStruct) MinerCreateBlock(ctx context.Context, addr address.Address, base *types.TipSet, tickets []*types.Ticket, eproof types.ElectionProof, msgs []*types.SignedMessage) (*chain.BlockMsg, error) {
|
||||||
return c.Internal.MinerCreateBlock(ctx, addr, base, tickets, eproof, msgs)
|
return c.Internal.MinerCreateBlock(ctx, addr, base, tickets, eproof, msgs)
|
||||||
}
|
}
|
||||||
@ -256,6 +262,10 @@ func (c *FullNodeStruct) StateMinerProvingSet(ctx context.Context, addr address.
|
|||||||
return c.Internal.StateMinerProvingSet(ctx, addr)
|
return c.Internal.StateMinerProvingSet(ctx, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *FullNodeStruct) StateMinerPower(ctx context.Context, a address.Address, ts *types.TipSet) (MinerPower, error) {
|
||||||
|
return c.Internal.StateMinerPower(ctx, a, ts)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) PaychCreate(ctx context.Context, from, to address.Address, amt types.BigInt) (address.Address, error) {
|
func (c *FullNodeStruct) PaychCreate(ctx context.Context, from, to address.Address, amt types.BigInt) (address.Address, error) {
|
||||||
return c.Internal.PaychCreate(ctx, from, to, amt)
|
return c.Internal.PaychCreate(ctx, from, to, amt)
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
|
logging "github.com/ipfs/go-log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var log = logging.Logger("types")
|
||||||
|
|
||||||
type TipSet struct {
|
type TipSet struct {
|
||||||
cids []cid.Cid
|
cids []cid.Cid
|
||||||
blks []*BlockHeader
|
blks []*BlockHeader
|
||||||
@ -65,8 +68,10 @@ func (ts *TipSet) Height() uint64 {
|
|||||||
return ts.height
|
return ts.height
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ts *TipSet) Weight() uint64 {
|
func (ts *TipSet) Weight() BigInt {
|
||||||
panic("if tipsets are going to have weight on them, we need to wire that through")
|
// TODO: implement correctly
|
||||||
|
log.Warn("Called TipSet.Weight: TODO: correct implementation")
|
||||||
|
return BigAdd(ts.blks[0].ParentWeight, NewInt(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ts *TipSet) Parents() []cid.Cid {
|
func (ts *TipSet) Parents() []cid.Cid {
|
||||||
|
38
cli/state.go
38
cli/state.go
@ -2,13 +2,10 @@ package cli
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
|
||||||
|
|
||||||
"gopkg.in/urfave/cli.v2"
|
"gopkg.in/urfave/cli.v2"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/chain/actors"
|
|
||||||
"github.com/filecoin-project/go-lotus/chain/address"
|
"github.com/filecoin-project/go-lotus/chain/address"
|
||||||
types "github.com/filecoin-project/go-lotus/chain/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var stateCmd = &cli.Command{
|
var stateCmd = &cli.Command{
|
||||||
@ -32,43 +29,24 @@ var statePowerCmd = &cli.Command{
|
|||||||
|
|
||||||
ctx := ReqContext(cctx)
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
var msg *types.Message
|
var maddr address.Address
|
||||||
if cctx.Args().Present() {
|
if cctx.Args().Present() {
|
||||||
maddr, err := address.NewFromString(cctx.Args().First())
|
maddr, err = address.NewFromString(cctx.Args().First())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
enc, err := actors.SerializeParams(&actors.PowerLookupParams{
|
|
||||||
Miner: maddr,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = &types.Message{
|
|
||||||
To: actors.StorageMarketAddress,
|
|
||||||
From: actors.StorageMarketAddress,
|
|
||||||
Method: actors.SMAMethods.PowerLookup,
|
|
||||||
Params: enc,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
msg = &types.Message{
|
|
||||||
To: actors.StorageMarketAddress,
|
|
||||||
From: actors.StorageMarketAddress,
|
|
||||||
Method: actors.SMAMethods.GetTotalStorage,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ret, err := api.ChainCall(ctx, msg, nil)
|
power, err := api.StateMinerPower(ctx, maddr, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if ret.ExitCode != 0 {
|
|
||||||
return fmt.Errorf("call to get power failed: %d", ret.ExitCode)
|
res := power.TotalPower
|
||||||
|
if cctx.Args().Present() {
|
||||||
|
res = power.MinerPower
|
||||||
}
|
}
|
||||||
|
|
||||||
v := big.NewInt(0).SetBytes(ret.Return)
|
fmt.Println(res.String())
|
||||||
fmt.Println(v.String())
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -217,7 +217,7 @@ func createStorageMiner(ctx context.Context, api api.FullNode, peerid peer.ID) (
|
|||||||
return address.Undef, err
|
return address.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
k, err := api.WalletNew(ctx, types.KTSecp256k1)
|
k, err := api.WalletNew(ctx, types.KTBLS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return address.Undef, err
|
return address.Undef, err
|
||||||
}
|
}
|
||||||
|
@ -149,8 +149,13 @@ func (api *api) SpawnStorage(fullNodeRepo string) (nodeInfo, error) {
|
|||||||
return nodeInfo{}, err
|
return nodeInfo{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initArgs := []string{"init"}
|
||||||
|
if fullNodeRepo == api.running[1].meta.Repo {
|
||||||
|
initArgs = []string{"init", "--actor=t0101", "--genesis-miner"}
|
||||||
|
}
|
||||||
|
|
||||||
id := atomic.AddInt32(&api.cmds, 1)
|
id := atomic.AddInt32(&api.cmds, 1)
|
||||||
cmd := exec.Command("./lotus-storage-miner", "init")
|
cmd := exec.Command("./lotus-storage-miner", initArgs...)
|
||||||
cmd.Stderr = io.MultiWriter(os.Stderr, errlogfile)
|
cmd.Stderr = io.MultiWriter(os.Stderr, errlogfile)
|
||||||
cmd.Stdout = io.MultiWriter(os.Stdout, logfile)
|
cmd.Stdout = io.MultiWriter(os.Stdout, logfile)
|
||||||
cmd.Env = []string{"LOTUS_STORAGE_PATH=" + dir, "LOTUS_PATH=" + fullNodeRepo}
|
cmd.Env = []string{"LOTUS_STORAGE_PATH=" + dir, "LOTUS_PATH=" + fullNodeRepo}
|
||||||
|
@ -31,17 +31,21 @@ class Address extends React.Component {
|
|||||||
let balance = 0
|
let balance = 0
|
||||||
let actor = {}
|
let actor = {}
|
||||||
let actorInfo
|
let actorInfo
|
||||||
|
let minerInfo
|
||||||
|
|
||||||
try {
|
try {
|
||||||
balance = await this.props.client.call('Filecoin.WalletBalance', [this.props.addr])
|
balance = await this.props.client.call('Filecoin.WalletBalance', [this.props.addr])
|
||||||
actor = await this.props.client.call('Filecoin.ChainGetActor', [this.props.addr, this.props.ts || null])
|
actor = await this.props.client.call('Filecoin.ChainGetActor', [this.props.addr, this.props.ts || null])
|
||||||
|
|
||||||
actorInfo = await this.actorInfo(actor)
|
actorInfo = await this.actorInfo(actor)
|
||||||
|
if(this.props.miner) {
|
||||||
|
minerInfo = await this.props.client.call('Filecoin.StateMinerPower', [this.props.addr, this.props.ts || null])
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
balance = -1
|
balance = -1
|
||||||
}
|
}
|
||||||
this.setState({balance, actor, actorInfo})
|
this.setState({balance, actor, actorInfo, minerInfo})
|
||||||
}
|
}
|
||||||
|
|
||||||
openState() {
|
openState() {
|
||||||
@ -94,7 +98,12 @@ class Address extends React.Component {
|
|||||||
transfer = <span> {this.props.transfer}FIL</span>
|
transfer = <span> {this.props.transfer}FIL</span>
|
||||||
}
|
}
|
||||||
|
|
||||||
return <span>{addr}{balance}{actInfo}{add1k}{transfer}</span>
|
let minerInfo = <span/>
|
||||||
|
if(this.state.minerInfo) {
|
||||||
|
minerInfo = <span> Power: {this.state.minerInfo.MinerPower} ({this.state.minerInfo.MinerPower/this.state.minerInfo.TotalPower*100}%)</span>
|
||||||
|
}
|
||||||
|
|
||||||
|
return <span>{addr}{balance}{actInfo}{add1k}{transfer}{minerInfo}</span>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,13 +10,11 @@ class FullNode extends React.Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
this.state = {
|
this.state = {}
|
||||||
mining: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
this.loadInfo = this.loadInfo.bind(this)
|
this.loadInfo = this.loadInfo.bind(this)
|
||||||
this.startMining = this.startMining.bind(this)
|
this.newSecpAddr = this.newSecpAddr.bind(this)
|
||||||
this.newScepAddr = this.newScepAddr.bind(this)
|
this.newBLSAddr = this.newBLSAddr.bind(this)
|
||||||
this.startStorageMiner = this.startStorageMiner.bind(this)
|
this.startStorageMiner = this.startStorageMiner.bind(this)
|
||||||
this.add1k = this.add1k.bind(this)
|
this.add1k = this.add1k.bind(this)
|
||||||
this.explorer = this.explorer.bind(this)
|
this.explorer = this.explorer.bind(this)
|
||||||
@ -46,6 +44,8 @@ class FullNode extends React.Component {
|
|||||||
return this.props.client.call('Filecoin.PaychVoucherList', [paych])
|
return this.props.client.call('Filecoin.PaychVoucherList', [paych])
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
let minerList = await this.props.client.call('Filecoin.MinerAddresses', [])
|
||||||
|
|
||||||
this.setState(() => ({
|
this.setState(() => ({
|
||||||
id: id,
|
id: id,
|
||||||
version: version,
|
version: version,
|
||||||
@ -56,28 +56,24 @@ class FullNode extends React.Component {
|
|||||||
paychs: paychs,
|
paychs: paychs,
|
||||||
vouchers: vouchers,
|
vouchers: vouchers,
|
||||||
|
|
||||||
defaultAddr: defaultAddr}))
|
defaultAddr: defaultAddr,
|
||||||
|
|
||||||
|
minerList: minerList,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
async startMining() {
|
async newSecpAddr() {
|
||||||
// TODO: Use actual miner address
|
|
||||||
// see cli/miner.go
|
|
||||||
this.setState({mining: true})
|
|
||||||
let addr = "t0101" // in case we have no wallets
|
|
||||||
/*if (this.state.defaultAddr) {
|
|
||||||
addr = this.state.defaultAddr
|
|
||||||
}*/
|
|
||||||
|
|
||||||
this.setState({mining: true})
|
|
||||||
await this.props.client.call("Filecoin.MinerStart", [addr])
|
|
||||||
}
|
|
||||||
|
|
||||||
async newScepAddr() {
|
|
||||||
const t = "secp256k1"
|
const t = "secp256k1"
|
||||||
await this.props.client.call("Filecoin.WalletNew", [t])
|
await this.props.client.call("Filecoin.WalletNew", [t])
|
||||||
this.loadInfo()
|
this.loadInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async newBLSAddr() {
|
||||||
|
const t = "bls"
|
||||||
|
await this.props.client.call("Filecoin.WalletNew", [t])
|
||||||
|
this.loadInfo()
|
||||||
|
}
|
||||||
|
|
||||||
async startStorageMiner() {
|
async startStorageMiner() {
|
||||||
this.props.mountWindow((onClose) => <StorageNodeInit fullRepo={this.props.node.Repo} fullConn={this.props.client} pondClient={this.props.pondClient} onClose={onClose} mountWindow={this.props.mountWindow}/>)
|
this.props.mountWindow((onClose) => <StorageNodeInit fullRepo={this.props.node.Repo} fullConn={this.props.client} pondClient={this.props.pondClient} onClose={onClose} mountWindow={this.props.mountWindow}/>)
|
||||||
}
|
}
|
||||||
@ -105,9 +101,9 @@ class FullNode extends React.Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let mine = <a href="#" disabled={this.state.mining} onClick={this.startMining}>[Mine]</a>
|
let miners = <span/>
|
||||||
if (this.state.mining) {
|
if(this.state.minerList.length > 0) {
|
||||||
mine = "[Mining]"
|
miners = this.state.minerList.map((a, k) => <div key={k}><Address miner={true} client={this.props.client} addr={a} mountWindow={this.props.mountWindow}/></div>)
|
||||||
}
|
}
|
||||||
|
|
||||||
let storageMine = <a href="#" onClick={this.startStorageMiner}>[Spawn Storage Miner]</a>
|
let storageMine = <a href="#" onClick={this.startStorageMiner}>[Spawn Storage Miner]</a>
|
||||||
@ -143,11 +139,12 @@ class FullNode extends React.Component {
|
|||||||
<div>Repo: LOTUS_PATH={this.props.node.Repo}</div>
|
<div>Repo: LOTUS_PATH={this.props.node.Repo}</div>
|
||||||
{chainInfo}
|
{chainInfo}
|
||||||
<div>
|
<div>
|
||||||
{mine} {storageMine}
|
{storageMine}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>Balances: [New <a href="#" onClick={this.newScepAddr}>[Secp256k1]</a>]</div>
|
<div>Balances: [New <a href="#" onClick={this.newSecpAddr}>[Secp256k1]</a> <a href="#" onClick={this.newBLSAddr}>[BLS]</a>]</div>
|
||||||
<div>{addresses}</div>
|
<div>{addresses}</div>
|
||||||
|
<div>{miners}</div>
|
||||||
<div>{paychannels}</div>
|
<div>{paychannels}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ type api struct {
|
|||||||
full.ChainAPI
|
full.ChainAPI
|
||||||
full.MpoolAPI
|
full.MpoolAPI
|
||||||
full.WalletAPI
|
full.WalletAPI
|
||||||
|
full.StateAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMiner(api api) *Miner {
|
func NewMiner(api api) *Miner {
|
||||||
@ -53,6 +54,16 @@ type Miner struct {
|
|||||||
lastWork *MiningBase
|
lastWork *MiningBase
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Miner) Addresses() ([]address.Address, error) {
|
||||||
|
m.lk.Lock()
|
||||||
|
defer m.lk.Unlock()
|
||||||
|
|
||||||
|
out := make([]address.Address, len(m.addresses))
|
||||||
|
copy(out, m.addresses)
|
||||||
|
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Miner) Register(addr address.Address) error {
|
func (m *Miner) Register(addr address.Address) error {
|
||||||
m.lk.Lock()
|
m.lk.Lock()
|
||||||
defer m.lk.Unlock()
|
defer m.lk.Unlock()
|
||||||
@ -171,7 +182,7 @@ func (m *Miner) GetBestMiningCandidate() (*MiningBase, error) {
|
|||||||
return m.lastWork, nil
|
return m.lastWork, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if bts.Weight() <= m.lastWork.ts.Weight() {
|
if types.BigCmp(bts.Weight(), m.lastWork.ts.Weight()) <= 0 {
|
||||||
return m.lastWork, nil
|
return m.lastWork, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,12 +265,12 @@ func (m *Miner) isWinnerNextRound(ctx context.Context, base *MiningBase) (bool,
|
|||||||
return false, nil, xerrors.Errorf("failed to compute VRF: %w", err)
|
return false, nil, xerrors.Errorf("failed to compute VRF: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
mpow, totpow, err := m.getPowerForTipset(ctx, m.addresses[0], base.ts)
|
pow, err := m.api.StateMinerPower(ctx, m.addresses[0], base.ts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil, xerrors.Errorf("failed to check power: %w", err)
|
return false, nil, xerrors.Errorf("failed to check power: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return powerCmp(vrfout, mpow, totpow), vrfout, nil
|
return powerCmp(vrfout, pow.MinerPower, pow.TotalPower), vrfout, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func powerCmp(vrfout []byte, mpow, totpow types.BigInt) bool {
|
func powerCmp(vrfout []byte, mpow, totpow types.BigInt) bool {
|
||||||
@ -280,45 +291,6 @@ func powerCmp(vrfout []byte, mpow, totpow types.BigInt) bool {
|
|||||||
return types.BigCmp(types.BigFromBytes(h[:]), out) < 0
|
return types.BigCmp(types.BigFromBytes(h[:]), out) < 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Miner) getPowerForTipset(ctx context.Context, maddr address.Address, ts *types.TipSet) (types.BigInt, types.BigInt, error) {
|
|
||||||
var err error
|
|
||||||
enc, err := actors.SerializeParams(&actors.PowerLookupParams{maddr})
|
|
||||||
if err != nil {
|
|
||||||
return types.EmptyInt, types.EmptyInt, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ret, err := m.api.ChainCall(ctx, &types.Message{
|
|
||||||
From: maddr,
|
|
||||||
To: actors.StorageMarketAddress,
|
|
||||||
Method: actors.SMAMethods.PowerLookup,
|
|
||||||
Params: enc,
|
|
||||||
}, ts)
|
|
||||||
if err != nil {
|
|
||||||
return types.EmptyInt, types.EmptyInt, xerrors.Errorf("failed to get miner power from chain: %w", err)
|
|
||||||
}
|
|
||||||
if ret.ExitCode != 0 {
|
|
||||||
return types.EmptyInt, types.EmptyInt, xerrors.Errorf("failed to get miner power from chain (exit code %d)", ret.ExitCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
mpow := types.BigFromBytes(ret.Return)
|
|
||||||
|
|
||||||
ret, err = m.api.ChainCall(ctx, &types.Message{
|
|
||||||
From: maddr,
|
|
||||||
To: actors.StorageMarketAddress,
|
|
||||||
Method: actors.SMAMethods.GetTotalStorage,
|
|
||||||
}, ts)
|
|
||||||
if err != nil {
|
|
||||||
return types.EmptyInt, types.EmptyInt, xerrors.Errorf("failed to get total power from chain: %w", err)
|
|
||||||
}
|
|
||||||
if ret.ExitCode != 0 {
|
|
||||||
return types.EmptyInt, types.EmptyInt, xerrors.Errorf("failed to get total power from chain (exit code %d)", ret.ExitCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
tpow := types.BigFromBytes(ret.Return)
|
|
||||||
|
|
||||||
return mpow, tpow, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Miner) runVDF(ctx context.Context, input []byte) ([]byte, []byte, error) {
|
func (m *Miner) runVDF(ctx context.Context, input []byte) ([]byte, []byte, error) {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
|
@ -24,6 +24,10 @@ type FullNodeAPI struct {
|
|||||||
Miner *miner.Miner
|
Miner *miner.Miner
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *FullNodeAPI) MinerAddresses(context.Context) ([]address.Address, error) {
|
||||||
|
return a.Miner.Addresses()
|
||||||
|
}
|
||||||
|
|
||||||
func (a *FullNodeAPI) MinerRegister(ctx context.Context, addr address.Address) error {
|
func (a *FullNodeAPI) MinerRegister(ctx context.Context, addr address.Address) error {
|
||||||
return a.Miner.Register(addr)
|
return a.Miner.Register(addr)
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@ package full
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/vm"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/api"
|
"github.com/filecoin-project/go-lotus/api"
|
||||||
@ -137,3 +140,49 @@ func (a *StateAPI) StateMinerProvingSet(ctx context.Context, addr address.Addres
|
|||||||
})
|
})
|
||||||
return sinfos, nil
|
return sinfos, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *StateAPI) StateMinerPower(ctx context.Context, maddr address.Address, ts *types.TipSet) (api.MinerPower, error) {
|
||||||
|
var err error
|
||||||
|
enc, err := actors.SerializeParams(&actors.PowerLookupParams{maddr})
|
||||||
|
if err != nil {
|
||||||
|
return api.MinerPower{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var mpow types.BigInt
|
||||||
|
|
||||||
|
if maddr != address.Undef {
|
||||||
|
ret, err := vm.Call(ctx, a.Chain, &types.Message{
|
||||||
|
From: maddr,
|
||||||
|
To: actors.StorageMarketAddress,
|
||||||
|
Method: actors.SMAMethods.PowerLookup,
|
||||||
|
Params: enc,
|
||||||
|
}, ts)
|
||||||
|
if err != nil {
|
||||||
|
return api.MinerPower{}, xerrors.Errorf("failed to get miner power from chain: %w", err)
|
||||||
|
}
|
||||||
|
if ret.ExitCode != 0 {
|
||||||
|
return api.MinerPower{}, xerrors.Errorf("failed to get miner power from chain (exit code %d)", ret.ExitCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
mpow = types.BigFromBytes(ret.Return)
|
||||||
|
}
|
||||||
|
|
||||||
|
ret, err := vm.Call(ctx, a.Chain, &types.Message{
|
||||||
|
From: actors.StorageMarketAddress,
|
||||||
|
To: actors.StorageMarketAddress,
|
||||||
|
Method: actors.SMAMethods.GetTotalStorage,
|
||||||
|
}, ts)
|
||||||
|
if err != nil {
|
||||||
|
return api.MinerPower{}, xerrors.Errorf("failed to get total power from chain: %w", err)
|
||||||
|
}
|
||||||
|
if ret.ExitCode != 0 {
|
||||||
|
return api.MinerPower{}, xerrors.Errorf("failed to get total power from chain (exit code %d)", ret.ExitCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
tpow := types.BigFromBytes(ret.Return)
|
||||||
|
|
||||||
|
return api.MinerPower{
|
||||||
|
MinerPower: mpow,
|
||||||
|
TotalPower: tpow,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user