From 0f65b88b33ed669aa47bbb7183a62eb8e4068803 Mon Sep 17 00:00:00 2001 From: zale144 Date: Wed, 9 Oct 2024 14:34:47 +0200 Subject: [PATCH] fix(ethsecp256k1): register missing codecs for supporting ethsecp256k1 algo (#138) --- README.md | 2 +- app/ante.go | 136 +++++++++++++++++++++++++++++++++++-------- app/app.go | 16 ++--- app/encoding.go | 21 ++++++- go.mod | 3 + rollappd/cmd/root.go | 18 +++--- 6 files changed, 154 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 5a0e926..771fbca 100644 --- a/README.md +++ b/README.md @@ -174,7 +174,7 @@ Modify `dymint.toml` in the chain directory (`~/.rollapp/config`) ```shell dasel put -f "${ROLLAPP_HOME_DIR}"/config/dymint.toml "settlement_layer" -v "dymension" -dasel put -f "${ROLLAPP_HOME_DIR}"/config/dymint.toml "node_address" -v "$HUB_RPC_URL" +dasel put -f "${ROLLAPP_HOME_DIR}"/config/dymint.toml "settlement_node_address" -v "$HUB_RPC_URL" dasel put -f "${ROLLAPP_HOME_DIR}"/config/dymint.toml "rollapp_id" -v "$ROLLAPP_CHAIN_ID" dasel put -f "${ROLLAPP_HOME_DIR}"/config/dymint.toml "max_idle_time" -v "2s" dasel put -f "${ROLLAPP_HOME_DIR}"/config/dymint.toml "max_proof_time" -v "1s" diff --git a/app/ante.go b/app/ante.go index 4ca1dcb..fb99f0f 100644 --- a/app/ante.go +++ b/app/ante.go @@ -1,19 +1,26 @@ package app import ( + "fmt" + "runtime/debug" + errorsmod "cosmossdk.io/errors" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/ante" conntypes "github.com/cosmos/ibc-go/v6/modules/core/03-connection/types" - ibcante "github.com/cosmos/ibc-go/v6/modules/core/ante" ibckeeper "github.com/cosmos/ibc-go/v6/modules/core/keeper" + cosmosante "github.com/evmos/evmos/v12/app/ante/cosmos" + evmostypes "github.com/evmos/evmos/v12/types" + evmtypes "github.com/evmos/evmos/v12/x/evm/types" + tmlog "github.com/tendermint/tendermint/libs/log" + "github.com/dymensionxyz/dymension-rdk/x/gasless" gaslesskeeper "github.com/dymensionxyz/dymension-rdk/x/gasless/keeper" - cosmosante "github.com/evmos/evmos/v12/app/ante/cosmos" ) // HandlerOptions are the options required for constructing a default SDK AnteHandler. @@ -26,13 +33,74 @@ type HandlerOptions struct { GaslessKeeper gaslesskeeper.Keeper } -func GetAnteDecorators(options HandlerOptions) []sdk.AnteDecorator { +// NewAnteHandler returns an AnteHandler that checks and increments sequence +// numbers, checks signatures & account numbers, and deducts fees from the first +// signer. +func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { + if err := options.validate(); err != nil { + return nil, fmt.Errorf("options validate: %w", err) + } + + return func( + ctx sdk.Context, tx sdk.Tx, sim bool, + ) (newCtx sdk.Context, err error) { + var anteHandler sdk.AnteHandler + + defer Recover(ctx.Logger(), &err) + + txWithExtensions, ok := tx.(ante.HasExtensionOptionsTx) + if ok { + opts := txWithExtensions.GetExtensionOptions() + if len(opts) > 0 { + switch typeURL := opts[0].GetTypeUrl(); typeURL { + case "/ethermint.types.v1.ExtensionOptionsWeb3Tx": + // Deprecated: Handle as normal Cosmos SDK tx, except signature is checked for Legacy EIP712 representation + options.ExtensionOptionChecker = func(c *codectypes.Any) bool { + _, ok := c.GetCachedValue().(*evmostypes.ExtensionOptionsWeb3Tx) + return ok + } + anteHandler = cosmosHandler( + options, + // nolint:staticcheck + cosmosante.NewLegacyEip712SigVerificationDecorator(options.AccountKeeper.(evmtypes.AccountKeeper), options.SignModeHandler), // Use old signature verification: uses EIP instead of the cosmos signature validator + ) + default: + return ctx, errorsmod.Wrapf( + sdkerrors.ErrUnknownExtensionOptions, + "rejecting tx with unsupported extension option: %s", typeURL, + ) + } + + return anteHandler(ctx, tx, sim) + } + } + + // handle as totally normal Cosmos SDK tx + switch tx.(type) { + case sdk.Tx: + // we reject any extension + anteHandler = cosmosHandler( + options, + ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler), // Use modern signature verification + ) + default: + return ctx, errorsmod.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", tx) + } + + return anteHandler(ctx, tx, sim) + }, nil +} + +func cosmosHandler(options HandlerOptions, sigChecker sdk.AnteDecorator) sdk.AnteHandler { sigGasConsumer := options.SigGasConsumer if sigGasConsumer == nil { sigGasConsumer = ante.DefaultSigVerificationGasConsumer } - - anteDecorators := []sdk.AnteDecorator{ + // only override the modern sig checker, and preserve the legacy one + if _, ok := sigChecker.(ante.SigVerificationDecorator); ok { + sigChecker = NewSigCheckDecorator(options.AccountKeeper.(accountKeeper), options.SignModeHandler) + } + return sdk.ChainAnteDecorators( ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first cosmosante.NewRejectMessagesDecorator( []string{ @@ -53,35 +121,55 @@ func GetAnteDecorators(options HandlerOptions) []sdk.AnteDecorator { ante.NewSetPubKeyDecorator(options.AccountKeeper), // SetPubKeyDecorator must be called before all signature verification decorators ante.NewValidateSigCountDecorator(options.AccountKeeper), ante.NewSigGasConsumeDecorator(options.AccountKeeper, sigGasConsumer), - NewSigCheckDecorator(options.AccountKeeper.(accountKeeper), options.SignModeHandler), + sigChecker, ante.NewIncrementSequenceDecorator(options.AccountKeeper), - } - - anteDecorators = append(anteDecorators, ibcante.NewRedundantRelayDecorator(options.IBCKeeper)) - - return anteDecorators + ) } -// NewAnteHandler returns an AnteHandler that checks and increments sequence -// numbers, checks signatures & account numbers, and deducts fees from the first -// signer. -func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { +func (o HandlerOptions) validate() error { // From x/auth/ante.go - if options.AccountKeeper == nil { - return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "account keeper is required for ante builder") + if o.AccountKeeper == nil { + return errorsmod.Wrap(sdkerrors.ErrLogic, "account keeper is required for ante builder") } - if options.BankKeeper == nil { - return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "bank keeper is required for ante builder") + if o.BankKeeper == nil { + return errorsmod.Wrap(sdkerrors.ErrLogic, "bank keeper is required for ante builder") } - if options.SignModeHandler == nil { - return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder") + if o.SignModeHandler == nil { + return errorsmod.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder") } - if options.WasmConfig == nil { - return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "wasm config is required for ante builder") + if o.WasmConfig == nil { + return errorsmod.Wrap(sdkerrors.ErrLogic, "wasm config is required for ante builder") } - return sdk.ChainAnteDecorators(GetAnteDecorators(options)...), nil + if o.TxCounterStoreKey == nil { + return errorsmod.Wrap(sdkerrors.ErrLogic, "tx counter store key is required for ante builder") + } + + if o.SigGasConsumer == nil { + return errorsmod.Wrap(sdkerrors.ErrLogic, "signature gas consumer is required for ante builder") + } + + return nil +} + +func Recover(logger tmlog.Logger, err *error) { + if r := recover(); r != nil { + *err = errorsmod.Wrapf(sdkerrors.ErrPanic, "%v", r) + + if e, ok := r.(error); ok { + logger.Error( + "ante handler panicked", + "error", e, + "stack trace", string(debug.Stack()), + ) + } else { + logger.Error( + "ante handler panicked", + "recover", fmt.Sprintf("%v", r), + ) + } + } } diff --git a/app/app.go b/app/app.go index fe620c1..8ef159a 100644 --- a/app/app.go +++ b/app/app.go @@ -11,9 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/authz" authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module" - gaslessmodule "github.com/dymensionxyz/dymension-rdk/x/gasless" - gaslesskeeper "github.com/dymensionxyz/dymension-rdk/x/gasless/keeper" - gaslesstypes "github.com/dymensionxyz/dymension-rdk/x/gasless/types" + evmosante "github.com/evmos/evmos/v12/app/ante" "github.com/gorilla/mux" "github.com/rakyll/statik/fs" abci "github.com/tendermint/tendermint/abci/types" @@ -23,6 +21,10 @@ import ( tmproto "github.com/tendermint/tendermint/proto/tendermint/types" dbm "github.com/tendermint/tm-db" + gaslessmodule "github.com/dymensionxyz/dymension-rdk/x/gasless" + gaslesskeeper "github.com/dymensionxyz/dymension-rdk/x/gasless/keeper" + gaslesstypes "github.com/dymensionxyz/dymension-rdk/x/gasless/types" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" @@ -144,7 +146,7 @@ import ( cwerrorsKeeper "github.com/dymensionxyz/rollapp-wasm/x/cwerrors/keeper" cwerrorsTypes "github.com/dymensionxyz/rollapp-wasm/x/cwerrors/types" - rollappparams "github.com/dymensionxyz/dymension-rdk/x/rollappparams" + "github.com/dymensionxyz/dymension-rdk/x/rollappparams" rollappparamskeeper "github.com/dymensionxyz/dymension-rdk/x/rollappparams/keeper" rollappparamstypes "github.com/dymensionxyz/dymension-rdk/x/rollappparams/types" ) @@ -847,14 +849,14 @@ func NewRollapp( } func (app *App) setAnteHandler(txConfig client.TxConfig, wasmConfig wasmtypes.WasmConfig) { - anteHandler, err := NewAnteHandler( + handler, err := NewAnteHandler( HandlerOptions{ HandlerOptions: ante.HandlerOptions{ AccountKeeper: app.AccountKeeper, BankKeeper: app.BankKeeper, FeegrantKeeper: app.FeeGrantKeeper, SignModeHandler: txConfig.SignModeHandler(), - SigGasConsumer: ante.DefaultSigVerificationGasConsumer, + SigGasConsumer: evmosante.SigVerificationGasConsumer, }, IBCKeeper: app.IBCKeeper, WasmConfig: &wasmConfig, @@ -866,7 +868,7 @@ func (app *App) setAnteHandler(txConfig client.TxConfig, wasmConfig wasmtypes.Wa panic(err) } - app.SetAnteHandler(anteHandler) + app.SetAnteHandler(handler) } func (app *App) setPostHandler() { diff --git a/app/encoding.go b/app/encoding.go index 666e087..b128650 100644 --- a/app/encoding.go +++ b/app/encoding.go @@ -1,7 +1,11 @@ package app import ( + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/std" + sdk "github.com/cosmos/cosmos-sdk/types" + cryptocodec "github.com/evmos/evmos/v12/crypto/codec" "github.com/dymensionxyz/rollapp-wasm/app/params" ) @@ -9,9 +13,22 @@ import ( // MakeEncodingConfig creates an EncodingConfig for testing func MakeEncodingConfig() params.EncodingConfig { encodingConfig := params.MakeEncodingConfig() - std.RegisterLegacyAminoCodec(encodingConfig.Amino) - std.RegisterInterfaces(encodingConfig.InterfaceRegistry) + RegisterLegacyAminoCodec(encodingConfig.Amino) + RegisterInterfaces(encodingConfig.InterfaceRegistry) ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry) return encodingConfig } + +// RegisterLegacyAminoCodec registers Interfaces from types, crypto, and SDK std. +func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + sdk.RegisterLegacyAminoCodec(cdc) + cryptocodec.RegisterCrypto(cdc) + codec.RegisterEvidences(cdc) +} + +// RegisterInterfaces registers Interfaces from types, crypto, and SDK std. +func RegisterInterfaces(interfaceRegistry codectypes.InterfaceRegistry) { + std.RegisterInterfaces(interfaceRegistry) + cryptocodec.RegisterInterfaces(interfaceRegistry) +} diff --git a/go.mod b/go.mod index 4cedaac..78ce6a5 100644 --- a/go.mod +++ b/go.mod @@ -113,8 +113,10 @@ require ( github.com/dgraph-io/badger/v3 v3.2103.3 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect + github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/go-units v0.5.0 // indirect + github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/dymensionxyz/cosmosclient v0.4.2-beta.0.20240821081230-b4018b2bac13 // indirect github.com/dymensionxyz/gerr-cosmos v1.0.0 // indirect @@ -135,6 +137,7 @@ require ( github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/go-stack/stack v1.8.1 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect diff --git a/rollappd/cmd/root.go b/rollappd/cmd/root.go index 8b30cb5..5807276 100644 --- a/rollappd/cmd/root.go +++ b/rollappd/cmd/root.go @@ -9,18 +9,18 @@ import ( "github.com/cosmos/cosmos-sdk/client/config" "github.com/cosmos/cosmos-sdk/client/debug" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/keys" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/server" serverconfig "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" + ethermintclient "github.com/evmos/evmos/v12/client" + evmosconfig "github.com/evmos/evmos/v12/cmd/config" "github.com/prometheus/client_golang/prometheus" "github.com/spf13/cast" "github.com/spf13/cobra" @@ -38,6 +38,7 @@ import ( rdkserverconfig "github.com/dymensionxyz/dymension-rdk/server/config" "github.com/dymensionxyz/dymension-rdk/utils" dymintconf "github.com/dymensionxyz/dymint/config" + "github.com/dymensionxyz/rollapp-wasm/app" "github.com/dymensionxyz/rollapp-wasm/app/params" ) @@ -54,7 +55,7 @@ const rollappAscii = ` func NewRootCmd() (*cobra.Command, params.EncodingConfig) { encodingConfig := app.MakeEncodingConfig() - //TODO: refactor to use depinject + // TODO: refactor to use depinject initClientCtx := client.Context{}. WithCodec(encodingConfig.Codec). @@ -68,7 +69,7 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) { WithViper("ROLLAPP") rootCmd := &cobra.Command{ - //TODO: set by code, not in Makefile + // TODO: set by code, not in Makefile Use: version.AppName, Short: rollappAscii, PersistentPreRunE: func(cmd *cobra.Command, _ []string) error { @@ -100,11 +101,11 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) { } serverCtx := server.GetServerContextFromCmd(cmd) - //create dymint toml config file + // create dymint toml config file home := serverCtx.Viper.GetString(tmcli.HomeFlag) dymintconf.EnsureRoot(home, dymintconf.DefaultConfig(home)) - //create Block Explorer Json-RPC toml config file + // create Block Explorer Json-RPC toml config file berpcconfig.EnsureRoot(home, berpcconfig.DefaultBeJsonRpcConfig()) return nil @@ -145,6 +146,7 @@ func initRootCmd( // Set config sdkconfig := sdk.GetConfig() utils.SetPrefixes(sdkconfig, app.AccountAddressPrefix) + evmosconfig.SetBip44CoinType(sdkconfig) sdkconfig.Seal() ac := appCreator{ @@ -171,7 +173,7 @@ func initRootCmd( rpc.StatusCommand(), queryCommand(), txCommand(), - keys.Commands(app.DefaultNodeHome), + ethermintclient.KeyCommands(app.DefaultNodeHome), ) }