Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: skip sig verification on genesis block #273

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ include contrib/devtools/Makefile
###############################################################################

BUILD_TARGETS := build install

.PHONY: build build-linux-amd64 build-linux-arm64
build: BUILD_ARGS=-o $(BUILDDIR)/

build-linux-amd64:
Expand Down
8 changes: 4 additions & 4 deletions tests/e2e/genutil/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ func (s *E2ETestSuite) TestGenTxCmd() {
args: []string{
fmt.Sprintf("--%s=%s", flags.FlagChainID, s.network.Config.ChainID),
fmt.Sprintf("--%s=1", stakingcli.FlagCommissionRate),
val.Moniker,
amount.String(),
val.Address.String(),
val.Address.String(),
val.Address.String(),
val.Address.String(),
blsPk,
},
expError: true,
Expand All @@ -80,11 +80,11 @@ func (s *E2ETestSuite) TestGenTxCmd() {
name: "valid gentx",
args: []string{
fmt.Sprintf("--%s=%s", flags.FlagChainID, s.network.Config.ChainID),
val.Moniker,
amount.String(),
val.Address.String(),
val.Address.String(),
val.Address.String(),
val.Address.String(),
blsPk,
blsProof,
},
Expand All @@ -95,11 +95,11 @@ func (s *E2ETestSuite) TestGenTxCmd() {
args: []string{
fmt.Sprintf("--%s=%s", flags.FlagChainID, s.network.Config.ChainID),
fmt.Sprintf("--%s={\"key\":\"BOIkjkFruMpfOFC9oNPhiJGfmY2pHF/gwHdLDLnrnS0=\"}", stakingcli.FlagPubKey),
val.Moniker,
amount.String(),
val.Address.String(),
val.Address.String(),
val.Address.String(),
val.Address.String(),
blsPk,
blsProof,
},
Expand All @@ -110,11 +110,11 @@ func (s *E2ETestSuite) TestGenTxCmd() {
args: []string{
fmt.Sprintf("--%s=%s", flags.FlagChainID, s.network.Config.ChainID),
fmt.Sprintf("--%s={\"@type\":\"/cosmos.crypto.ed25519.PubKey\",\"key\":\"BOIkjkFruMpfOFC9oNPhiJGfmY2pHF/gwHdLDLnrnS0=\"}", stakingcli.FlagPubKey),
val.Moniker,
amount.String(),
val.Address.String(),
val.Address.String(),
val.Address.String(),
val.Address.String(),
blsPk,
blsProof,
},
Expand Down
9 changes: 5 additions & 4 deletions x/auth/ante/ante_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,8 @@ func TestAnteHandlerAccountNumbersAtBlockHeightZero(t *testing.T) {
}
},
false,
false,
sdkerrors.ErrUnauthorized,
true,
nil,
},
{
"new tx with another signer and incorrect account numbers",
Expand All @@ -371,8 +371,8 @@ func TestAnteHandlerAccountNumbersAtBlockHeightZero(t *testing.T) {
}
},
false,
false,
sdkerrors.ErrUnauthorized,
true,
nil,
},
{
"new tx with another signer and correct account numbers",
Expand All @@ -398,6 +398,7 @@ func TestAnteHandlerAccountNumbersAtBlockHeightZero(t *testing.T) {

for _, tc := range testCases {
t.Run(fmt.Sprintf("Case %s", tc.desc), func(t *testing.T) {
t.Log(tc.desc)
suite := SetupTestSuite(t, false)
suite.ctx = suite.ctx.WithBlockHeight(0)
suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder()
Expand Down
13 changes: 13 additions & 0 deletions x/auth/ante/sigverify.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -148,6 +153,10 @@ func NewSigGasConsumeDecorator(ak AccountKeeper, sigGasConsumer SignatureVerific
}

func (sgcd SigGasConsumeDecorator) 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")
Expand Down Expand Up @@ -234,6 +243,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")
Expand Down
5 changes: 5 additions & 0 deletions x/auth/tx/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
91 changes: 35 additions & 56 deletions x/genutil/client/cli/gentx.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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,
Expand All @@ -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 \
Expand Down Expand Up @@ -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
Expand All @@ -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:
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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 == "" {
Expand Down
Loading