Merge remote-tracking branch 'origin/next' into feat/actors-miner-refactor

This commit is contained in:
Łukasz Magiera
2020-07-17 15:18:11 +02:00
137 changed files with 1476 additions and 912 deletions
+3 -2
View File
@@ -11,6 +11,7 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli"
@@ -68,7 +69,7 @@ func sendSmallFundsTxs(ctx context.Context, api api.FullNode, from address.Addre
sendSet = append(sendSet, naddr)
}
tick := time.NewTicker(time.Second / time.Duration(rate))
tick := build.Clock.Ticker(time.Second / time.Duration(rate))
for {
select {
case <-tick.C:
@@ -76,7 +77,7 @@ func sendSmallFundsTxs(ctx context.Context, api api.FullNode, from address.Addre
From: from,
To: sendSet[rand.Intn(20)],
Value: types.NewInt(1),
GasLimit: 100000,
GasLimit: 100_000_000,
GasPrice: types.NewInt(0),
}
+9 -6
View File
@@ -405,16 +405,19 @@ func getExtras(ex interface{}) (*string, *float64) {
func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) {
for i, gc := range et.GasCharges {
name := gc.Name
if name == "OnIpldGetStart" {
if name == "OnIpldGetEnd" {
continue
}
tt := float64(gc.TimeTaken.Nanoseconds())
if name == "OnIpldGet" {
prev := et.GasCharges[i-1]
if prev.Name != "OnIpldGetStart" {
log.Warn("OnIpldGet without OnIpldGetStart")
next := &types.GasTrace{}
if i+1 < len(et.GasCharges) {
next = et.GasCharges[i+1]
}
tt += float64(prev.TimeTaken.Nanoseconds())
if next.Name != "OnIpldGetEnd" {
log.Warn("OnIpldGet without OnIpldGetEnd")
}
tt += float64(next.TimeTaken.Nanoseconds())
}
eType, eSize := getExtras(gc.Extra)
if eType != nil {
@@ -604,7 +607,7 @@ var importAnalyzeCmd = &cli.Command{
timeInActors := actorExec.timeTaken.Mean() * actorExec.timeTaken.n
fmt.Printf("Avarage time per epoch in actors: %s (%.1f%%)\n", time.Duration(timeInActors)/time.Duration(totalTipsets), timeInActors/float64(totalTime)*100)
}
if actorExecDone, ok := charges["OnActorExecDone"]; ok {
if actorExecDone, ok := charges["OnMethodInvocationDone"]; ok {
timeInActors := actorExecDone.timeTaken.Mean() * actorExecDone.timeTaken.n
fmt.Printf("Avarage time per epoch in OnActorExecDone %s (%.1f%%)\n", time.Duration(timeInActors)/time.Duration(totalTipsets), timeInActors/float64(totalTime)*100)
}
+221 -4
View File
@@ -3,6 +3,7 @@ package main
import (
"context"
"database/sql"
"strconv"
"sync"
"time"
@@ -330,8 +331,15 @@ create table if not exists miner_sectors_heads
primary key (miner_id,miner_sectors_cid)
);
create type miner_sector_event_type as enum ('ADDED', 'EXTENDED', 'EXPIRED', 'TERMINATED');
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'miner_sector_event_type') THEN
CREATE TYPE miner_sector_event_type AS ENUM
(
'ADDED','EXTENDED', 'EXPIRED', 'TERMINATED'
);
END IF;
END$$;
create table if not exists miner_sector_events
(
@@ -342,7 +350,50 @@ create table if not exists miner_sector_events
constraint miner_sector_events_pk
primary key (sector_id, event, miner_id, state_root)
)
);
create table if not exists market_deal_proposals
(
deal_id bigint not null,
state_root text not null,
piece_cid text not null,
padded_piece_size bigint not null,
unpadded_piece_size bigint not null,
is_verified bool not null,
client_id text not null,
provider_id text not null,
start_epoch bigint not null,
end_epoch bigint not null,
slashed_epoch bigint,
storage_price_per_epoch text not null,
provider_collateral text not null,
client_collateral text not null,
constraint market_deal_proposal_pk
primary key (deal_id)
);
create table if not exists market_deal_states
(
deal_id bigint not null,
sector_start_epoch bigint not null,
last_update_epoch bigint not null,
slash_epoch bigint not null,
state_root text not null,
unique (deal_id, sector_start_epoch, last_update_epoch, slash_epoch),
constraint market_deal_states_pk
primary key (deal_id, state_root)
);
/*
create or replace function miner_tips(epoch bigint)
@@ -854,7 +905,7 @@ func (st *storage) updateMinerSectors(minerTips map[types.TipSetKey][]*minerStat
}
for _, added := range changes.Added {
if _, err := eventStmt.Exec(miner.addr.String(), added.SectorNumber, miner.stateroot.String(), "ADDED"); err != nil {
if _, err := eventStmt.Exec(added.SectorNumber, "ADDED", miner.addr.String(), miner.stateroot.String()); err != nil {
return err
}
}
@@ -902,6 +953,172 @@ func (st *storage) updateMinerSectors(minerTips map[types.TipSetKey][]*minerStat
return updateTx.Commit()
}
func (st *storage) storeMarketActorDealStates(marketTips map[types.TipSetKey]*marketStateInfo, tipHeights []tipsetKeyHeight, api api.FullNode) error {
start := time.Now()
defer func() {
log.Infow("Stored Market Deal States", "duration", time.Since(start).String())
}()
tx, err := st.db.Begin()
if err != nil {
return err
}
if _, err := tx.Exec(`create temp table mds (like market_deal_states excluding constraints) on commit drop;`); err != nil {
return err
}
stmt, err := tx.Prepare(`copy mds (deal_id, sector_start_epoch, last_update_epoch, slash_epoch, state_root) from STDIN`)
if err != nil {
return err
}
for _, th := range tipHeights {
mt := marketTips[th.tsKey]
dealStates, err := api.StateMarketDeals(context.TODO(), mt.tsKey)
if err != nil {
return err
}
for dealID, ds := range dealStates {
id, err := strconv.ParseUint(dealID, 10, 64)
if err != nil {
return err
}
if _, err := stmt.Exec(
id,
ds.State.SectorStartEpoch,
ds.State.LastUpdatedEpoch,
ds.State.SlashEpoch,
mt.stateroot.String(),
); err != nil {
return err
}
}
}
if err := stmt.Close(); err != nil {
return err
}
if _, err := tx.Exec(`insert into market_deal_states select * from mds on conflict do nothing`); err != nil {
return err
}
return tx.Commit()
}
func (st *storage) storeMarketActorDealProposals(marketTips map[types.TipSetKey]*marketStateInfo, tipHeights []tipsetKeyHeight, api api.FullNode) error {
start := time.Now()
defer func() {
log.Infow("Stored Market Deal Proposals", "duration", time.Since(start).String())
}()
tx, err := st.db.Begin()
if err != nil {
return err
}
if _, err := tx.Exec(`create temp table mdp (like market_deal_proposals excluding constraints) on commit drop;`); err != nil {
return xerrors.Errorf("prep temp: %w", err)
}
stmt, err := tx.Prepare(`copy mdp (deal_id, state_root, piece_cid, padded_piece_size, unpadded_piece_size, is_verified, client_id, provider_id, start_epoch, end_epoch, slashed_epoch, storage_price_per_epoch, provider_collateral, client_collateral) from STDIN`)
if err != nil {
return err
}
// insert in sorted order (lowest height -> highest height) since dealid is pk of table.
for _, th := range tipHeights {
mt := marketTips[th.tsKey]
dealStates, err := api.StateMarketDeals(context.TODO(), mt.tsKey)
if err != nil {
return err
}
for dealID, ds := range dealStates {
id, err := strconv.ParseUint(dealID, 10, 64)
if err != nil {
return err
}
if _, err := stmt.Exec(
id,
mt.stateroot.String(),
ds.Proposal.PieceCID.String(),
ds.Proposal.PieceSize,
ds.Proposal.PieceSize.Unpadded(),
ds.Proposal.VerifiedDeal,
ds.Proposal.Client.String(),
ds.Proposal.Provider.String(),
ds.Proposal.StartEpoch,
ds.Proposal.EndEpoch,
nil, // slashed_epoch
ds.Proposal.StoragePricePerEpoch.String(),
ds.Proposal.ProviderCollateral.String(),
ds.Proposal.ClientCollateral.String(),
); err != nil {
return err
}
}
}
if err := stmt.Close(); err != nil {
return err
}
if _, err := tx.Exec(`insert into market_deal_proposals select * from mdp on conflict do nothing`); err != nil {
return err
}
return tx.Commit()
}
func (st *storage) updateMarketActorDealProposals(marketTip map[types.TipSetKey]*marketStateInfo, tipHeights []tipsetKeyHeight, api api.FullNode) error {
start := time.Now()
defer func() {
log.Infow("Updated Market Deal Proposals", "duration", time.Since(start).String())
}()
pred := state.NewStatePredicates(api)
tx, err := st.db.Begin()
if err != nil {
return err
}
stmt, err := tx.Prepare(`update market_deal_proposals set slashed_epoch=$1 where deal_id=$2`)
if err != nil {
return err
}
for _, th := range tipHeights {
mt := marketTip[th.tsKey]
stateDiff := pred.OnStorageMarketActorChanged(pred.OnDealStateChanged(pred.OnDealStateAmtChanged()))
changed, val, err := stateDiff(context.TODO(), mt.parentTsKey, mt.tsKey)
if err != nil {
log.Warnw("error getting market deal state diff", "error", err)
}
if !changed {
continue
}
changes, ok := val.(*state.MarketDealStateChanges)
if !ok {
return xerrors.Errorf("Unknown type returned by Deal State AMT predicate: %T", val)
}
for _, modified := range changes.Modified {
if modified.From.SlashEpoch != modified.To.SlashEpoch {
if _, err := stmt.Exec(modified.To.SlashEpoch, modified.ID); err != nil {
return err
}
}
}
}
if err := stmt.Close(); err != nil {
return err
}
return tx.Commit()
}
func (st *storage) storeHeaders(bhs map[cid.Cid]*types.BlockHeader, sync bool) error {
st.headerLk.Lock()
defer st.headerLk.Unlock()
+90 -13
View File
@@ -7,6 +7,7 @@ import (
"encoding/json"
"fmt"
"math"
"sort"
"sync"
"time"
@@ -18,6 +19,7 @@ import (
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/market"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
@@ -81,6 +83,20 @@ type minerStateInfo struct {
psize uint64
}
type marketStateInfo struct {
// common
act types.Actor
stateroot cid.Cid
// calculating changes
// calculating changes
tsKey types.TipSetKey
parentTsKey types.TipSetKey
// market actor specific
state market.State
}
type actorInfo struct {
stateroot cid.Cid
tsKey types.TipSetKey
@@ -88,6 +104,11 @@ type actorInfo struct {
state string
}
type tipsetKeyHeight struct {
height abi.ChainEpoch
tsKey types.TipSetKey
}
func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types.TipSet, maxBatch int) {
var alk sync.Mutex
@@ -169,6 +190,9 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types.
log.Infow("Starting Sync", "height", minH, "numBlocks", len(toSync), "maxBatch", maxBatch)
// relate tipset keys to height so they may be processed in ascending order.
var tipHeights []tipsetKeyHeight
tipsSeen := make(map[types.TipSetKey]struct{})
// map of addresses to changed actors
var changes map[string]types.Actor
// collect all actor state that has changes between block headers
@@ -276,9 +300,20 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types.
parentTsKey: pts.Parents(),
}
addressToID[addr] = address.Undef
if _, ok := tipsSeen[pts.Key()]; !ok {
tipHeights = append(tipHeights, tipsetKeyHeight{
height: pts.Height(),
tsKey: pts.Key(),
})
}
tipsSeen[pts.Key()] = struct{}{}
alk.Unlock()
}
})
// sort tipHeights in ascending order.
sort.Slice(tipHeights, func(i, j int) bool {
return tipHeights[i].height < tipHeights[j].height
})
// map of tipset to reward state
rewardTips := make(map[types.TipSetKey]*rewardStateInfo, len(changes))
@@ -313,23 +348,28 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types.
log.Infof("Getting actor change info")
// highly likely that the market actor will change at every epoch
marketActorChanges := make(map[types.TipSetKey]*marketStateInfo, len(changes))
minerChanges := 0
for addr, m := range actors {
for actor, c := range m {
// reward actor
if actor.Code == builtin.RewardActorCodeID {
rewardTips[c.tsKey] = &rewardStateInfo{
stateroot: c.stateroot,
baselinePower: big.Zero(),
}
// only want actors with head change events
if _, found := headsSeen[actor.Head]; found {
continue
}
headsSeen[actor.Head] = struct{}{}
// miner actors with head change events
if actor.Code == builtin.StorageMinerActorCodeID {
if _, found := headsSeen[actor.Head]; found {
continue
switch actor.Code {
case builtin.StorageMarketActorCodeID:
marketActorChanges[c.tsKey] = &marketStateInfo{
act: actor,
stateroot: c.stateroot,
tsKey: c.tsKey,
parentTsKey: c.parentTsKey,
state: market.State{},
}
case builtin.StorageMinerActorCodeID:
minerChanges++
minerTips[c.tsKey] = append(minerTips[c.tsKey], &minerStateInfo{
@@ -346,10 +386,14 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types.
rawPower: big.Zero(),
qalPower: big.Zero(),
})
headsSeen[actor.Head] = struct{}{}
// reward actor
case builtin.RewardActorCodeID:
rewardTips[c.tsKey] = &rewardStateInfo{
stateroot: c.stateroot,
baselinePower: big.Zero(),
}
}
continue
}
}
@@ -440,6 +484,21 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types.
})
log.Infow("Completed Miner Processing", "duration", time.Since(minerProcessingStartedAt).String(), "processed", minerChanges)
log.Info("Getting market actor info")
// TODO: consider taking the min of the array length and using that for concurrency param, e.g:
// concurrency := math.Min(len(marketActorChanges), 50)
parmap.Par(50, parmap.MapArr(marketActorChanges), func(mrktInfo *marketStateInfo) {
astb, err := api.ChainReadObj(ctx, mrktInfo.act.Head)
if err != nil {
log.Error(err)
return
}
if err := mrktInfo.state.UnmarshalCBOR(bytes.NewReader(astb)); err != nil {
log.Error(err)
return
}
})
log.Info("Getting receipts")
receipts := fetchParentReceipts(ctx, api, toSync)
@@ -501,6 +560,24 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types.
return
}
log.Info("Storing market actor deal proposal info")
if err := st.storeMarketActorDealProposals(marketActorChanges, tipHeights, api); err != nil {
log.Error(err)
return
}
log.Info("Storing market actor deal state info")
if err := st.storeMarketActorDealStates(marketActorChanges, tipHeights, api); err != nil {
log.Error(err)
return
}
log.Info("Updating market actor deal proposal info")
if err := st.updateMarketActorDealProposals(marketActorChanges, tipHeights, api); err != nil {
log.Error(err)
return
}
log.Infof("Storing messages")
if err := st.storeMessages(msgs); err != nil {
+5 -5
View File
@@ -281,7 +281,7 @@ func (h *handler) send(w http.ResponseWriter, r *http.Request) {
To: to,
GasPrice: types.NewInt(0),
GasLimit: 10000,
GasLimit: 100_000_000,
})
if err != nil {
w.WriteHeader(400)
@@ -355,7 +355,7 @@ func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) {
To: owner,
GasPrice: types.NewInt(0),
GasLimit: 10000,
GasLimit: 100_000_000,
})
if err != nil {
w.WriteHeader(400)
@@ -391,7 +391,7 @@ func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) {
Method: builtin.MethodsPower.CreateMiner,
Params: params,
GasLimit: 10000000,
GasLimit: 100_000_000,
GasPrice: types.NewInt(0),
}
@@ -424,7 +424,7 @@ func (h *handler) msgwait(w http.ResponseWriter, r *http.Request) {
if mw.Receipt.ExitCode != 0 {
w.WriteHeader(400)
w.Write([]byte(xerrors.Errorf("create storage miner failed: exit code %d", mw.Receipt.ExitCode).Error()))
w.Write([]byte(xerrors.Errorf("create miner failed: exit code %d", mw.Receipt.ExitCode).Error()))
return
}
w.WriteHeader(200)
@@ -447,7 +447,7 @@ func (h *handler) msgwaitaddr(w http.ResponseWriter, r *http.Request) {
if mw.Receipt.ExitCode != 0 {
w.WriteHeader(400)
w.Write([]byte(xerrors.Errorf("create storage miner failed: exit code %d", mw.Receipt.ExitCode).Error()))
w.Write([]byte(xerrors.Errorf("create miner failed: exit code %d", mw.Receipt.ExitCode).Error()))
return
}
w.WriteHeader(200)
+3 -3
View File
@@ -1,14 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Creating Storage Miner - Lotus Fountain</title>
<title>Creating Miner - Lotus Fountain</title>
<link rel="stylesheet" type="text/css" href="main.css">
</head>
<body>
<div class="Index">
<div class="Index-nodes">
<div class="Index-node">
[CREATING STORAGE MINER]
[CREATING MINER]
</div>
<div class="Index-node" id="formnd">
<form id="f" action='/mkminer' method='POST'>
@@ -26,7 +26,7 @@
<b>Waiting for transaction on chain..</b>
</div>
<div class="Index-node">
<span>When creating storage miner, DO NOT REFRESH THE PAGE, wait for it to load. This can take more than 5min.</span>
<span>When creating miner, DO NOT REFRESH THE PAGE, wait for it to load. This can take more than 5min.</span>
</div>
<div class="Index-node">
<span>If you don't have an owner/worker address, you can create it by following <a target="_blank" href="https://docs.lotu.sh/en+mining#get-started-22083">these instructions</a>.</span>
+5 -5
View File
@@ -1,14 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Creating Storage Miner (wait) - Lotus Fountain</title>
<title>Creating Miner (wait) - Lotus Fountain</title>
<link rel="stylesheet" type="text/css" href="main.css">
</head>
<body>
<div class="Index">
<div class="Index-nodes">
<div class="Index-node">
[CREATING STORAGE MINER]
[CREATING MINER]
</div>
<div class="Index-node">
Gas Funds:&nbsp;&nbsp;&nbsp;<span id="fcid"></span> - <span id="fstate">WAIT</span>
@@ -17,12 +17,12 @@
Miner Actor:&nbsp;<span id="mcid"></span> - <span id="mstate">WAIT</span>
</div>
<div class="Index-node" style="display: none" id="fwait">
New storage miners address is: <b id="actaddr">t</b>
New miners address is: <b id="actaddr">t</b>
</div>
<div class="Index-node" style="display: none" id="mwait">
<div style="padding-bottom: 1em">To initialize the storage miner run the following command:</div>
<div style="padding-bottom: 1em">To initialize the miner run the following command:</div>
<div style="overflow-x: visible; white-space: nowrap; background: #353500">
<code>lotus-storage-miner init --actor=<span id="actaddr2">t</span> --owner=<span id="owner">t3</span></code>
<code>lotus-miner init --actor=<span id="actaddr2">t</span> --owner=<span id="owner">t3</span></code>
</div>
</div>
</div>
+16 -10
View File
@@ -36,7 +36,9 @@ import (
var log = logging.Logger("main")
const FlagStorageRepo = "workerrepo"
const FlagWorkerRepo = "worker-repo"
// TODO remove after deprecation period
const FlagWorkerRepoDeprecation = "workerrepo"
func main() {
lotuslog.SetupLogLevels()
@@ -48,19 +50,23 @@ func main() {
}
app := &cli.App{
Name: "lotus-seal-worker",
Usage: "Remote storage miner worker",
Name: "lotus-worker",
Usage: "Remote miner worker",
Version: build.UserVersion(),
Flags: []cli.Flag{
&cli.StringFlag{
Name: FlagStorageRepo,
EnvVars: []string{"WORKER_PATH"},
Name: FlagWorkerRepo,
Aliases: []string{FlagWorkerRepoDeprecation},
EnvVars: []string{"LOTUS_WORKER_PATH", "WORKER_PATH"},
Value: "~/.lotusworker", // TODO: Consider XDG_DATA_HOME
Usage: fmt.Sprintf("Specify worker repo path. flag %s and env WORKER_PATH are DEPRECATION, will REMOVE SOON", FlagWorkerRepoDeprecation),
},
&cli.StringFlag{
Name: "storagerepo",
EnvVars: []string{"LOTUS_STORAGE_PATH"},
Value: "~/.lotusstorage", // TODO: Consider XDG_DATA_HOME
Name: "miner-repo",
Aliases: []string{"storagerepo"},
EnvVars: []string{"LOTUS_MINER_PATH", "LOTUS_STORAGE_PATH"},
Value: "~/.lotusminer", // TODO: Consider XDG_DATA_HOME
Usage: fmt.Sprintf("Specify miner repo path. flag storagerepo and env LOTUS_STORAGE_PATH are DEPRECATION, will REMOVE SOON"),
},
&cli.BoolFlag{
Name: "enable-gpu-proving",
@@ -143,7 +149,7 @@ var runCmd = &cli.Command{
return err
}
if v.APIVersion != build.APIVersion {
return xerrors.Errorf("lotus-storage-miner API version doesn't match: local: ", api.Version{APIVersion: build.APIVersion})
return xerrors.Errorf("lotus-miner API version doesn't match: local: ", api.Version{APIVersion: build.APIVersion})
}
log.Infof("Remote version %s", v)
@@ -186,7 +192,7 @@ var runCmd = &cli.Command{
// Open repo
repoPath := cctx.String(FlagStorageRepo)
repoPath := cctx.String(FlagWorkerRepo)
r, err := repo.NewFS(repoPath)
if err != nil {
return err
+1 -1
View File
@@ -89,7 +89,7 @@ var noncefix = &cli.Command{
From: addr,
To: addr,
Value: types.NewInt(1),
GasLimit: 10000,
GasLimit: 100_000_000,
GasPrice: types.NewInt(1),
Nonce: i,
}
+2 -2
View File
@@ -76,7 +76,7 @@ var verifRegAddVerifierCmd = &cli.Command{
From: fromk,
Method: builtin.MethodsVerifiedRegistry.AddVerifier,
GasPrice: types.NewInt(1),
GasLimit: 300000,
GasLimit: 100_000_000,
Params: params,
}
@@ -152,7 +152,7 @@ var verifRegVerifyClientCmd = &cli.Command{
From: fromk,
Method: builtin.MethodsVerifiedRegistry.AddVerifiedClient,
GasPrice: types.NewInt(1),
GasLimit: 300000,
GasLimit: 100_000_000,
Params: params,
}
+1 -1
View File
@@ -23,7 +23,7 @@ import (
var infoCmd = &cli.Command{
Name: "info",
Usage: "Print storage miner info",
Usage: "Print miner info",
Flags: []cli.Flag{
&cli.BoolFlag{Name: "color"},
},
+14 -14
View File
@@ -50,7 +50,7 @@ import (
var initCmd = &cli.Command{
Name: "init",
Usage: "Initialize a lotus storage miner repo",
Usage: "Initialize a lotus miner repo",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "actor",
@@ -107,7 +107,7 @@ var initCmd = &cli.Command{
},
},
Action: func(cctx *cli.Context) error {
log.Info("Initializing lotus storage miner")
log.Info("Initializing lotus miner")
sectorSizeInt, err := units.RAMInBytes(cctx.String("sector-size"))
if err != nil {
@@ -151,7 +151,7 @@ var initCmd = &cli.Command{
log.Info("Checking if repo exists")
repoPath := cctx.String(FlagStorageRepo)
repoPath := cctx.String(FlagMinerRepo)
r, err := repo.NewFS(repoPath)
if err != nil {
return err
@@ -162,7 +162,7 @@ var initCmd = &cli.Command{
return err
}
if ok {
return xerrors.Errorf("repo at '%s' is already initialized", cctx.String(FlagStorageRepo))
return xerrors.Errorf("repo at '%s' is already initialized", cctx.String(FlagMinerRepo))
}
log.Info("Checking full node version")
@@ -236,7 +236,7 @@ var initCmd = &cli.Command{
}
if err := storageMinerInit(ctx, cctx, api, r, ssize, gasPrice); err != nil {
log.Errorf("Failed to initialize lotus-storage-miner: %+v", err)
log.Errorf("Failed to initialize lotus-miner: %+v", err)
path, err := homedir.Expand(repoPath)
if err != nil {
return err
@@ -249,7 +249,7 @@ var initCmd = &cli.Command{
}
// TODO: Point to setting storage price, maybe do it interactively or something
log.Info("Storage miner successfully created, you can now start it with 'lotus-storage-miner run'")
log.Info("Miner successfully created, you can now start it with 'lotus-miner run'")
return nil
},
@@ -454,11 +454,11 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode,
cerr := configureStorageMiner(ctx, api, a, peerid, gasPrice)
if err := m.Stop(ctx); err != nil {
log.Error("failed to shut down storage miner: ", err)
log.Error("failed to shut down miner: ", err)
}
if cerr != nil {
return xerrors.Errorf("failed to configure storage miner: %w", cerr)
return xerrors.Errorf("failed to configure miner: %w", cerr)
}
}
@@ -492,7 +492,7 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode,
}
if err := configureStorageMiner(ctx, api, a, peerid, gasPrice); err != nil {
return xerrors.Errorf("failed to configure storage miner: %w", err)
return xerrors.Errorf("failed to configure miner: %w", err)
}
addr = a
@@ -505,7 +505,7 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode,
addr = a
}
log.Infof("Created new storage miner: %s", addr)
log.Infof("Created new miner: %s", addr)
if err := mds.Put(datastore.NewKey("miner-address"), addr.Bytes()); err != nil {
return err
}
@@ -557,7 +557,7 @@ func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address.
Params: enc,
Value: types.NewInt(0),
GasPrice: gasPrice,
GasLimit: 99999999,
GasLimit: 100_000_000,
}
smsg, err := api.MpoolPushMessage(ctx, msg)
@@ -636,7 +636,7 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID,
Method: builtin.MethodsPower.CreateMiner,
Params: params,
GasLimit: 10000000,
GasLimit: 100_000_000,
GasPrice: gasPrice,
}
@@ -654,7 +654,7 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID,
}
if mw.Receipt.ExitCode != 0 {
return address.Undef, xerrors.Errorf("create storage miner failed: exit code %d", mw.Receipt.ExitCode)
return address.Undef, xerrors.Errorf("create miner failed: exit code %d", mw.Receipt.ExitCode)
}
var retval power.CreateMinerReturn
@@ -662,6 +662,6 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID,
return address.Undef, err
}
log.Infof("New storage miners address is: %s (%s)", retval.IDAddress, retval.RobustAddress)
log.Infof("New miners address is: %s (%s)", retval.IDAddress, retval.RobustAddress)
return retval.IDAddress, nil
}
+11 -6
View File
@@ -2,6 +2,7 @@ package main
import (
"context"
"fmt"
"os"
logging "github.com/ipfs/go-log/v2"
@@ -20,7 +21,9 @@ import (
var log = logging.Logger("main")
const FlagStorageRepo = "storagerepo"
const FlagMinerRepo = "miner-repo"
// TODO remove after deprecation period
const FlagMinerRepoDeprecation = "storagerepo"
func main() {
lotuslog.SetupLogLevels()
@@ -61,8 +64,8 @@ func main() {
}
app := &cli.App{
Name: "lotus-storage-miner",
Usage: "Filecoin decentralized storage network storage miner",
Name: "lotus-miner",
Usage: "Filecoin decentralized storage network miner",
Version: build.UserVersion(),
EnableBashCompletion: true,
Flags: []cli.Flag{
@@ -79,9 +82,11 @@ func main() {
Value: "~/.lotus", // TODO: Consider XDG_DATA_HOME
},
&cli.StringFlag{
Name: FlagStorageRepo,
EnvVars: []string{"LOTUS_STORAGE_PATH"},
Value: "~/.lotusstorage", // TODO: Consider XDG_DATA_HOME
Name: FlagMinerRepo,
Aliases: []string{FlagMinerRepoDeprecation},
EnvVars: []string{"LOTUS_MINER_PATH", "LOTUS_STORAGE_PATH"},
Value: "~/.lotusminer", // TODO: Consider XDG_DATA_HOME
Usage: fmt.Sprintf("Specify miner repo path. flag(%s) and env(LOTUS_STORAGE_PATH) are DEPRECATION, will REMOVE SOON", FlagMinerRepoDeprecation),
},
},
+31 -3
View File
@@ -6,6 +6,7 @@ import (
"fmt"
"os"
"path/filepath"
"strconv"
"text/tabwriter"
"time"
@@ -296,6 +297,7 @@ var storageDealsCmd = &cli.Command{
setBlocklistCmd,
getBlocklistCmd,
resetBlocklistCmd,
setSealDurationCmd,
},
}
@@ -357,7 +359,7 @@ var dealsListCmd = &cli.Command{
var getBlocklistCmd = &cli.Command{
Name: "get-blocklist",
Usage: "List the contents of the storage miner's piece CID blocklist",
Usage: "List the contents of the miner's piece CID blocklist",
Flags: []cli.Flag{
&CidBaseFlag,
},
@@ -388,7 +390,7 @@ var getBlocklistCmd = &cli.Command{
var setBlocklistCmd = &cli.Command{
Name: "set-blocklist",
Usage: "Set the storage miner's list of blocklisted piece CIDs",
Usage: "Set the miner's list of blocklisted piece CIDs",
ArgsUsage: "[<path-of-file-containing-newline-delimited-piece-CIDs> (optional, will read from stdin if omitted)]",
Flags: []cli.Flag{},
Action: func(cctx *cli.Context) error {
@@ -435,7 +437,7 @@ var setBlocklistCmd = &cli.Command{
var resetBlocklistCmd = &cli.Command{
Name: "reset-blocklist",
Usage: "Remove all entries from the storage miner's piece CID blocklist",
Usage: "Remove all entries from the miner's piece CID blocklist",
Flags: []cli.Flag{},
Action: func(cctx *cli.Context) error {
api, closer, err := lcli.GetStorageMinerAPI(cctx)
@@ -447,3 +449,29 @@ var resetBlocklistCmd = &cli.Command{
return api.DealsSetPieceCidBlocklist(lcli.DaemonContext(cctx), []cid.Cid{})
},
}
var setSealDurationCmd = &cli.Command{
Name: "set-seal-duration",
Usage: "Set the expected time, in minutes, that you expect sealing sectors to take. Deals that start before this duration will be rejected.",
ArgsUsage: "<minutes>",
Action: func(cctx *cli.Context) error {
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := lcli.ReqContext(cctx)
if cctx.Args().Len() != 1 {
return xerrors.Errorf("must pass duration in minutes")
}
hs, err := strconv.ParseUint(cctx.Args().Get(0), 10, 64)
if err != nil {
return xerrors.Errorf("could not parse duration: %w", err)
}
delay := hs * uint64(time.Minute)
return nodeApi.SectorSetExpectedSealDuration(ctx, time.Duration(delay))
},
}
+4 -4
View File
@@ -30,7 +30,7 @@ import (
var runCmd = &cli.Command{
Name: "run",
Usage: "Start a lotus storage miner process",
Usage: "Start a lotus miner process",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "api",
@@ -86,8 +86,8 @@ var runCmd = &cli.Command{
}
}
storageRepoPath := cctx.String(FlagStorageRepo)
r, err := repo.NewFS(storageRepoPath)
minerRepoPath := cctx.String(FlagMinerRepo)
r, err := repo.NewFS(minerRepoPath)
if err != nil {
return err
}
@@ -97,7 +97,7 @@ var runCmd = &cli.Command{
return err
}
if !ok {
return xerrors.Errorf("repo at '%s' is not initialized, run 'lotus-storage-miner init' to set it up", storageRepoPath)
return xerrors.Errorf("repo at '%s' is not initialized, run 'lotus-miner init' to set it up", minerRepoPath)
}
shutdownChan := make(chan struct{})
+1 -1
View File
@@ -10,7 +10,7 @@ import (
var stopCmd = &cli.Command{
Name: "stop",
Usage: "Stop a running lotus storage miner",
Usage: "Stop a running lotus miner",
Flags: []cli.Flag{},
Action: func(cctx *cli.Context) error {
api, closer, err := lcli.GetAPI(cctx)
+1 -1
View File
@@ -278,7 +278,7 @@ var storageFindCmd = &cli.Command{
}
if !cctx.Args().Present() {
return xerrors.New("Usage: lotus-storage-miner storage find [sector number]")
return xerrors.New("Usage: lotus-miner storage find [sector number]")
}
snum, err := strconv.ParseUint(cctx.Args().First(), 10, 64)