5733c71c50
We were ignoring quite a few error cases, and had one case where we weren't actually updating state where we wanted to. Unfortunately, if the linter doesn't pass, nobody has any reason to actually check lint failures in CI. There are three remaining XXXs marked in the code for lint.
202 lines
4.3 KiB
Go
202 lines
4.3 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
|
|
"github.com/docker/go-units"
|
|
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
|
|
|
logging "github.com/ipfs/go-log/v2"
|
|
"github.com/mitchellh/go-homedir"
|
|
"github.com/urfave/cli/v2"
|
|
|
|
"github.com/filecoin-project/go-address"
|
|
"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"
|
|
"github.com/filecoin-project/lotus/cmd/lotus-seed/seed"
|
|
"github.com/filecoin-project/lotus/genesis"
|
|
)
|
|
|
|
var log = logging.Logger("lotus-seed")
|
|
|
|
func main() {
|
|
logging.SetLogLevel("*", "INFO")
|
|
|
|
local := []*cli.Command{
|
|
genesisCmd,
|
|
|
|
preSealCmd,
|
|
aggregateManifestsCmd,
|
|
}
|
|
|
|
app := &cli.App{
|
|
Name: "lotus-seed",
|
|
Usage: "Seal sectors for genesis miner",
|
|
Version: build.UserVersion(),
|
|
Flags: []cli.Flag{
|
|
&cli.StringFlag{
|
|
Name: "sector-dir",
|
|
Value: "~/.genesis-sectors",
|
|
},
|
|
},
|
|
|
|
Commands: local,
|
|
}
|
|
|
|
if err := app.Run(os.Args); err != nil {
|
|
log.Warn(err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
var preSealCmd = &cli.Command{
|
|
Name: "pre-seal",
|
|
Flags: []cli.Flag{
|
|
&cli.StringFlag{
|
|
Name: "miner-addr",
|
|
Value: "t01000",
|
|
Usage: "specify the future address of your miner",
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "sector-size",
|
|
Value: "2KiB",
|
|
Usage: "specify size of sectors to pre-seal",
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "ticket-preimage",
|
|
Value: "lotus is fire",
|
|
Usage: "set the ticket preimage for sealing randomness",
|
|
},
|
|
&cli.IntFlag{
|
|
Name: "num-sectors",
|
|
Value: 1,
|
|
Usage: "select number of sectors to pre-seal",
|
|
},
|
|
&cli.Uint64Flag{
|
|
Name: "sector-offset",
|
|
Value: 0,
|
|
Usage: "how many sector ids to skip when starting to seal",
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "key",
|
|
Value: "",
|
|
Usage: "(optional) Key to use for signing / owner/worker addresses",
|
|
},
|
|
&cli.BoolFlag{
|
|
Name: "fake-sectors",
|
|
Value: false,
|
|
},
|
|
},
|
|
Action: func(c *cli.Context) error {
|
|
sdir := c.String("sector-dir")
|
|
sbroot, err := homedir.Expand(sdir)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
maddr, err := address.NewFromString(c.String("miner-addr"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var k *types.KeyInfo
|
|
if c.String("key") != "" {
|
|
k = new(types.KeyInfo)
|
|
kh, err := ioutil.ReadFile(c.String("key"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
kb, err := hex.DecodeString(string(kh))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := json.Unmarshal(kb, k); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
sectorSizeInt, err := units.RAMInBytes(c.String("sector-size"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
sectorSize := abi.SectorSize(sectorSizeInt)
|
|
|
|
rp, err := ffiwrapper.SealProofTypeFromSectorSize(sectorSize)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
gm, key, err := seed.PreSeal(maddr, rp, abi.SectorNumber(c.Uint64("sector-offset")), c.Int("num-sectors"), sbroot, []byte(c.String("ticket-preimage")), k, c.Bool("fake-sectors"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return seed.WriteGenesisMiner(maddr, sbroot, gm, key)
|
|
},
|
|
}
|
|
|
|
var aggregateManifestsCmd = &cli.Command{
|
|
Name: "aggregate-manifests",
|
|
Usage: "aggregate a set of preseal manifests into a single file",
|
|
Action: func(cctx *cli.Context) error {
|
|
var inputs []map[string]genesis.Miner
|
|
for _, infi := range cctx.Args().Slice() {
|
|
fi, err := os.Open(infi)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var val map[string]genesis.Miner
|
|
if err := json.NewDecoder(fi).Decode(&val); err != nil {
|
|
return err
|
|
}
|
|
|
|
inputs = append(inputs, val)
|
|
if err := fi.Close(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
output := make(map[string]genesis.Miner)
|
|
for _, in := range inputs {
|
|
for maddr, val := range in {
|
|
if gm, ok := output[maddr]; ok {
|
|
output[maddr] = mergeGenMiners(gm, val)
|
|
} else {
|
|
output[maddr] = val
|
|
}
|
|
}
|
|
}
|
|
|
|
blob, err := json.MarshalIndent(output, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Println(string(blob))
|
|
return nil
|
|
},
|
|
}
|
|
|
|
func mergeGenMiners(a, b genesis.Miner) genesis.Miner {
|
|
if a.SectorSize != b.SectorSize {
|
|
panic("sector sizes mismatch")
|
|
}
|
|
|
|
return genesis.Miner{
|
|
Owner: a.Owner,
|
|
Worker: a.Worker,
|
|
PeerId: a.PeerId,
|
|
MarketBalance: big.Zero(),
|
|
PowerBalance: big.Zero(),
|
|
SectorSize: a.SectorSize,
|
|
Sectors: append(a.Sectors, b.Sectors...),
|
|
}
|
|
}
|