diff --git a/x/auth/ante/sigverify.go b/x/auth/ante/sigverify.go index af571b9d3d..8b94335124 100644 --- a/x/auth/ante/sigverify.go +++ b/x/auth/ante/sigverify.go @@ -56,6 +56,11 @@ func NewSetPubKeyDecorator(ak AccountKeeper) SetPubKeyDecorator { } func (spkd SetPubKeyDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { + if ctx.BlockHeight() == 0 { + // skip the signature verification on the genesis block + return next(ctx, tx, simulate) + } + sigTx, ok := tx.(authsigning.SigVerifiableTx) if !ok { return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "invalid tx type") @@ -234,6 +239,10 @@ func OnlyLegacyAminoSigners(sigData signing.SignatureData) bool { } func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { + if ctx.BlockHeight() == 0 { + // skip the signature verification on the genesis block + return next(ctx, tx, simulate) + } sigTx, ok := tx.(authsigning.SigVerifiableTx) if !ok { return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "invalid transaction type") diff --git a/x/auth/tx/decoder.go b/x/auth/tx/decoder.go index 2fef6312b9..7ef538fbb4 100644 --- a/x/auth/tx/decoder.go +++ b/x/auth/tx/decoder.go @@ -168,3 +168,8 @@ func varintMinLength(n uint64) int { return 10 } } + +// UnWrapTx returns the underlying Tx. +func UnWrapTx(tx sdk.Tx) *tx.Tx { + return tx.(*wrapper).tx +} diff --git a/x/genutil/client/cli/gentx.go b/x/genutil/client/cli/gentx.go index 82b4d04879..ab9e9ebb3f 100644 --- a/x/genutil/client/cli/gentx.go +++ b/x/genutil/client/cli/gentx.go @@ -16,12 +16,11 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" - "github.com/cosmos/cosmos-sdk/crypto/keyring" "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/version" - authclient "github.com/cosmos/cosmos-sdk/x/auth/client" + authTx "github.com/cosmos/cosmos-sdk/x/auth/tx" "github.com/cosmos/cosmos-sdk/x/genutil" "github.com/cosmos/cosmos-sdk/x/genutil/types" "github.com/cosmos/cosmos-sdk/x/staking/client/cli" @@ -33,7 +32,7 @@ func GenTxCmd(mbm module.BasicManager, txEncCfg client.TxEncodingConfig, genBalI fsCreateValidator, defaultsDesc := cli.CreateValidatorMsgFlagSet(ipDefault) cmd := &cobra.Command{ - Use: "gentx [key_name] [amount] [validator] [relayer] [challenger] [blskey] [blsProof]", + Use: "gentx [amount] [validator] [delegator] [relayer] [challenger] [blskey] [blsProof]", Short: "Generate a genesis tx carrying a self delegation", Args: cobra.ExactArgs(7), Long: fmt.Sprintf(`Generate a genesis transaction that creates a validator with a self-delegation, @@ -43,7 +42,8 @@ file. The following default parameters are included: %s Example: -$ %s gentx my-key-name 1000000stake \ +$ %s gentx 1000000stake \ + 0x6D967dc83b625603c963713eABd5B43A281E595e \ 0x6D967dc83b625603c963713eABd5B43A281E595e \ 0xcdd393723f1Af81faa3F3c87B51dAB72B6c68154 \ ac1e598ae0ccbeeaafa31bc6faefa85c2ae3138699cac79169cd718f1a38445201454ec092a86f200e08a15266bdc6e9 \ @@ -102,12 +102,6 @@ $ %s gentx my-key-name 1000000stake \ inBuf := bufio.NewReader(cmd.InOrStdin()) - name := args[0] - key, err := clientCtx.Keyring.Key(name) - if err != nil { - return errors.Wrapf(err, "failed to fetch '%s' from the keyring", name) - } - moniker := config.Moniker if m, _ := cmd.Flags().GetString(cli.FlagMoniker); m != "" { moniker = m @@ -119,30 +113,47 @@ $ %s gentx my-key-name 1000000stake \ return errors.Wrap(err, "error creating configuration to create validator msg") } - amount := args[1] + amount := args[0] coins, err := sdk.ParseCoinsNormalized(amount) if err != nil { return errors.Wrap(err, "failed to parse coins") } - addr, err := key.GetAddress() + validator, err := sdk.AccAddressFromHexUnsafe(args[1]) if err != nil { return err } - err = genutil.ValidateAccountInGenesis(genesisState, genBalIterator, addr, coins, cdc) + delegator, err := sdk.AccAddressFromHexUnsafe(args[2]) if err != nil { - return errors.Wrap(err, "failed to validate account in genesis") + return err } - - txFactory, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + relayer, err := sdk.AccAddressFromHexUnsafe(args[3]) if err != nil { return err } + challenger, err := sdk.AccAddressFromHexUnsafe(args[4]) + if err != nil { + return err + } + blsPk := args[5] + if len(blsPk) != 2*sdk.BLSPubKeyLength { + return fmt.Errorf("invalid bls pubkey") + } + blsProof := args[6] + if len(blsProof) != 2*sdk.BLSSignatureLength { + return fmt.Errorf("invalid bls proof, len: %d", len(blsProof)) + } - pub, err := key.GetAddress() + err = genutil.ValidateAccountInGenesis(genesisState, genBalIterator, delegator, coins, cdc) + if err != nil { + return errors.Wrap(err, "failed to validate account in genesis") + } + + txFactory, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) if err != nil { return err } - clientCtx = clientCtx.WithInput(inBuf).WithFromAddress(pub) + + clientCtx = clientCtx.WithInput(inBuf).WithFromAddress(delegator) // The following line comes from a discrepancy between the `gentx` // and `create-validator` commands: @@ -156,30 +167,8 @@ $ %s gentx my-key-name 1000000stake \ // config file instead of so many flags. // ref: https://github.com/cosmos/cosmos-sdk/issues/8177 createValCfg.Amount = amount - - validator, err := sdk.AccAddressFromHexUnsafe(args[2]) - if err != nil { - return err - } - relayer, err := sdk.AccAddressFromHexUnsafe(args[3]) - if err != nil { - return err - } - challenger, err := sdk.AccAddressFromHexUnsafe(args[4]) - if err != nil { - return err - } - blsPk := args[5] - if len(blsPk) != 2*sdk.BLSPubKeyLength { - return fmt.Errorf("invalid bls pubkey") - } - blsProof := args[6] - if len(blsProof) != 2*sdk.BLSSignatureLength { - return fmt.Errorf("invalid bls proof, len: %d", len(blsProof)) - } - createValCfg.Validator = validator - createValCfg.Delegator = addr + createValCfg.Delegator = delegator createValCfg.Relayer = relayer createValCfg.Challenger = challenger createValCfg.BlsKey = blsPk @@ -191,11 +180,6 @@ $ %s gentx my-key-name 1000000stake \ return errors.Wrap(err, "failed to build create-validator message") } - if key.GetType() == keyring.TypeOffline || key.GetType() == keyring.TypeMulti { - cmd.PrintErrln("Offline key passed in. Use `tx sign` command to sign.") - return txBldr.PrintUnsignedTx(clientCtx, msg) - } - // write the unsigned transaction to the buffer w := bytes.NewBuffer([]byte{}) clientCtx = clientCtx.WithOutput(w) @@ -214,16 +198,11 @@ $ %s gentx my-key-name 1000000stake \ return errors.Wrap(err, "failed to read unsigned gen tx file") } - // sign the transaction and write it to the output file - txBuilder, err := clientCtx.TxConfig.WrapTxBuilder(stdTx) - if err != nil { - return fmt.Errorf("error creating tx builder: %w", err) - } - - err = authclient.SignTx(txFactory, clientCtx, name, txBuilder, true, true) - if err != nil { - return errors.Wrap(err, "failed to sign std tx") - } + // sig verification will skip in the genesis block, + // but still need a data to be set in Tx to skip the basic validation. + underlyingTx := authTx.UnWrapTx(stdTx) + underlyingTx.Signatures = [][]byte{[]byte(fmt.Sprintf("genesis create validator [%s]", createValCfg.Moniker))} + stdTx = underlyingTx outputDocument, _ := cmd.Flags().GetString(flags.FlagOutputDocument) if outputDocument == "" {