cosmos-sdk/x/validate/depinject.go
2024-11-11 15:12:15 +00:00

158 lines
5.4 KiB
Go

package validate
import (
"fmt"
"github.com/spf13/cast"
modulev1 "cosmossdk.io/api/cosmos/validate/module/v1"
appmodulev2 "cosmossdk.io/core/appmodule/v2"
"cosmossdk.io/core/server"
"cosmossdk.io/core/transaction"
"cosmossdk.io/depinject"
"cosmossdk.io/depinject/appconfig"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/runtime"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
"github.com/cosmos/cosmos-sdk/x/auth/ante/unorderedtx"
"github.com/cosmos/cosmos-sdk/x/auth/posthandler"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
// flagMinGasPricesV2 is the flag name for the minimum gas prices in the main server v2 component.
const flagMinGasPricesV2 = "server.minimum-gas-prices"
func init() {
appconfig.RegisterModule(&modulev1.Module{},
appconfig.Provide(ProvideModule, ProvideConfig),
)
}
// ProvideConfig specifies the configuration key for the minimum gas prices.
// During dependency injection, a configuration map is provided with the key set.
func ProvideConfig(key depinject.OwnModuleKey) server.ModuleConfigMap {
return server.ModuleConfigMap{
Module: depinject.ModuleKey(key).Name(),
Config: server.ConfigMap{
flagMinGasPricesV2: "",
},
}
}
type ModuleInputs struct {
depinject.In
ModuleConfig *modulev1.Module
Environment appmodulev2.Environment
TxConfig client.TxConfig
ConfigMap server.ConfigMap
AccountKeeper ante.AccountKeeper
BankKeeper authtypes.BankKeeper
ConsensusKeeper ante.ConsensusKeeper
FeeGrantKeeper ante.FeegrantKeeper `optional:"true"`
AccountAbstractionKeeper ante.AccountAbstractionKeeper `optional:"true"`
ExtraTxValidators []appmodulev2.TxValidator[transaction.Tx] `optional:"true"`
UnorderedTxManager *unorderedtx.Manager `optional:"true"`
TxFeeChecker ante.TxFeeChecker `optional:"true"`
}
type ModuleOutputs struct {
depinject.Out
Module appmodulev2.AppModule // Only useful for chains using server/v2. It setup tx validators that don't belong to other modules.
BaseAppOption runtime.BaseAppOption // Only useful for chains using baseapp. Server/v2 chains use TxValidator.
}
func ProvideModule(in ModuleInputs) ModuleOutputs {
svd := ante.NewSigVerificationDecorator(
in.AccountKeeper,
in.TxConfig.SignModeHandler(),
ante.DefaultSigVerificationGasConsumer,
in.AccountAbstractionKeeper, // can be nil
)
var (
err error
minGasPrices sdk.DecCoins
feeTxValidator *ante.DeductFeeDecorator
unorderedTxValidator *ante.UnorderedTxDecorator
)
minGasPricesStr := cast.ToString(in.ConfigMap[flagMinGasPricesV2])
minGasPrices, err = sdk.ParseDecCoins(minGasPricesStr)
if err != nil {
panic(fmt.Sprintf("invalid minimum gas prices: %v", err))
}
feeTxValidator = ante.NewDeductFeeDecorator(in.AccountKeeper, in.BankKeeper, in.FeeGrantKeeper, in.TxFeeChecker)
feeTxValidator.SetMinGasPrices(minGasPrices) // set min gas price in deduct fee decorator
if in.UnorderedTxManager != nil {
unorderedTxValidator = ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, in.UnorderedTxManager, in.Environment, ante.DefaultSha256Cost)
}
return ModuleOutputs{
Module: NewAppModule(svd, feeTxValidator, unorderedTxValidator, in.ExtraTxValidators...),
BaseAppOption: newBaseAppOption(in),
}
}
// newBaseAppOption returns baseapp option that sets the ante handler and post handler
// and set the tx encoder and decoder on baseapp.
func newBaseAppOption(in ModuleInputs) func(app *baseapp.BaseApp) {
return func(app *baseapp.BaseApp) {
anteHandler, err := newAnteHandler(in)
if err != nil {
panic(err)
}
app.SetAnteHandler(anteHandler)
// PostHandlers
// In v0.46, the SDK introduces _postHandlers_. PostHandlers are like
// antehandlers, but are run _after_ the `runMsgs` execution. They are also
// defined as a chain, and have the same signature as antehandlers.
//
// In baseapp, postHandlers are run in the same store branch as `runMsgs`,
// meaning that both `runMsgs` and `postHandler` state will be committed if
// both are successful, and both will be reverted if any of the two fails.
//
// The SDK exposes a default empty postHandlers chain.
//
// Please note that changing any of the anteHandler or postHandler chain is
// likely to be a state-machine breaking change, which needs a coordinated
// upgrade.
postHandler, err := posthandler.NewPostHandler(
posthandler.HandlerOptions{},
)
if err != nil {
panic(err)
}
app.SetPostHandler(postHandler)
}
}
func newAnteHandler(in ModuleInputs) (sdk.AnteHandler, error) {
anteHandler, err := ante.NewAnteHandler(
ante.HandlerOptions{
Environment: in.Environment,
AccountKeeper: in.AccountKeeper,
ConsensusKeeper: in.ConsensusKeeper,
BankKeeper: in.BankKeeper,
SignModeHandler: in.TxConfig.SignModeHandler(),
FeegrantKeeper: in.FeeGrantKeeper,
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
UnorderedTxManager: in.UnorderedTxManager,
AccountAbstractionKeeper: in.AccountAbstractionKeeper,
},
)
if err != nil {
return nil, fmt.Errorf("failed to create ante handler: %w", err)
}
return anteHandler, nil
}