Update keybase back to cosmos-sdk with support (#147)

* Migrate keybase back to Cosmos-sdk using temporary fork

* Cleaned up other affected code

* Change to updated tendermint

* fmt

* Change auth codec update

* clean up codec registration to respective packages

* Fix import fmt

* Remove no longer necessary replace

* Fix function comment
This commit is contained in:
Austin Abell
2019-11-13 12:00:21 -05:00
committed by GitHub
parent 327abc4edf
commit 9311f9efd0
30 changed files with 137 additions and 2542 deletions
+68
View File
@@ -0,0 +1,68 @@
package main
import (
"github.com/cosmos/cosmos-sdk/client/flags"
clientkeys "github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/crypto/keys"
emintCrypto "github.com/cosmos/ethermint/crypto"
tmcrypto "github.com/tendermint/tendermint/crypto"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
const (
flagDryRun = "dry-run"
)
// keyCommands registers a sub-tree of commands to interact with
// local private key storage.
func keyCommands() *cobra.Command {
cmd := &cobra.Command{
Use: "keys",
Short: "Add or view local private keys",
Long: `Keys allows you to manage your local keystore for tendermint.
These keys may be in any format supported by go-crypto and can be
used by light-clients, full nodes, or any other application that
needs to sign with a private key.`,
}
addCmd := clientkeys.AddKeyCommand()
addCmd.RunE = runAddCmd
cmd.AddCommand(
clientkeys.MnemonicKeyCommand(),
addCmd,
clientkeys.ExportKeyCommand(),
clientkeys.ImportKeyCommand(),
clientkeys.ListKeysCmd(),
clientkeys.ShowKeysCmd(),
flags.LineBreak,
clientkeys.DeleteKeyCommand(),
clientkeys.UpdateKeyCommand(),
clientkeys.ParseKeyStringCommand(),
clientkeys.MigrateCommand(),
)
return cmd
}
func getKeybase(dryrun bool) (keys.Keybase, error) {
if dryrun {
return keys.NewInMemory(keys.WithKeygenFunc(ethermintKeygenFunc)), nil
}
return clientkeys.NewKeyBaseFromHomeFlag(keys.WithKeygenFunc(ethermintKeygenFunc))
}
func runAddCmd(cmd *cobra.Command, args []string) error {
kb, err := getKeybase(viper.GetBool(flagDryRun))
if err != nil {
return err
}
return clientkeys.RunAddCmd(cmd, args, kb)
}
func ethermintKeygenFunc(bz [32]byte) tmcrypto.PrivKey {
return emintCrypto.PrivKeySecp256k1(bz[:])
}
+7 -5
View File
@@ -4,19 +4,20 @@ import (
"os"
"path"
emintapp "github.com/cosmos/ethermint/app"
"github.com/cosmos/ethermint/rpc"
"github.com/tendermint/go-amino"
"github.com/cosmos/cosmos-sdk/client"
clientkeys "github.com/cosmos/cosmos-sdk/client/keys"
sdkrpc "github.com/cosmos/cosmos-sdk/client/rpc"
cryptokeys "github.com/cosmos/cosmos-sdk/crypto/keys"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
emintkeys "github.com/cosmos/ethermint/keys"
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli"
emintapp "github.com/cosmos/ethermint/app"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
@@ -27,7 +28,8 @@ func main() {
cdc := emintapp.MakeCodec()
authtypes.ModuleCdc = cdc
cryptokeys.CryptoCdc = cdc
clientkeys.KeysCdc = cdc
// Read in the configuration file for the sdk
config := sdk.GetConfig()
@@ -56,7 +58,7 @@ func main() {
// TODO: Set up rest routes (if included, different from web3 api)
rpc.Web3RpcCmd(cdc),
client.LineBreak,
emintkeys.Commands(),
keyCommands(),
client.LineBreak,
)
+1 -1
View File
@@ -9,6 +9,7 @@ import (
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/server"
sdk "github.com/cosmos/cosmos-sdk/types"
@@ -16,7 +17,6 @@ import (
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
authvesting "github.com/cosmos/cosmos-sdk/x/auth/vesting"
"github.com/cosmos/cosmos-sdk/x/genutil"
"github.com/cosmos/ethermint/keys"
ethermint "github.com/cosmos/ethermint/types"
)
-302
View File
@@ -1,302 +0,0 @@
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"github.com/pkg/errors"
"github.com/spf13/cobra"
flag "github.com/spf13/pflag"
"github.com/spf13/viper"
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/common"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/codec"
kbkeys "github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/cosmos/cosmos-sdk/server"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/auth/client/utils"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/genutil"
"github.com/cosmos/cosmos-sdk/x/genutil/types"
"github.com/cosmos/ethermint/keys"
clientutils "github.com/cosmos/ethermint/x/evm/client/utils"
)
// StakingMsgBuildingHelpers helpers for message building gen-tx command
type StakingMsgBuildingHelpers interface {
CreateValidatorMsgHelpers(ipDefault string) (fs *flag.FlagSet, nodeIDFlag, pubkeyFlag, amountFlag, defaultsDesc string)
PrepareFlagsForTxCreateValidator(config *cfg.Config, nodeID, chainID string, valPubKey crypto.PubKey)
BuildCreateValidatorMsg(cliCtx context.CLIContext, txBldr auth.TxBuilder) (auth.TxBuilder, sdk.Msg, error)
}
// GenTxCmd builds the application's gentx command.
// nolint: errcheck
func GenTxCmd(ctx *server.Context, cdc *codec.Codec, mbm module.BasicManager, smbh StakingMsgBuildingHelpers,
genAccIterator types.GenesisAccountsIterator, defaultNodeHome, defaultCLIHome string) *cobra.Command {
ipDefault, _ := server.ExternalIP()
fsCreateValidator, flagNodeID, flagPubKey, flagAmount, defaultsDesc := smbh.CreateValidatorMsgHelpers(ipDefault)
cmd := &cobra.Command{
Use: "gentx",
Short: "Generate a genesis tx carrying a self delegation",
Args: cobra.NoArgs,
Long: fmt.Sprintf(`This command is an alias of the 'tx create-validator' command'.
It creates a genesis transaction to create a validator.
The following default parameters are included:
%s`, defaultsDesc),
RunE: func(cmd *cobra.Command, args []string) error {
config := ctx.Config
config.SetRoot(viper.GetString(client.FlagHome))
nodeID, valPubKey, err := genutil.InitializeNodeValidatorFiles(ctx.Config)
if err != nil {
return errors.Wrap(err, "failed to initialize node validator files")
}
// Read --nodeID, if empty take it from priv_validator.json
if nodeIDString := viper.GetString(flagNodeID); nodeIDString != "" {
nodeID = nodeIDString
}
// Read --pubkey, if empty take it from priv_validator.json
if valPubKeyString := viper.GetString(flagPubKey); valPubKeyString != "" {
valPubKey, err = sdk.GetConsPubKeyBech32(valPubKeyString)
if err != nil {
return errors.Wrap(err, "failed to get consensus node public key")
}
}
genDoc, err := tmtypes.GenesisDocFromFile(config.GenesisFile())
if err != nil {
return errors.Wrapf(err, "failed to read genesis doc file %s", config.GenesisFile())
}
var genesisState map[string]json.RawMessage
if err = cdc.UnmarshalJSON(genDoc.AppState, &genesisState); err != nil {
return errors.Wrap(err, "failed to unmarshal genesis state")
}
if err = mbm.ValidateGenesis(genesisState); err != nil {
return errors.Wrap(err, "failed to validate genesis state")
}
// * Necessary to change keybase here
kb, err := keys.NewKeyBaseFromDir(viper.GetString(flagClientHome))
if err != nil {
return errors.Wrap(err, "failed to initialize keybase")
}
name := viper.GetString(client.FlagName)
key, err := kb.Get(name)
if err != nil {
return errors.Wrap(err, "failed to read from keybase")
}
// Set flags for creating gentx
viper.Set(client.FlagHome, viper.GetString(flagClientHome))
smbh.PrepareFlagsForTxCreateValidator(config, nodeID, genDoc.ChainID, valPubKey)
// Fetch the amount of coins staked
amount := viper.GetString(flagAmount)
coins, err := sdk.ParseCoins(amount)
if err != nil {
return errors.Wrap(err, "failed to parse coins")
}
err = genutil.ValidateAccountInGenesis(genesisState, genAccIterator, key.GetAddress(), coins, cdc)
if err != nil {
return errors.Wrap(err, "failed to validate account in genesis")
}
txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)).WithKeybase(kb)
cliCtx := clientutils.NewETHCLIContext().WithCodec(cdc)
// Set the generate-only flag here after the CLI context has
// been created. This allows the from name/key to be correctly populated.
//
// TODO: Consider removing the manual setting of generate-only in
// favor of a 'gentx' flag in the create-validator command.
viper.Set(client.FlagGenerateOnly, true)
// create a 'create-validator' message
txBldr, msg, err := smbh.BuildCreateValidatorMsg(cliCtx, txBldr)
if err != nil {
return errors.Wrap(err, "failed to build create-validator message")
}
info, err := kb.Get(name)
if err != nil {
return errors.Wrap(err, "failed to read from tx builder keybase")
}
if info.GetType() == kbkeys.TypeOffline || info.GetType() == kbkeys.TypeMulti {
fmt.Println("Offline key passed in. Use `tx sign` command to sign:")
return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg})
}
// write the unsigned transaction to the buffer
w := bytes.NewBuffer([]byte{})
cliCtx = cliCtx.WithOutput(w)
if err = utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg}); err != nil {
return errors.Wrap(err, "failed to print unsigned std tx")
}
// read the transaction
stdTx, err := readUnsignedGenTxFile(cdc, w)
if err != nil {
return errors.Wrap(err, "failed to read unsigned gen tx file")
}
// * Function needed to be overriden for signStdTx function using default keybase
// sign the transaction and write it to the output file
signedTx, err := signStdTx(txBldr, cliCtx, name, stdTx, false, true)
if err != nil {
return errors.Wrap(err, "failed to sign std tx")
}
// Fetch output file name
outputDocument := viper.GetString(client.FlagOutputDocument)
if outputDocument == "" {
outputDocument, err = makeOutputFilepath(config.RootDir, nodeID)
if err != nil {
return errors.Wrap(err, "failed to create output file path")
}
}
if err := writeSignedGenTx(cdc, outputDocument, signedTx); err != nil {
return errors.Wrap(err, "failed to write signed gen tx")
}
fmt.Fprintf(os.Stderr, "Genesis transaction written to %q\n", outputDocument)
return nil
},
}
cmd.Flags().String(client.FlagHome, defaultNodeHome, "node's home directory")
cmd.Flags().String(flagClientHome, defaultCLIHome, "client's home directory")
cmd.Flags().String(client.FlagName, "", "name of private key with which to sign the gentx")
cmd.Flags().String(client.FlagOutputDocument, "",
"write the genesis transaction JSON document to the given file instead of the default location")
cmd.Flags().AddFlagSet(fsCreateValidator)
if err := cmd.MarkFlagRequired(client.FlagName); err != nil {
panic(err)
}
return cmd
}
func makeOutputFilepath(rootDir, nodeID string) (string, error) {
writePath := filepath.Join(rootDir, "config", "gentx")
if err := common.EnsureDir(writePath, 0700); err != nil {
return "", err
}
return filepath.Join(writePath, fmt.Sprintf("gentx-%v.json", nodeID)), nil
}
func readUnsignedGenTxFile(cdc *codec.Codec, r io.Reader) (auth.StdTx, error) {
var stdTx auth.StdTx
bytes, err := ioutil.ReadAll(r)
if err != nil {
return stdTx, err
}
err = cdc.UnmarshalJSON(bytes, &stdTx)
return stdTx, err
}
func writeSignedGenTx(cdc *codec.Codec, outputDocument string, tx auth.StdTx) error {
outputFile, err := os.OpenFile(outputDocument, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0600)
if err != nil {
return err
}
defer func() {
if err := outputFile.Close(); err != nil {
panic(err)
}
}()
json, err := cdc.MarshalJSON(tx)
if err != nil {
return err
}
_, err = fmt.Fprintf(outputFile, "%s\n", json)
return err
}
// SignStdTx appends a signature to a StdTx and returns a copy of it. If appendSig
// is false, it replaces the signatures already attached with the new signature.
// Don't perform online validation or lookups if offline is true.
func signStdTx(
txBldr authtypes.TxBuilder, cliCtx context.CLIContext, name string,
stdTx authtypes.StdTx, appendSig bool, offline bool,
) (authtypes.StdTx, error) {
var signedStdTx authtypes.StdTx
info, err := txBldr.Keybase().Get(name)
if err != nil {
return signedStdTx, err
}
addr := info.GetPubKey().Address()
// check whether the address is a signer
if !isTxSigner(sdk.AccAddress(addr), stdTx.GetSigners()) {
return signedStdTx, fmt.Errorf("%s: %s", errors.New("tx intended signer does not match the given signer"), name)
}
if !offline {
txBldr, err = populateAccountFromState(txBldr, cliCtx, sdk.AccAddress(addr))
if err != nil {
return signedStdTx, err
}
}
// * Switched to use Ethermint keybase
passphrase, err := keys.GetPassphrase(name)
if err != nil {
return signedStdTx, err
}
return txBldr.SignStdTx(name, passphrase, stdTx, appendSig)
}
func populateAccountFromState(
txBldr authtypes.TxBuilder, cliCtx context.CLIContext, addr sdk.AccAddress,
) (authtypes.TxBuilder, error) {
num, seq, err := authtypes.NewAccountRetriever(cliCtx).GetAccountNumberSequence(addr)
if err != nil {
return txBldr, err
}
return txBldr.WithAccountNumber(num).WithSequence(seq), nil
}
func isTxSigner(user sdk.AccAddress, signers []sdk.AccAddress) bool {
for _, s := range signers {
if bytes.Equal(user.Bytes(), s.Bytes()) {
return true
}
}
return false
}
+6 -4
View File
@@ -8,12 +8,13 @@ import (
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
clientkeys "github.com/cosmos/cosmos-sdk/client/keys"
cryptokeys "github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
genutil "github.com/cosmos/cosmos-sdk/x/genutil"
"github.com/cosmos/cosmos-sdk/x/genutil"
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
"github.com/cosmos/cosmos-sdk/x/staking"
@@ -36,9 +37,10 @@ func main() {
cdc := emintapp.MakeCodec()
cryptokeys.CryptoCdc = cdc
genutil.ModuleCdc = cdc
genutiltypes.ModuleCdc = cdc
authtypes.ModuleCdc = cdc
clientkeys.KeysCdc = cdc
config := sdk.GetConfig()
config.SetBech32PrefixForAccount(sdk.Bech32PrefixAccAddr, sdk.Bech32PrefixAccPub)
@@ -57,7 +59,7 @@ func main() {
rootCmd.AddCommand(
withChainIDValidation(genutilcli.InitCmd(ctx, cdc, emintapp.ModuleBasics, emintapp.DefaultNodeHome)),
genutilcli.CollectGenTxsCmd(ctx, cdc, auth.GenesisAccountIterator{}, emintapp.DefaultNodeHome),
GenTxCmd(
genutilcli.GenTxCmd(
ctx, cdc, emintapp.ModuleBasics, staking.AppModuleBasic{}, auth.GenesisAccountIterator{}, emintapp.DefaultNodeHome, emintapp.DefaultCLIHome,
),
genutilcli.ValidateGenesisCmd(ctx, cdc, emintapp.ModuleBasics),