Skip to content

Commit 9f9dc97

Browse files
LexLuthrmagik6ksnadrus
authored
feat: curio: add miner init (#11775)
* sptool: Initial structure * sptool: Port lotus-miner actor withdraw * sptool: Make cli docsgen happy * actors are done * info * proving * sptool the rest * fixed gitignore * lints * oops * 2 * terminate * fixes * curio new-miner setup * reword doc section * fix curio flags * fix gen * change repetitive prompt * add miner to base * add config test * fix config compare, add tests * go mod tidy * fix itest in GA * fix comparer function * fix compare value match --------- Co-authored-by: Łukasz Magiera <magik6k@gmail.com> Co-authored-by: Andrew Jackson (Ajax) <snadrus@gmail.com>
1 parent f1c04c8 commit 9f9dc97

23 files changed

Lines changed: 3132 additions & 916 deletions

File tree

.circleci/config.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,12 @@ workflows:
554554
- build
555555
suite: itest-cli
556556
target: "./itests/cli_test.go"
557+
- test:
558+
name: test-itest-curio
559+
requires:
560+
- build
561+
suite: itest-curio
562+
target: "./itests/curio_test.go"
557563
- test:
558564
name: test-itest-deadlines
559565
requires:

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ jobs:
124124
# A list of test groups that require YugabyteDB to be running
125125
# In CircleCI, all jobs had yugabytedb running as a sidecar.
126126
yugabytedb: |
127-
["itest-harmonydb", "itest-harmonytask"]
127+
["itest-harmonydb", "itest-harmonytask", "itest-curio"]
128128
# A list of test groups that require Proof Parameters to be fetched
129129
# In CircleCI, only the following jobs had get-params set:
130130
# - unit-cli (✅)

cli/spcli/actor.go

Lines changed: 195 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package spcli
22

33
import (
44
"bytes"
5+
"context"
56
"fmt"
67
"strconv"
78

9+
"github.com/docker/go-units"
810
cbor "github.com/ipfs/go-ipld-cbor"
911
"github.com/libp2p/go-libp2p/core/peer"
1012
ma "github.com/multiformats/go-multiaddr"
@@ -19,16 +21,20 @@ import (
1921
"github.com/filecoin-project/go-state-types/builtin"
2022
"github.com/filecoin-project/go-state-types/builtin/v9/miner"
2123
"github.com/filecoin-project/go-state-types/network"
24+
power2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/power"
25+
power6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/power"
2226

23-
"github.com/filecoin-project/lotus/api"
2427
lapi "github.com/filecoin-project/lotus/api"
28+
"github.com/filecoin-project/lotus/api/v1api"
2529
"github.com/filecoin-project/lotus/blockstore"
2630
"github.com/filecoin-project/lotus/build"
2731
"github.com/filecoin-project/lotus/chain/actors"
2832
"github.com/filecoin-project/lotus/chain/actors/adt"
2933
lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
34+
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
3035
"github.com/filecoin-project/lotus/chain/types"
3136
lcli "github.com/filecoin-project/lotus/cli"
37+
cliutil "github.com/filecoin-project/lotus/cli/util"
3238
"github.com/filecoin-project/lotus/node/impl"
3339
)
3440

@@ -1225,7 +1231,7 @@ func ActorCompactAllocatedCmd(getActor ActorAddressGetter) *cli.Command {
12251231
}
12261232
}
12271233

1228-
func isController(mi api.MinerInfo, addr address.Address) bool {
1234+
func isController(mi lapi.MinerInfo, addr address.Address) bool {
12291235
if addr == mi.Owner || addr == mi.Worker {
12301236
return true
12311237
}
@@ -1238,3 +1244,190 @@ func isController(mi api.MinerInfo, addr address.Address) bool {
12381244

12391245
return false
12401246
}
1247+
1248+
var ActorNewMinerCmd = &cli.Command{
1249+
Name: "new-miner",
1250+
Usage: "Initializes a new miner actor",
1251+
Flags: []cli.Flag{
1252+
&cli.StringFlag{
1253+
Name: "worker",
1254+
Aliases: []string{"w"},
1255+
Usage: "worker key to use for new miner initialisation",
1256+
},
1257+
&cli.StringFlag{
1258+
Name: "owner",
1259+
Aliases: []string{"o"},
1260+
Usage: "owner key to use for new miner initialisation",
1261+
},
1262+
&cli.StringFlag{
1263+
Name: "from",
1264+
Aliases: []string{"f"},
1265+
Usage: "address to send actor(miner) creation message from",
1266+
},
1267+
&cli.StringFlag{
1268+
Name: "sector-size",
1269+
Usage: "specify sector size to use for new miner initialisation",
1270+
},
1271+
},
1272+
Action: func(cctx *cli.Context) error {
1273+
ctx := cctx.Context
1274+
1275+
full, closer, err := cliutil.GetFullNodeAPIV1(cctx)
1276+
if err != nil {
1277+
return xerrors.Errorf("connecting to full node: %w", err)
1278+
}
1279+
defer closer()
1280+
1281+
var owner address.Address
1282+
if cctx.String("owner") == "" {
1283+
return xerrors.Errorf("must provide a owner address")
1284+
}
1285+
owner, err = address.NewFromString(cctx.String("owner"))
1286+
1287+
if err != nil {
1288+
return err
1289+
}
1290+
1291+
worker := owner
1292+
if cctx.String("worker") != "" {
1293+
worker, err = address.NewFromString(cctx.String("worker"))
1294+
if err != nil {
1295+
return xerrors.Errorf("could not parse worker address: %w", err)
1296+
}
1297+
}
1298+
1299+
sender := owner
1300+
if fromstr := cctx.String("from"); fromstr != "" {
1301+
faddr, err := address.NewFromString(fromstr)
1302+
if err != nil {
1303+
return xerrors.Errorf("could not parse from address: %w", err)
1304+
}
1305+
sender = faddr
1306+
}
1307+
1308+
if !cctx.IsSet("sector-size") {
1309+
return xerrors.Errorf("must define sector size")
1310+
}
1311+
1312+
sectorSizeInt, err := units.RAMInBytes(cctx.String("sector-size"))
1313+
if err != nil {
1314+
return err
1315+
}
1316+
ssize := abi.SectorSize(sectorSizeInt)
1317+
1318+
_, err = CreateStorageMiner(ctx, full, owner, worker, sender, ssize, cctx.Uint64("confidence"))
1319+
if err != nil {
1320+
return err
1321+
}
1322+
return nil
1323+
},
1324+
}
1325+
1326+
func CreateStorageMiner(ctx context.Context, fullNode v1api.FullNode, owner, worker, sender address.Address, ssize abi.SectorSize, confidence uint64) (address.Address, error) {
1327+
// make sure the sender account exists on chain
1328+
_, err := fullNode.StateLookupID(ctx, owner, types.EmptyTSK)
1329+
if err != nil {
1330+
return address.Undef, xerrors.Errorf("sender must exist on chain: %w", err)
1331+
}
1332+
1333+
// make sure the worker account exists on chain
1334+
_, err = fullNode.StateLookupID(ctx, worker, types.EmptyTSK)
1335+
if err != nil {
1336+
signed, err := fullNode.MpoolPushMessage(ctx, &types.Message{
1337+
From: sender,
1338+
To: worker,
1339+
Value: types.NewInt(0),
1340+
}, nil)
1341+
if err != nil {
1342+
return address.Undef, xerrors.Errorf("push worker init: %w", err)
1343+
}
1344+
1345+
fmt.Printf("Initializing worker account %s, message: %s\n", worker, signed.Cid())
1346+
fmt.Println("Waiting for confirmation")
1347+
1348+
mw, err := fullNode.StateWaitMsg(ctx, signed.Cid(), confidence, 2000, true)
1349+
if err != nil {
1350+
return address.Undef, xerrors.Errorf("waiting for worker init: %w", err)
1351+
}
1352+
if mw.Receipt.ExitCode != 0 {
1353+
return address.Undef, xerrors.Errorf("initializing worker account failed: exit code %d", mw.Receipt.ExitCode)
1354+
}
1355+
}
1356+
1357+
// make sure the owner account exists on chain
1358+
_, err = fullNode.StateLookupID(ctx, owner, types.EmptyTSK)
1359+
if err != nil {
1360+
signed, err := fullNode.MpoolPushMessage(ctx, &types.Message{
1361+
From: sender,
1362+
To: owner,
1363+
Value: types.NewInt(0),
1364+
}, nil)
1365+
if err != nil {
1366+
return address.Undef, xerrors.Errorf("push owner init: %w", err)
1367+
}
1368+
1369+
fmt.Printf("Initializing owner account %s, message: %s\n", worker, signed.Cid())
1370+
fmt.Println("Waiting for confirmation")
1371+
1372+
mw, err := fullNode.StateWaitMsg(ctx, signed.Cid(), confidence, 2000, true)
1373+
if err != nil {
1374+
return address.Undef, xerrors.Errorf("waiting for owner init: %w", err)
1375+
}
1376+
if mw.Receipt.ExitCode != 0 {
1377+
return address.Undef, xerrors.Errorf("initializing owner account failed: exit code %d", mw.Receipt.ExitCode)
1378+
}
1379+
}
1380+
1381+
// Note: the correct thing to do would be to call SealProofTypeFromSectorSize if actors version is v3 or later, but this still works
1382+
nv, err := fullNode.StateNetworkVersion(ctx, types.EmptyTSK)
1383+
if err != nil {
1384+
return address.Undef, xerrors.Errorf("failed to get network version: %w", err)
1385+
}
1386+
spt, err := lminer.WindowPoStProofTypeFromSectorSize(ssize, nv)
1387+
if err != nil {
1388+
return address.Undef, xerrors.Errorf("getting post proof type: %w", err)
1389+
}
1390+
1391+
params, err := actors.SerializeParams(&power6.CreateMinerParams{
1392+
Owner: owner,
1393+
Worker: worker,
1394+
WindowPoStProofType: spt,
1395+
})
1396+
if err != nil {
1397+
return address.Undef, err
1398+
}
1399+
1400+
createStorageMinerMsg := &types.Message{
1401+
To: power.Address,
1402+
From: sender,
1403+
Value: big.Zero(),
1404+
1405+
Method: power.Methods.CreateMiner,
1406+
Params: params,
1407+
}
1408+
1409+
signed, err := fullNode.MpoolPushMessage(ctx, createStorageMinerMsg, nil)
1410+
if err != nil {
1411+
return address.Undef, xerrors.Errorf("pushing createMiner message: %w", err)
1412+
}
1413+
1414+
fmt.Printf("Pushed CreateMiner message: %s\n", signed.Cid())
1415+
fmt.Println("Waiting for confirmation")
1416+
1417+
mw, err := fullNode.StateWaitMsg(ctx, signed.Cid(), confidence, 2000, true)
1418+
if err != nil {
1419+
return address.Undef, xerrors.Errorf("waiting for createMiner message: %w", err)
1420+
}
1421+
1422+
if mw.Receipt.ExitCode != 0 {
1423+
return address.Undef, xerrors.Errorf("create miner failed: exit code %d", mw.Receipt.ExitCode)
1424+
}
1425+
1426+
var retval power2.CreateMinerReturn
1427+
if err := retval.UnmarshalCBOR(bytes.NewReader(mw.Receipt.Return)); err != nil {
1428+
return address.Undef, err
1429+
}
1430+
1431+
fmt.Printf("New miners address is: %s (%s)\n", retval.IDAddress, retval.RobustAddress)
1432+
return retval.IDAddress, nil
1433+
}

cmd/curio/config.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -352,15 +352,6 @@ var configEditCmd = &cli.Command{
352352
},
353353
}
354354

355-
func getDefaultConfig(comment bool) (string, error) {
356-
c := config.DefaultCurioConfig()
357-
cb, err := config.ConfigUpdate(c, nil, config.Commented(comment), config.DefaultKeepUncommented(), config.NoEnv())
358-
if err != nil {
359-
return "", err
360-
}
361-
return string(cb), nil
362-
}
363-
364355
func diff(sourceConf, newConf string) (string, error) {
365356
lpSrc := config.DefaultCurioConfig()
366357
lpNew := config.DefaultCurioConfig()

0 commit comments

Comments
 (0)