Merge pull request #7595 from filecoin-project/asr/miner-create
Shed: Add a util to create miners more easily
This commit is contained in:
commit
6056858bf8
@ -67,3 +67,22 @@ func SealProofTypeFromSectorSize(ssize abi.SectorSize, nv network.Version) (abi.
|
|||||||
|
|
||||||
return 0, xerrors.Errorf("unsupported network version")
|
return 0, xerrors.Errorf("unsupported network version")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WindowPoStProofTypeFromSectorSize returns preferred post proof type for creating
|
||||||
|
// new miner actors and new sectors
|
||||||
|
func WindowPoStProofTypeFromSectorSize(ssize abi.SectorSize) (abi.RegisteredPoStProof, error) {
|
||||||
|
switch ssize {
|
||||||
|
case 2 << 10:
|
||||||
|
return abi.RegisteredPoStProof_StackedDrgWindow2KiBV1, nil
|
||||||
|
case 8 << 20:
|
||||||
|
return abi.RegisteredPoStProof_StackedDrgWindow8MiBV1, nil
|
||||||
|
case 512 << 20:
|
||||||
|
return abi.RegisteredPoStProof_StackedDrgWindow512MiBV1, nil
|
||||||
|
case 32 << 30:
|
||||||
|
return abi.RegisteredPoStProof_StackedDrgWindow32GiBV1, nil
|
||||||
|
case 64 << 30:
|
||||||
|
return abi.RegisteredPoStProof_StackedDrgWindow64GiBV1, nil
|
||||||
|
default:
|
||||||
|
return 0, xerrors.Errorf("unsupported sector size for miner: %v", ssize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -13,6 +13,8 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
power6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/power"
|
||||||
|
|
||||||
"github.com/docker/go-units"
|
"github.com/docker/go-units"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/ipfs/go-datastore"
|
"github.com/ipfs/go-datastore"
|
||||||
@ -644,11 +646,26 @@ func createStorageMiner(ctx context.Context, api v1api.FullNode, peerid peer.ID,
|
|||||||
return address.Address{}, err
|
return address.Address{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sender := owner
|
||||||
|
if fromstr := cctx.String("from"); fromstr != "" {
|
||||||
|
faddr, err := address.NewFromString(fromstr)
|
||||||
|
if err != nil {
|
||||||
|
return address.Undef, fmt.Errorf("could not parse from address: %w", err)
|
||||||
|
}
|
||||||
|
sender = faddr
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure the sender account exists on chain
|
||||||
|
_, err = api.StateLookupID(ctx, owner, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return address.Undef, xerrors.Errorf("sender must exist on chain: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
// make sure the worker account exists on chain
|
// make sure the worker account exists on chain
|
||||||
_, err = api.StateLookupID(ctx, worker, types.EmptyTSK)
|
_, err = api.StateLookupID(ctx, worker, types.EmptyTSK)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
signed, err := api.MpoolPushMessage(ctx, &types.Message{
|
signed, err := api.MpoolPushMessage(ctx, &types.Message{
|
||||||
From: owner,
|
From: sender,
|
||||||
To: worker,
|
To: worker,
|
||||||
Value: types.NewInt(0),
|
Value: types.NewInt(0),
|
||||||
}, nil)
|
}, nil)
|
||||||
@ -668,35 +685,46 @@ func createStorageMiner(ctx context.Context, api v1api.FullNode, peerid peer.ID,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nv, err := api.StateNetworkVersion(ctx, types.EmptyTSK)
|
// make sure the owner account exists on chain
|
||||||
|
_, err = api.StateLookupID(ctx, owner, types.EmptyTSK)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return address.Undef, xerrors.Errorf("getting network version: %w", err)
|
signed, err := api.MpoolPushMessage(ctx, &types.Message{
|
||||||
|
From: sender,
|
||||||
|
To: owner,
|
||||||
|
Value: types.NewInt(0),
|
||||||
|
}, nil)
|
||||||
|
if err != nil {
|
||||||
|
return address.Undef, xerrors.Errorf("push owner init: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("Initializing owner account %s, message: %s", worker, signed.Cid())
|
||||||
|
log.Infof("Waiting for confirmation")
|
||||||
|
|
||||||
|
mw, err := api.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence, lapi.LookbackNoLimit, true)
|
||||||
|
if err != nil {
|
||||||
|
return address.Undef, xerrors.Errorf("waiting for owner init: %w", err)
|
||||||
|
}
|
||||||
|
if mw.Receipt.ExitCode != 0 {
|
||||||
|
return address.Undef, xerrors.Errorf("initializing owner account failed: exit code %d", mw.Receipt.ExitCode)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spt, err := miner.SealProofTypeFromSectorSize(abi.SectorSize(ssize), nv)
|
// Note: the correct thing to do would be to call SealProofTypeFromSectorSize if actors version is v3 or later, but this still works
|
||||||
|
spt, err := miner.WindowPoStProofTypeFromSectorSize(abi.SectorSize(ssize))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return address.Undef, xerrors.Errorf("getting seal proof type: %w", err)
|
return address.Undef, xerrors.Errorf("getting post proof type: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
params, err := actors.SerializeParams(&power2.CreateMinerParams{
|
params, err := actors.SerializeParams(&power6.CreateMinerParams{
|
||||||
Owner: owner,
|
Owner: owner,
|
||||||
Worker: worker,
|
Worker: worker,
|
||||||
SealProofType: spt,
|
WindowPoStProofType: spt,
|
||||||
Peer: abi.PeerID(peerid),
|
Peer: abi.PeerID(peerid),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return address.Undef, err
|
return address.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sender := owner
|
|
||||||
if fromstr := cctx.String("from"); fromstr != "" {
|
|
||||||
faddr, err := address.NewFromString(fromstr)
|
|
||||||
if err != nil {
|
|
||||||
return address.Undef, fmt.Errorf("could not parse from address: %w", err)
|
|
||||||
}
|
|
||||||
sender = faddr
|
|
||||||
}
|
|
||||||
|
|
||||||
createStorageMinerMsg := &types.Message{
|
createStorageMinerMsg := &types.Message{
|
||||||
To: power.Address,
|
To: power.Address,
|
||||||
From: sender,
|
From: sender,
|
||||||
|
@ -2,11 +2,27 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
power6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/power"
|
||||||
|
|
||||||
|
"github.com/docker/go-units"
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/lotus/build"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
lcli "github.com/filecoin-project/lotus/cli"
|
||||||
|
|
||||||
"github.com/mitchellh/go-homedir"
|
"github.com/mitchellh/go-homedir"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
@ -17,6 +33,153 @@ var minerCmd = &cli.Command{
|
|||||||
Usage: "miner-related utilities",
|
Usage: "miner-related utilities",
|
||||||
Subcommands: []*cli.Command{
|
Subcommands: []*cli.Command{
|
||||||
minerUnpackInfoCmd,
|
minerUnpackInfoCmd,
|
||||||
|
minerCreateCmd,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var minerCreateCmd = &cli.Command{
|
||||||
|
Name: "create",
|
||||||
|
Usage: "sends a create miner msg",
|
||||||
|
ArgsUsage: "[sender] [owner] [worker] [sector size]",
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
wapi, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer closer()
|
||||||
|
ctx := lcli.ReqContext(cctx)
|
||||||
|
|
||||||
|
if cctx.Args().Len() != 4 {
|
||||||
|
return xerrors.Errorf("expected 4 args (sender owner worker sectorSize)")
|
||||||
|
}
|
||||||
|
|
||||||
|
sender, err := address.NewFromString(cctx.Args().First())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
owner, err := address.NewFromString(cctx.Args().Get(1))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
worker, err := address.NewFromString(cctx.Args().Get(2))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize, err := units.RAMInBytes(cctx.Args().Get(3))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to parse sector size: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure the sender account exists on chain
|
||||||
|
_, err = wapi.StateLookupID(ctx, owner, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("sender must exist on chain: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure the worker account exists on chain
|
||||||
|
_, err = wapi.StateLookupID(ctx, worker, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
signed, err := wapi.MpoolPushMessage(ctx, &types.Message{
|
||||||
|
From: sender,
|
||||||
|
To: worker,
|
||||||
|
Value: types.NewInt(0),
|
||||||
|
}, nil)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("push worker init: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("Initializing worker account %s, message: %s", worker, signed.Cid())
|
||||||
|
log.Infof("Waiting for confirmation")
|
||||||
|
|
||||||
|
mw, err := wapi.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("waiting for worker init: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if mw.Receipt.ExitCode != 0 {
|
||||||
|
return xerrors.Errorf("initializing worker account failed: exit code %d", mw.Receipt.ExitCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure the owner account exists on chain
|
||||||
|
_, err = wapi.StateLookupID(ctx, owner, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
signed, err := wapi.MpoolPushMessage(ctx, &types.Message{
|
||||||
|
From: sender,
|
||||||
|
To: owner,
|
||||||
|
Value: types.NewInt(0),
|
||||||
|
}, nil)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("push owner init: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("Initializing owner account %s, message: %s", worker, signed.Cid())
|
||||||
|
log.Infof("Wating for confirmation")
|
||||||
|
|
||||||
|
mw, err := wapi.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("waiting for owner init: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if mw.Receipt.ExitCode != 0 {
|
||||||
|
return xerrors.Errorf("initializing owner account failed: exit code %d", mw.Receipt.ExitCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: the correct thing to do would be to call SealProofTypeFromSectorSize if actors version is v3 or later, but this still works
|
||||||
|
spt, err := miner.WindowPoStProofTypeFromSectorSize(abi.SectorSize(ssize))
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting post proof type: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
params, err := actors.SerializeParams(&power6.CreateMinerParams{
|
||||||
|
Owner: owner,
|
||||||
|
Worker: worker,
|
||||||
|
WindowPoStProofType: spt,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
createStorageMinerMsg := &types.Message{
|
||||||
|
To: power.Address,
|
||||||
|
From: sender,
|
||||||
|
Value: big.Zero(),
|
||||||
|
|
||||||
|
Method: power.Methods.CreateMiner,
|
||||||
|
Params: params,
|
||||||
|
}
|
||||||
|
|
||||||
|
signed, err := wapi.MpoolPushMessage(ctx, createStorageMinerMsg, nil)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("pushing createMiner message: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("Pushed CreateMiner message: %s", signed.Cid())
|
||||||
|
log.Infof("Waiting for confirmation")
|
||||||
|
|
||||||
|
mw, err := wapi.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("waiting for createMiner message: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if mw.Receipt.ExitCode != 0 {
|
||||||
|
return xerrors.Errorf("create miner failed: exit code %d", mw.Receipt.ExitCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
var retval power6.CreateMinerReturn
|
||||||
|
if err := retval.UnmarshalCBOR(bytes.NewReader(mw.Receipt.Return)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("New miners address is: %s (%s)", retval.IDAddress, retval.RobustAddress)
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user