Skip to content

Commit

Permalink
add miner init
Browse files Browse the repository at this point in the history
  • Loading branch information
LexLuthr committed Mar 22, 2024
1 parent ed98bf9 commit 55dab9f
Show file tree
Hide file tree
Showing 2 changed files with 205 additions and 10 deletions.
208 changes: 199 additions & 9 deletions cmd/curio/config_new.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,30 @@ package main

import (
"bytes"
"context"
"crypto/rand"
"encoding/base64"
"fmt"
"io"

"github.com/BurntSushi/toml"
"github.com/docker/go-units"
"github.com/fatih/color"
"github.com/samber/lo"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
power2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/power"
power6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/power"

"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/api/v1api"
"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"
cliutil "github.com/filecoin-project/lotus/cli/util"
"github.com/filecoin-project/lotus/cmd/curio/deps"
Expand All @@ -34,31 +44,64 @@ var configNewCmd = &cli.Command{
Hidden: true,
Value: "~/.lotus",
},
&cli.BoolFlag{
Name: "init",
Usage: "create a new miner on chain and then initiates a new Curio cluster for it",
},
&cli.StringFlag{
Name: "worker",
Aliases: []string{"w"},
Usage: "worker key to use for new miner initialisation",
},
&cli.StringFlag{
Name: "owner",
Aliases: []string{"o"},
Usage: "owner key to use for new miner initialisation",
},
&cli.StringFlag{
Name: "from",
Aliases: []string{"f"},
Usage: "address to send actor(miner) creation message from",
},
&cli.StringFlag{
Name: "sector-size",
Usage: "specify sector size to use for new miner initialisation",
},
},
Action: func(cctx *cli.Context) error {
configColor := color.New(color.FgHiGreen).SprintFunc()

if cctx.Args().Len() < 1 {
return xerrors.New("must specify at least one SP actor address. Use 'lotus-shed miner create'")
if cctx.Args().Len() < 1 && !cctx.Bool("init") {
return xerrors.New("must specify at least one SP actor address or use --init flag to create a new miner")
}

ctx := cctx.Context

db, err := deps.MakeDB(cctx)
if err != nil {
return err
}

full, closer, err := cliutil.GetFullNodeAPIV1(cctx)
if err != nil {
return xerrors.Errorf("connecting to full node: %w", err)
}
defer closer()

addrs := cctx.Args().Slice()

if cctx.Bool("init") {
miner, err := createStorageMiner(ctx, full, cctx)
if err != nil {
return err
}
addrs = []string{miner.String()}
}

db, err := deps.MakeDB(cctx)
if err != nil {
return err
}

var titles []string
err = db.Select(ctx, &titles, `SELECT title FROM harmony_config WHERE LENGTH(config) > 0`)
if err != nil {
return fmt.Errorf("miner cannot reach the db. Ensure the config toml's HarmonyDB entry"+
return xerrors.Errorf("miner cannot reach the db. Ensure the config toml's HarmonyDB entry"+
" is setup to reach Yugabyte correctly: %s", err.Error())
}

Expand All @@ -75,7 +118,7 @@ var configNewCmd = &cli.Command{
// setup config
lpCfg := config.DefaultCurioConfig()

for _, addr := range cctx.Args().Slice() {
for _, addr := range addrs {
maddr, err := address.NewFromString(addr)
if err != nil {
return xerrors.Errorf("Invalid address: %s", addr)
Expand Down Expand Up @@ -157,3 +200,150 @@ var configNewCmd = &cli.Command{
return nil
},
}

func createStorageMiner(ctx context.Context, fullNode v1api.FullNode, cctx *cli.Context) (address.Address, error) {
var err error
var owner address.Address
if cctx.String("owner") == "" {
return address.Undef, xerrors.Errorf("must provide a owner address")
}
owner, err = address.NewFromString(cctx.String("owner"))

if err != nil {
return address.Undef, err
}

worker := owner
if cctx.String("worker") != "" {
worker, err = address.NewFromString(cctx.String("worker"))
if err != nil {
return address.Undef, xerrors.Errorf("could not parse worker address: %w", err)
}
}

sender := owner
if fromstr := cctx.String("from"); fromstr != "" {
faddr, err := address.NewFromString(fromstr)
if err != nil {
return address.Undef, xerrors.Errorf("could not parse from address: %w", err)
}
sender = faddr
}

if !cctx.IsSet("sector-size") {
return address.Undef, xerrors.Errorf("must define sector size")
}

sectorSizeInt, err := units.RAMInBytes(cctx.String("sector-size"))
if err != nil {
return address.Undef, err
}
ssize := abi.SectorSize(sectorSizeInt)

// make sure the sender account exists on chain
_, err = fullNode.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
_, err = fullNode.StateLookupID(ctx, worker, types.EmptyTSK)
if err != nil {
signed, err := fullNode.MpoolPushMessage(ctx, &types.Message{
From: sender,
To: worker,
Value: types.NewInt(0),
}, nil)
if err != nil {
return address.Undef, 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 := fullNode.StateWaitMsg(ctx, signed.Cid(), cctx.Uint64("confidence"), api.LookbackNoLimit, true)
if err != nil {
return address.Undef, xerrors.Errorf("waiting for worker init: %w", err)
}
if mw.Receipt.ExitCode != 0 {
return address.Undef, xerrors.Errorf("initializing worker account failed: exit code %d", mw.Receipt.ExitCode)
}
}

// make sure the owner account exists on chain
_, err = fullNode.StateLookupID(ctx, owner, types.EmptyTSK)
if err != nil {
signed, err := fullNode.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 := fullNode.StateWaitMsg(ctx, signed.Cid(), cctx.Uint64("confidence"), api.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)
}
}

// Note: the correct thing to do would be to call SealProofTypeFromSectorSize if actors version is v3 or later, but this still works
nv, err := fullNode.StateNetworkVersion(ctx, types.EmptyTSK)
if err != nil {
return address.Undef, xerrors.Errorf("failed to get network version: %w", err)
}
spt, err := miner.WindowPoStProofTypeFromSectorSize(ssize, nv)
if err != nil {
return address.Undef, xerrors.Errorf("getting post proof type: %w", err)
}

params, err := actors.SerializeParams(&power6.CreateMinerParams{
Owner: owner,
Worker: worker,
WindowPoStProofType: spt,
})
if err != nil {
return address.Undef, err
}

createStorageMinerMsg := &types.Message{
To: power.Address,
From: sender,
Value: big.Zero(),

Method: power.Methods.CreateMiner,
Params: params,
}

signed, err := fullNode.MpoolPushMessage(ctx, createStorageMinerMsg, nil)
if err != nil {
return address.Undef, xerrors.Errorf("pushing createMiner message: %w", err)
}

log.Infof("Pushed CreateMiner message: %s", signed.Cid())
log.Infof("Waiting for confirmation")

mw, err := fullNode.StateWaitMsg(ctx, signed.Cid(), cctx.Uint64("confidence"), api.LookbackNoLimit, true)
if err != nil {
return address.Undef, xerrors.Errorf("waiting for createMiner message: %w", err)
}

if mw.Receipt.ExitCode != 0 {
return address.Undef, xerrors.Errorf("create miner failed: exit code %d", mw.Receipt.ExitCode)
}

var retval power2.CreateMinerReturn
if err := retval.UnmarshalCBOR(bytes.NewReader(mw.Receipt.Return)); err != nil {
return address.Undef, err
}

log.Infof("New miners address is: %s (%s)", retval.IDAddress, retval.RobustAddress)
return retval.IDAddress, nil
}
7 changes: 6 additions & 1 deletion documentation/en/cli-curio.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,12 @@ USAGE:
curio config new-cluster [command options] [SP actor address...]
OPTIONS:
--help, -h show help
--init create a new miner on chain and then initiates a new Curio cluster for it (default: false)
--worker value, -w value worker key to use for new miner initialisation
--owner value, -o value owner key to use for new miner initialisation
--from value, -f value address to send actor(miner) creation message from
--sector-size value specify sector size to use for new miner initialisation
--help, -h show help
```

## curio test
Expand Down

0 comments on commit 55dab9f

Please sign in to comment.