Skip to content

Commit

Permalink
feat: skip sig verification on genesis block (#273)
Browse files Browse the repository at this point in the history
* feat: skip sig verification on genesis block

* fix: skip SigGasConsume on genesis block

* chore: fix test case
  • Loading branch information
j75689 committed Aug 16, 2023
1 parent db13145 commit 2e24113
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 65 deletions.
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

0 comments on commit 2e24113

Please sign in to comment.