diff --git a/build/bootstrap/butterflynet.pi b/build/bootstrap/butterflynet.pi index 65c194d19..dc49bdf0e 100644 --- a/build/bootstrap/butterflynet.pi +++ b/build/bootstrap/butterflynet.pi @@ -1,2 +1,2 @@ -/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWBQb5Eg2DRqL1Xrzm8S7AFnG2gkj1iKQKBBMEXJ7mXuWQ -/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWJ2qKfGJg2i4Pn7nVCQ13oktS4eZfXFJk9ZjQy9uxLdq9 +/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWQafkXgEWDgcVhZvF6KMhiC8ktdxjvmdQN8RarRXe9jCc +/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWE7UmZ4DLk9WBdEJUSwuSCPiSqjoCv3wPeoe8Tq3yMa77 diff --git a/build/genesis/butterflynet.car b/build/genesis/butterflynet.car index d5caa1131..1f5185c1a 100644 Binary files a/build/genesis/butterflynet.car and b/build/genesis/butterflynet.car differ diff --git a/chain/gen/genesis/genesis.go b/chain/gen/genesis/genesis.go index 3a4e317a5..d382e4d0d 100644 --- a/chain/gen/genesis/genesis.go +++ b/chain/gen/genesis/genesis.go @@ -7,6 +7,7 @@ import ( "fmt" "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/journal" "github.com/ipfs/go-cid" @@ -233,13 +234,36 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge } - vregroot, err := address.NewIDAddress(80) - if err != nil { - return nil, nil, err - } + switch template.VerifregRootKey.Type { + case genesis.TAccount: + var ainfo genesis.AccountMeta + if err := json.Unmarshal(template.VerifregRootKey.Meta, &ainfo); err != nil { + return nil, nil, xerrors.Errorf("unmarshaling account meta: %w", err) + } + st, err := cst.Put(ctx, &account0.State{Address: ainfo.Owner}) + if err != nil { + return nil, nil, err + } - if err = createMultisigAccount(ctx, bs, cst, state, vregroot, template.VerifregRootKey, keyIDs); err != nil { - return nil, nil, xerrors.Errorf("failed to set up verified registry signer: %w", err) + _, ok := keyIDs[ainfo.Owner] + if ok { + return nil, nil, fmt.Errorf("rootkey account has already been declared, cannot be assigned 80: %s", ainfo.Owner) + } + + err = state.SetActor(builtin.RootVerifierAddress, &types.Actor{ + Code: builtin0.AccountActorCodeID, + Balance: template.VerifregRootKey.Balance, + Head: st, + }) + if err != nil { + return nil, nil, xerrors.Errorf("setting verifreg rootkey account: %w", err) + } + case genesis.TMultisig: + if err = createMultisigAccount(ctx, bs, cst, state, builtin.RootVerifierAddress, template.VerifregRootKey, keyIDs); err != nil { + return nil, nil, xerrors.Errorf("failed to set up verified registry signer: %w", err) + } + default: + return nil, nil, xerrors.Errorf("unknown account type for verifreg rootkey: %w", err) } // Setup the first verifier as ID-address 81 @@ -300,8 +324,36 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge template.RemainderAccount.Balance = remainingFil - if err := createMultisigAccount(ctx, bs, cst, state, builtin.ReserveAddress, template.RemainderAccount, keyIDs); err != nil { - return nil, nil, xerrors.Errorf("failed to set up remainder account: %w", err) + switch template.RemainderAccount.Type { + case genesis.TAccount: + var ainfo genesis.AccountMeta + if err := json.Unmarshal(template.RemainderAccount.Meta, &ainfo); err != nil { + return nil, nil, xerrors.Errorf("unmarshaling account meta: %w", err) + } + st, err := cst.Put(ctx, &account0.State{Address: ainfo.Owner}) + if err != nil { + return nil, nil, err + } + + _, ok := keyIDs[ainfo.Owner] + if ok { + return nil, nil, fmt.Errorf("remainder account has already been declared, cannot be assigned 90: %s", ainfo.Owner) + } + + err = state.SetActor(builtin.ReserveAddress, &types.Actor{ + Code: builtin0.AccountActorCodeID, + Balance: template.RemainderAccount.Balance, + Head: st, + }) + if err != nil { + return nil, nil, xerrors.Errorf("setting remainder account: %w", err) + } + case genesis.TMultisig: + if err = createMultisigAccount(ctx, bs, cst, state, builtin.ReserveAddress, template.RemainderAccount, keyIDs); err != nil { + return nil, nil, xerrors.Errorf("failed to set up remainder: %w", err) + } + default: + return nil, nil, xerrors.Errorf("unknown account type for remainder: %w", err) } return state, keyIDs, nil diff --git a/cli/disputer.go b/cli/disputer.go index 7fb0bbb47..1a72173c3 100644 --- a/cli/disputer.go +++ b/cli/disputer.go @@ -270,7 +270,7 @@ var disputerStartCmd = &cli.Command{ if err != nil { disputeLog.Errorw("failed to dispute post message", "err", err.Error(), "miner", dpmsg.To) } else { - disputeLog.Infof("submited dispute", "mcid", m.Cid(), "miner", dpmsg.To) + disputeLog.Infow("submited dispute", "mcid", m.Cid(), "miner", dpmsg.To) } } diff --git a/cmd/lotus-seed/genesis.go b/cmd/lotus-seed/genesis.go index 67c5583ee..6f2c22147 100644 --- a/cmd/lotus-seed/genesis.go +++ b/cmd/lotus-seed/genesis.go @@ -37,6 +37,8 @@ var genesisCmd = &cli.Command{ genesisNewCmd, genesisAddMinerCmd, genesisAddMsigsCmd, + genesisSetVRKCmd, + genesisSetRemainderCmd, genesisCarCmd, }, } @@ -309,6 +311,200 @@ func parseMultisigCsv(csvf string) ([]GenAccountEntry, error) { return entries, nil } +var genesisSetVRKCmd = &cli.Command{ + Name: "set-vrk", + Usage: "Set the verified registry's root key", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "multisig", + Usage: "CSV file to parse the multisig that will be set as the root key", + }, + &cli.StringFlag{ + Name: "account", + Usage: "pubkey address that will be set as the root key (must NOT be declared anywhere else, since it must be given ID 80)", + }, + }, + Action: func(cctx *cli.Context) error { + if cctx.Args().Len() != 1 { + return fmt.Errorf("must specify template file") + } + + genf, err := homedir.Expand(cctx.Args().First()) + if err != nil { + return err + } + + csvf, err := homedir.Expand(cctx.Args().Get(1)) + if err != nil { + return err + } + + var template genesis.Template + b, err := ioutil.ReadFile(genf) + if err != nil { + return xerrors.Errorf("read genesis template: %w", err) + } + + if err := json.Unmarshal(b, &template); err != nil { + return xerrors.Errorf("unmarshal genesis template: %w", err) + } + + if cctx.IsSet("account") { + addr, err := address.NewFromString(cctx.String("account")) + if err != nil { + return err + } + + am := genesis.AccountMeta{Owner: addr} + + template.VerifregRootKey = genesis.Actor{ + Type: genesis.TAccount, + Balance: big.Zero(), + Meta: am.ActorMeta(), + } + } else if cctx.IsSet("multisig") { + + entries, err := parseMultisigCsv(csvf) + if err != nil { + return xerrors.Errorf("parsing multisig csv file: %w", err) + } + + if len(entries) == 0 { + return xerrors.Errorf("no msig entries in csv file: %w", err) + } + + e := entries[0] + if len(e.Addresses) != e.N { + return fmt.Errorf("entry had mismatch between 'N' and number of addresses") + } + + msig := &genesis.MultisigMeta{ + Signers: e.Addresses, + Threshold: e.M, + VestingDuration: monthsToBlocks(e.VestingMonths), + VestingStart: 0, + } + + act := genesis.Actor{ + Type: genesis.TMultisig, + Balance: abi.TokenAmount(e.Amount), + Meta: msig.ActorMeta(), + } + + template.VerifregRootKey = act + } else { + return xerrors.Errorf("must include either --account or --multisig flag") + } + + b, err = json.MarshalIndent(&template, "", " ") + if err != nil { + return err + } + + if err := ioutil.WriteFile(genf, b, 0644); err != nil { + return err + } + return nil + }, +} + +var genesisSetRemainderCmd = &cli.Command{ + Name: "set-remainder", + Usage: "Set the remainder actor", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "multisig", + Usage: "CSV file to parse the multisig that will be set as the remainder actor", + }, + &cli.StringFlag{ + Name: "account", + Usage: "pubkey address that will be set as the remainder key (must NOT be declared anywhere else, since it must be given ID 90)", + }, + }, + Action: func(cctx *cli.Context) error { + if cctx.Args().Len() != 1 { + return fmt.Errorf("must specify template file") + } + + genf, err := homedir.Expand(cctx.Args().First()) + if err != nil { + return err + } + + csvf, err := homedir.Expand(cctx.Args().Get(1)) + if err != nil { + return err + } + + var template genesis.Template + b, err := ioutil.ReadFile(genf) + if err != nil { + return xerrors.Errorf("read genesis template: %w", err) + } + + if err := json.Unmarshal(b, &template); err != nil { + return xerrors.Errorf("unmarshal genesis template: %w", err) + } + + if cctx.IsSet("account") { + addr, err := address.NewFromString(cctx.String("account")) + if err != nil { + return err + } + + am := genesis.AccountMeta{Owner: addr} + + template.RemainderAccount = genesis.Actor{ + Type: genesis.TAccount, + Balance: big.Zero(), + Meta: am.ActorMeta(), + } + } else if cctx.IsSet("multisig") { + + entries, err := parseMultisigCsv(csvf) + if err != nil { + return xerrors.Errorf("parsing multisig csv file: %w", err) + } + + if len(entries) == 0 { + return xerrors.Errorf("no msig entries in csv file: %w", err) + } + + e := entries[0] + if len(e.Addresses) != e.N { + return fmt.Errorf("entry had mismatch between 'N' and number of addresses") + } + + msig := &genesis.MultisigMeta{ + Signers: e.Addresses, + Threshold: e.M, + VestingDuration: monthsToBlocks(e.VestingMonths), + VestingStart: 0, + } + + act := genesis.Actor{ + Type: genesis.TMultisig, + Balance: abi.TokenAmount(e.Amount), + Meta: msig.ActorMeta(), + } + + template.RemainderAccount = act + } else { + return xerrors.Errorf("must include either --account or --multisig flag") + } + + b, err = json.MarshalIndent(&template, "", " ") + if err != nil { + return err + } + + if err := ioutil.WriteFile(genf, b, 0644); err != nil { + return err + } + return nil + }, +} + var genesisCarCmd = &cli.Command{ Name: "car", Description: "write genesis car file",