281 lines
7.6 KiB
Go
281 lines
7.6 KiB
Go
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
"cosmossdk.io/client/v2/offchain"
|
|
coreserver "cosmossdk.io/core/server"
|
|
"cosmossdk.io/core/transaction"
|
|
"cosmossdk.io/log"
|
|
runtimev2 "cosmossdk.io/runtime/v2"
|
|
serverv2 "cosmossdk.io/server/v2"
|
|
grpcserver "cosmossdk.io/server/v2/api/grpc"
|
|
"cosmossdk.io/server/v2/api/grpcgateway"
|
|
"cosmossdk.io/server/v2/api/rest"
|
|
"cosmossdk.io/server/v2/api/swagger"
|
|
"cosmossdk.io/server/v2/api/telemetry"
|
|
"cosmossdk.io/server/v2/cometbft"
|
|
serverstore "cosmossdk.io/server/v2/store"
|
|
"cosmossdk.io/simapp/v2"
|
|
confixcmd "cosmossdk.io/tools/confix/cmd"
|
|
|
|
"github.com/cosmos/cosmos-sdk/client"
|
|
"github.com/cosmos/cosmos-sdk/client/config"
|
|
"github.com/cosmos/cosmos-sdk/client/debug"
|
|
"github.com/cosmos/cosmos-sdk/client/docs"
|
|
"github.com/cosmos/cosmos-sdk/client/grpc/cmtservice"
|
|
nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node"
|
|
"github.com/cosmos/cosmos-sdk/client/keys"
|
|
"github.com/cosmos/cosmos-sdk/client/rpc"
|
|
sdktelemetry "github.com/cosmos/cosmos-sdk/telemetry"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
|
|
"github.com/cosmos/cosmos-sdk/version"
|
|
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
|
"github.com/cosmos/cosmos-sdk/x/genutil"
|
|
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
|
|
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
|
v2 "github.com/cosmos/cosmos-sdk/x/genutil/v2/cli"
|
|
)
|
|
|
|
// CommandDependencies is a struct that contains all the dependencies needed to initialize the root command.
|
|
// an alternative design could fetch these even later from the command context
|
|
type CommandDependencies[T transaction.Tx] struct {
|
|
GlobalConfig coreserver.ConfigMap
|
|
TxConfig client.TxConfig
|
|
ModuleManager *runtimev2.MM[T]
|
|
SimApp *simapp.SimApp[T]
|
|
ClientContext client.Context
|
|
}
|
|
|
|
func InitRootCmd[T transaction.Tx](
|
|
rootCmd *cobra.Command,
|
|
logger log.Logger,
|
|
deps CommandDependencies[T],
|
|
) (serverv2.ConfigWriter, error) {
|
|
cfg := sdk.GetConfig()
|
|
cfg.Seal()
|
|
|
|
rootCmd.AddCommand(
|
|
genutilcli.InitCmd(deps.ModuleManager),
|
|
genesisCommand(deps.ModuleManager, deps.SimApp),
|
|
NewTestnetCmd(deps.ModuleManager),
|
|
debug.Cmd(),
|
|
confixcmd.ConfigCommand(),
|
|
// add keybase, auxiliary RPC, query, genesis, and tx child commands
|
|
queryCommand(),
|
|
txCommand(),
|
|
keys.Commands(),
|
|
offchain.OffChain(),
|
|
version.NewVersionCommand(),
|
|
)
|
|
|
|
// build CLI skeleton for initial config parsing or a client application invocation
|
|
if deps.SimApp == nil {
|
|
return serverv2.AddCommands[T](
|
|
rootCmd,
|
|
logger,
|
|
io.NopCloser(nil),
|
|
deps.GlobalConfig,
|
|
initServerConfig(),
|
|
cometbft.NewWithConfigOptions[T](initCometConfig()),
|
|
&grpcserver.Server[T]{},
|
|
&serverstore.Server[T]{},
|
|
&telemetry.Server[T]{},
|
|
&rest.Server[T]{},
|
|
&grpcgateway.Server[T]{},
|
|
&swagger.Server[T]{},
|
|
)
|
|
}
|
|
|
|
// build full app!
|
|
simApp := deps.SimApp
|
|
|
|
// store component (not a server)
|
|
storeComponent, err := serverstore.New[T](simApp.Store(), deps.GlobalConfig)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
restServer, err := rest.New[T](logger, simApp.App.AppManager, deps.GlobalConfig)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// consensus component
|
|
consensusServer, err := cometbft.New(
|
|
logger,
|
|
simApp.Name(),
|
|
simApp.Store(),
|
|
simApp.App.AppManager,
|
|
cometbft.AppCodecs[T]{
|
|
AppCodec: simApp.AppCodec(),
|
|
TxCodec: &client.DefaultTxDecoder[T]{TxConfig: deps.TxConfig},
|
|
LegacyAmino: deps.ClientContext.LegacyAmino,
|
|
ConsensusAddressCodec: deps.ClientContext.ConsensusAddressCodec,
|
|
},
|
|
simApp.App.QueryHandlers(),
|
|
simApp.App.SchemaDecoderResolver(),
|
|
initCometOptions[T](),
|
|
deps.GlobalConfig,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
telemetryServer, err := telemetry.New[T](logger, sdktelemetry.EnableTelemetry, deps.GlobalConfig)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
swaggerServer, err := swagger.New[T](logger, docs.GetSwaggerFS(), deps.GlobalConfig)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
grpcServer, err := grpcserver.New[T](
|
|
logger,
|
|
simApp.InterfaceRegistry(),
|
|
simApp.QueryHandlers(),
|
|
simApp.Query,
|
|
deps.GlobalConfig,
|
|
grpcserver.WithExtraGRPCHandlers[T](
|
|
consensusServer.GRPCServiceRegistrar(
|
|
deps.ClientContext,
|
|
deps.GlobalConfig,
|
|
),
|
|
),
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
grpcgatewayServer, err := grpcgateway.New[T](
|
|
logger,
|
|
deps.GlobalConfig,
|
|
simApp.InterfaceRegistry(),
|
|
simApp.App.AppManager,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
registerGRPCGatewayRoutes(deps.ClientContext, grpcgatewayServer)
|
|
|
|
// wire server commands
|
|
return serverv2.AddCommands[T](
|
|
rootCmd,
|
|
logger,
|
|
simApp,
|
|
deps.GlobalConfig,
|
|
initServerConfig(),
|
|
consensusServer,
|
|
grpcServer,
|
|
storeComponent,
|
|
telemetryServer,
|
|
restServer,
|
|
grpcgatewayServer,
|
|
swaggerServer,
|
|
)
|
|
}
|
|
|
|
// genesisCommand builds genesis-related `simd genesis` command.
|
|
func genesisCommand[T transaction.Tx](
|
|
moduleManager *runtimev2.MM[T],
|
|
app *simapp.SimApp[T],
|
|
) *cobra.Command {
|
|
var genTxValidator func([]transaction.Msg) error
|
|
if moduleManager != nil {
|
|
genTxValidator = moduleManager.Modules()[genutiltypes.ModuleName].(genutil.AppModule).GenTxValidator()
|
|
}
|
|
cmd := v2.Commands(
|
|
genTxValidator,
|
|
moduleManager,
|
|
app,
|
|
)
|
|
|
|
return cmd
|
|
}
|
|
|
|
func queryCommand() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "query",
|
|
Aliases: []string{"q"},
|
|
Short: "Querying subcommands",
|
|
DisableFlagParsing: false,
|
|
SuggestionsMinimumDistance: 2,
|
|
RunE: client.ValidateCmd,
|
|
}
|
|
|
|
cmd.AddCommand(
|
|
rpc.QueryEventForTxCmd(),
|
|
authcmd.QueryTxsByEventsCmd(),
|
|
authcmd.QueryTxCmd(),
|
|
)
|
|
|
|
return cmd
|
|
}
|
|
|
|
func txCommand() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "tx",
|
|
Short: "Transactions subcommands",
|
|
DisableFlagParsing: false,
|
|
SuggestionsMinimumDistance: 2,
|
|
RunE: client.ValidateCmd,
|
|
}
|
|
|
|
cmd.AddCommand(
|
|
authcmd.GetSignCommand(),
|
|
authcmd.GetSignBatchCommand(),
|
|
authcmd.GetMultiSignCommand(),
|
|
authcmd.GetMultiSignBatchCmd(),
|
|
authcmd.GetValidateSignaturesCommand(),
|
|
authcmd.GetBroadcastCommand(),
|
|
authcmd.GetEncodeCommand(),
|
|
authcmd.GetDecodeCommand(),
|
|
authcmd.GetSimulateCmd(),
|
|
)
|
|
|
|
return cmd
|
|
}
|
|
|
|
func RootCommandPersistentPreRun(clientCtx client.Context) func(*cobra.Command, []string) error {
|
|
return func(cmd *cobra.Command, args []string) error {
|
|
// set the default command outputs
|
|
cmd.SetOut(cmd.OutOrStdout())
|
|
cmd.SetErr(cmd.ErrOrStderr())
|
|
|
|
clientCtx = clientCtx.WithCmdContext(cmd.Context())
|
|
clientCtx, err := client.ReadPersistentCommandFlags(clientCtx, cmd.Flags())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
customClientTemplate, customClientConfig := initClientConfig()
|
|
clientCtx, err = config.CreateClientConfig(
|
|
clientCtx, customClientTemplate, customClientConfig)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err = client.SetCmdClientContextHandler(clientCtx, cmd); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// registerGRPCGatewayRoutes registers the gRPC gateway routes for all modules and other components
|
|
func registerGRPCGatewayRoutes[T transaction.Tx](
|
|
clientContext client.Context,
|
|
server *grpcgateway.Server[T],
|
|
) {
|
|
// those are the extra services that the CometBFT server implements (server/v2/cometbft/grpc.go)
|
|
cmtservice.RegisterGRPCGatewayRoutes(clientContext, server.GRPCGatewayRouter)
|
|
_ = nodeservice.RegisterServiceHandlerClient(context.Background(), server.GRPCGatewayRouter, nodeservice.NewServiceClient(clientContext))
|
|
_ = txtypes.RegisterServiceHandlerClient(context.Background(), server.GRPCGatewayRouter, txtypes.NewServiceClient(clientContext))
|
|
}
|