Skip to content

Commit

Permalink
feat(x/auth/tx): extend app module + docs (#21409)
Browse files Browse the repository at this point in the history
  • Loading branch information
julienrbrt committed Aug 28, 2024
1 parent 39b61a3 commit 355f4d7
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 35 deletions.
2 changes: 1 addition & 1 deletion x/auth/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ type AppModule struct {
// IsAppModule implements the appmodule.AppModule interface.
func (am AppModule) IsAppModule() {}

// NewAppModule creates a new AppModule object
// NewAppModule creates a new AppModule object.
func NewAppModule(
cdc codec.Codec,
accountKeeper keeper.AccountKeeper,
Expand Down
10 changes: 10 additions & 0 deletions x/auth/tx/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ This document specifies the `x/auth/tx` package of the Cosmos SDK.

This package represents the Cosmos SDK implementation of the `client.TxConfig`, `client.TxBuilder`, `client.TxEncoder` and `client.TxDecoder` interfaces.

It contains as well a depinject module and app module the registration of ante/post handler via `runtime` and tx validator via `runtime/v2`.

## Contents

* [Transactions](#transactions)
* [`TxConfig`](#txconfig)
* [`TxBuilder`](#txbuilder)
* [`TxEncoder`/ `TxDecoder`](#txencoder-txdecoder)
* [Depinject \& App Module](#depinject--app-module)
* [Client](#client)
* [CLI](#cli)
* [gRPC](#grpc)
Expand Down Expand Up @@ -57,6 +60,13 @@ A `client.TxBuilder` can be accessed with `TxConfig.NewTxBuilder()`.

More information about `TxEncoder` and `TxDecoder` can be found [here](https://docs.cosmos.network/main/core/encoding#transaction-encoding).

## Depinject & App Module

The `x/auth/tx/config` contains a depinject module and app module.
The depinject module is there to setup ante/post handlers on an runtime app (via baseapp options) and the tx validator on the runtime/v2 app (via app module). It as well outputs the `TxConfig` and `TxConfigOptions` for the app.

The app module is purely there for registering tx validators, due to the design of tx validators (tx validator belong to modules).

## Client

### CLI
Expand Down
52 changes: 18 additions & 34 deletions x/auth/tx/config/depinject.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ import (
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
txconfigv1 "cosmossdk.io/api/cosmos/tx/config/v1"
"cosmossdk.io/core/address"
"cosmossdk.io/core/appmodule"
appmodulev2 "cosmossdk.io/core/appmodule/v2"
"cosmossdk.io/core/appmodule/v2"
"cosmossdk.io/core/transaction"
"cosmossdk.io/depinject"
"cosmossdk.io/depinject/appconfig"
Expand Down Expand Up @@ -52,23 +51,24 @@ type ModuleInputs struct {
ProtoFileResolver txsigning.ProtoFileResolver
Environment appmodule.Environment
// BankKeeper is the expected bank keeper to be passed to AnteHandlers
BankKeeper authtypes.BankKeeper `optional:"true"`
MetadataBankKeeper BankKeeper `optional:"true"`
AccountKeeper ante.AccountKeeper `optional:"true"`
FeeGrantKeeper ante.FeegrantKeeper `optional:"true"`
AccountAbstractionKeeper ante.AccountAbstractionKeeper `optional:"true"`
CustomSignModeHandlers func() []txsigning.SignModeHandler `optional:"true"`
CustomGetSigners []txsigning.CustomGetSigner `optional:"true"`
UnorderedTxManager *unorderedtx.Manager `optional:"true"`
BankKeeper authtypes.BankKeeper `optional:"true"`
MetadataBankKeeper BankKeeper `optional:"true"`
AccountKeeper ante.AccountKeeper `optional:"true"`
FeeGrantKeeper ante.FeegrantKeeper `optional:"true"`
AccountAbstractionKeeper ante.AccountAbstractionKeeper `optional:"true"`
CustomSignModeHandlers func() []txsigning.SignModeHandler `optional:"true"`
CustomGetSigners []txsigning.CustomGetSigner `optional:"true"`
UnorderedTxManager *unorderedtx.Manager `optional:"true"`
ExtraTxValidators []appmodule.TxValidator[transaction.Tx] `optional:"true"`
}

type ModuleOutputs struct {
depinject.Out

Module appmodule.AppModule // This is only useful for chains using server/v2. It setup tx validators that don't belong to other modules.
BaseAppOption runtime.BaseAppOption // This is only useful for chains using baseapp. Server/v2 chains use TxValidator.
TxConfig client.TxConfig
TxConfigOptions tx.ConfigOptions
BaseAppOption runtime.BaseAppOption // This is only useful for chains using baseapp. Server/v2 chains use TxValidator.
Module appmodule.AppModule
}

func ProvideProtoRegistry() txsigning.ProtoFileResolver {
Expand Down Expand Up @@ -152,9 +152,13 @@ func ProvideModule(in ModuleInputs) ModuleOutputs {
ante.DefaultSigVerificationGasConsumer,
in.AccountAbstractionKeeper,
)
appModule := AppModule{svd}

return ModuleOutputs{TxConfig: txConfig, TxConfigOptions: txConfigOptions, BaseAppOption: baseAppOption, Module: appModule}
return ModuleOutputs{
Module: NewAppModule(svd, in.ExtraTxValidators...),
TxConfig: txConfig,
TxConfigOptions: txConfigOptions,
BaseAppOption: baseAppOption,
}
}

func newAnteHandler(txConfig client.TxConfig, in ModuleInputs) (sdk.AnteHandler, error) {
Expand Down Expand Up @@ -235,23 +239,3 @@ func metadataExists(err error) error {

return err
}

var (
_ appmodulev2.AppModule = AppModule{}
_ appmodulev2.HasTxValidator[transaction.Tx] = AppModule{}
)

type AppModule struct {
sigVerification ante.SigVerificationDecorator
}

// TxValidator implements appmodule.HasTxValidator.
func (a AppModule) TxValidator(ctx context.Context, tx transaction.Tx) error {
return a.sigVerification.ValidateTx(ctx, tx)
}

// IsAppModule implements appmodule.AppModule.
func (a AppModule) IsAppModule() {}

// IsOnePerModuleType implements appmodule.AppModule.
func (a AppModule) IsOnePerModuleType() {}
54 changes: 54 additions & 0 deletions x/auth/tx/config/module.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package tx

import (
"context"

appmodulev2 "cosmossdk.io/core/appmodule/v2"
"cosmossdk.io/core/transaction"
"cosmossdk.io/x/auth/ante"
)

var (
_ appmodulev2.AppModule = AppModule{}
_ appmodulev2.HasTxValidator[transaction.Tx] = AppModule{}
)

// AppModule is a module that only implements tx validators.
// The goal of this module is to allow extensible registration of tx validators provided by chains without requiring a new modules.
// Additionally, it registers tx validators that do not really have a place in other modules.
// This module is only useful for chains using server/v2. Ante/Post handlers are setup via baseapp options in depinject.
type AppModule struct {
sigVerification ante.SigVerificationDecorator
// txValidators contains tx validator that can be injected into the module via depinject.
// tx validators should be module based, but it can happen that you do not want to create a new module
// and simply depinject-it.
txValidators []appmodulev2.TxValidator[transaction.Tx]
}

// NewAppModule creates a new AppModule object.
func NewAppModule(
sigVerification ante.SigVerificationDecorator,
txValidators ...appmodulev2.TxValidator[transaction.Tx],
) AppModule {
return AppModule{
sigVerification: sigVerification,
txValidators: txValidators,
}
}

// IsAppModule implements appmodule.AppModule.
func (a AppModule) IsAppModule() {}

// IsOnePerModuleType implements appmodule.AppModule.
func (a AppModule) IsOnePerModuleType() {}

// TxValidator implements appmodule.HasTxValidator.
func (a AppModule) TxValidator(ctx context.Context, tx transaction.Tx) error {
for _, txValidator := range a.txValidators {
if err := txValidator.ValidateTx(ctx, tx); err != nil {
return err
}
}

return a.sigVerification.ValidateTx(ctx, tx)
}

0 comments on commit 355f4d7

Please sign in to comment.