diff --git a/cmd/lotus-seed/genesis.go b/cmd/lotus-seed/genesis.go new file mode 100644 index 000000000..039fc5dfb --- /dev/null +++ b/cmd/lotus-seed/genesis.go @@ -0,0 +1,142 @@ +package main + +import ( + "encoding/json" + "io/ioutil" + + "github.com/google/uuid" + "github.com/mitchellh/go-homedir" + "golang.org/x/xerrors" + "gopkg.in/urfave/cli.v2" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/specs-actors/actors/abi/big" + + genesis2 "github.com/filecoin-project/lotus/chain/gen/genesis" + "github.com/filecoin-project/lotus/genesis" +) + +var genesisCmd = &cli.Command{ + Name: "genesis", + Description: "manipulate lotus genesis template", + Subcommands: []*cli.Command{ + genesisNewCmd, + genesisAddMinerCmd, + }, +} + +var genesisNewCmd = &cli.Command{ + Name: "new", + Description: "create new genesis template", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "network-name", + }, + }, + Action: func(cctx *cli.Context) error { + if !cctx.Args().Present() { + return xerrors.New("seed genesis new [genesis.json]") + } + + out := genesis.Template{ + Accounts: []genesis.Actor{}, + Miners: []genesis.Miner{}, + NetworkName: cctx.String("network-name"), + } + if out.NetworkName == "" { + out.NetworkName = "localnet-" + uuid.New().String() + } + + genb, err := json.MarshalIndent(&out, ""," ") + if err != nil { + return err + } + + genf, err := homedir.Expand(cctx.Args().First()) + if err != nil { + return err + } + + if err := ioutil.WriteFile(genf, genb, 0644); err != nil { + return err + } + + return nil + }, +} + +var genesisAddMinerCmd = &cli.Command{ + Name: "add-miner", + Description: "add genesis miner", + Flags: []cli.Flag{}, + Action: func(cctx *cli.Context) error { + if cctx.Args().Len() != 2 { + return xerrors.New("seed genesis add-miner [genesis.json] [preseal.json]") + } + + genf, err := homedir.Expand(cctx.Args().First()) + if err != nil { + return err + } + + var template genesis.Template + genb, err := ioutil.ReadFile(genf) + if err != nil { + return xerrors.Errorf("read genesis template: %w", err) + } + + if err := json.Unmarshal(genb, &template); err != nil { + return xerrors.Errorf("unmarshal genesis template: %w", err) + } + + minf, err := homedir.Expand(cctx.Args().Get(1)) + if err != nil { + return xerrors.Errorf("expand preseal file path: %w", err) + } + miners := map[string]genesis.Miner{} + minb, err := ioutil.ReadFile(minf) + if err != nil { + return xerrors.Errorf("read preseal file: %w", err) + } + if err := json.Unmarshal(minb, &miners); err != nil { + return xerrors.Errorf("unmarshal miner info: %w", err) + } + + for mn, miner := range miners { + log.Infof("Adding miner %s to genesis template", mn) + { + id := uint64(genesis2.MinerStart) + uint64(len(template.Miners)) + maddr, err := address.NewFromString(mn) + if err != nil { + return xerrors.Errorf("parsing miner address: %w", err) + } + mid, err := address.IDFromAddress(maddr) + if err != nil { + return xerrors.Errorf("getting miner id from address: %w", err) + } + if mid != id { + return xerrors.Errorf("tried to set miner t0%d as t0%d", mid, id) + } + } + + template.Miners = append(template.Miners, miner) + log.Infof("Giving %s some initial balance", miner.Owner) + template.Accounts = append(template.Accounts, genesis.Actor{ + Type: genesis.TAccount, + Balance: big.NewInt(100000000000000), + Meta: (&genesis.AccountMeta{Owner: miner.Owner}).ActorMeta(), + }) + } + + genb, err = json.MarshalIndent(&template, ""," ") + if err != nil { + return err + } + + if err := ioutil.WriteFile(genf, genb, 0644); err != nil { + return err + } + + return nil + }, +} diff --git a/cmd/lotus-seed/main.go b/cmd/lotus-seed/main.go index 41f72996b..ded25ebf9 100644 --- a/cmd/lotus-seed/main.go +++ b/cmd/lotus-seed/main.go @@ -4,15 +4,10 @@ import ( "encoding/hex" "encoding/json" "fmt" - "github.com/filecoin-project/specs-actors/actors/abi/big" "io/ioutil" "os" "path/filepath" - "github.com/filecoin-project/specs-actors/actors/abi" - - sectorbuilder "github.com/filecoin-project/go-sectorbuilder" - "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" badger "github.com/ipfs/go-ds-badger2" @@ -22,6 +17,9 @@ import ( "gopkg.in/urfave/cli.v2" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/abi/big" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" @@ -34,9 +32,9 @@ var log = logging.Logger("lotus-seed") func main() { logging.SetLogLevel("*", "INFO") - log.Info("Starting seed") - local := []*cli.Command{ + genesisCmd, + preSealCmd, aggregateManifestsCmd, aggregateSectorDirsCmd, @@ -58,7 +56,7 @@ func main() { if err := app.Run(os.Args); err != nil { log.Warn(err) - return + os.Exit(1) } } @@ -67,7 +65,7 @@ var preSealCmd = &cli.Command{ Flags: []cli.Flag{ &cli.StringFlag{ Name: "miner-addr", - Value: "t0101", + Value: "t01000", Usage: "specify the future address of your miner", }, &cli.Uint64Flag{ diff --git a/cmd/lotus-seed/seed/seed.go b/cmd/lotus-seed/seed/seed.go index b44f2ced3..247454ac4 100644 --- a/cmd/lotus-seed/seed/seed.go +++ b/cmd/lotus-seed/seed/seed.go @@ -109,7 +109,6 @@ func PreSeal(maddr address.Address, ssize abi.SectorSize, offset abi.SectorNumbe miner := &genesis.Miner{ Owner: minerAddr.Address, Worker: minerAddr.Address, - PeerId: "", MarketBalance: big.Zero(), PowerBalance: big.Zero(), SectorSize: ssize, @@ -137,6 +136,8 @@ func WriteGenesisMiner(maddr address.Address, sbroot string, gm *genesis.Miner, return err } + log.Infof("Writing preseal manifest to %s", filepath.Join(sbroot, "pre-seal-"+maddr.String()+".json")) + if err := ioutil.WriteFile(filepath.Join(sbroot, "pre-seal-"+maddr.String()+".json"), out, 0664); err != nil { return err } diff --git a/cmd/lotus/daemon.go b/cmd/lotus/daemon.go index 221b8cb92..a37843c6d 100644 --- a/cmd/lotus/daemon.go +++ b/cmd/lotus/daemon.go @@ -28,7 +28,7 @@ import ( ) const ( - makeGenFlag = "lotus-make-random-genesis" + makeGenFlag = "lotus-make-genesis" preTemplateFlag = "genesis-template" ) @@ -54,11 +54,6 @@ var DaemonCmd = &cli.Command{ Name: "genesis", Usage: "genesis file to use for first node run", }, - &cli.StringFlag{ - Name: "genesis-timestamp", - Hidden: true, - Usage: "set the timestamp for the genesis block that will be created", - }, &cli.BoolFlag{ Name: "bootstrap", Value: true, diff --git a/documentation/en/local-dev-net.md b/documentation/en/local-dev-net.md index ac9608822..0a1abc870 100644 --- a/documentation/en/local-dev-net.md +++ b/documentation/en/local-dev-net.md @@ -20,7 +20,10 @@ Pre-seal some sectors: Create the genesis block and start up the first node: ```sh -./lotus daemon --lotus-make-random-genesis=dev.gen --genesis-presealed-sectors=~/.genesis-sectors/pre-seal-t0101.json --bootstrap=false +./lotus-seed genesis new localnet.json +./lotus-seed genesis add-miner localnet.json ~/.genesis-sectors/pre-seal-t0101.json +./lotus daemon --lotus-make-genesis=dev.gen --genesis-template=localnet.json --bootstrap=false +# TODO Key import ``` Set up the genesis miner: diff --git a/genesis/types.go b/genesis/types.go index 8af1708d9..f699a28b0 100644 --- a/genesis/types.go +++ b/genesis/types.go @@ -26,7 +26,7 @@ type PreSeal struct { type Miner struct { Owner address.Address Worker address.Address - PeerId peer.ID + PeerId peer.ID `json:",omitempty"` MarketBalance abi.TokenAmount PowerBalance abi.TokenAmount @@ -64,5 +64,5 @@ type Template struct { Miners []Miner NetworkName string - Timestamp uint64 + Timestamp uint64 `json:",omitempty"` } diff --git a/go.mod b/go.mod index 34d857364..cf536ea9a 100644 --- a/go.mod +++ b/go.mod @@ -26,6 +26,7 @@ require ( github.com/filecoin-project/specs-actors v0.0.0-20200221171119-030c8eaad3ba github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 github.com/go-ole/go-ole v1.2.4 // indirect + github.com/google/uuid v1.1.1 github.com/gorilla/mux v1.7.3 github.com/gorilla/websocket v1.4.1 github.com/hashicorp/go-multierror v1.0.0 diff --git a/node/modules/testing/genesis.go b/node/modules/testing/genesis.go index 7ca5a51c3..5035baca3 100644 --- a/node/modules/testing/genesis.go +++ b/node/modules/testing/genesis.go @@ -65,7 +65,7 @@ func MakeGenesis(outFile, genesisTemplate string) func(bs dtypes.ChainBlockstore } var template genesis.Template - if err := json.Unmarshal(fdata, template); err != nil { + if err := json.Unmarshal(fdata, &template); err != nil { return nil, err }