Skip to content

Commit 23359a0

Browse files
Devon Beartac0turtle
andauthored
feat(server): Allow calling back into the application struct in PostSetup. (#19455)
Co-authored-by: Marko <marbar3778@yahoo.com>
1 parent acdb356 commit 23359a0

11 files changed

Lines changed: 48 additions & 37 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ Every module contains its own CHANGELOG.md. Please refer to the module you are i
5656

5757
### Improvements
5858

59+
* (server) [#19455](https://github.com/cosmos/cosmos-sdk/pull/19455) Allow calling back into the application struct in PostSetup.
5960
* (types) [#19512](https://github.com/cosmos/cosmos-sdk/pull/19512) The notion of basic manager does not exist anymore.
6061
* The module manager now can do everything that the basic manager was doing.
6162
* `AppModuleBasic` has been deprecated for extension interfaces. Modules can now implement `HasRegisterInterfaces`, `HasGRPCGateway` and `HasAminoCodec` when relevant.

client/pruning/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const FlagAppDBBackend = "app-db-backend"
2222

2323
// Cmd prunes the sdk root multi store history versions based on the pruning options
2424
// specified by command flags.
25-
func Cmd(appCreator servertypes.AppCreator) *cobra.Command {
25+
func Cmd[T servertypes.Application](appCreator servertypes.AppCreator[T]) *cobra.Command {
2626
cmd := &cobra.Command{
2727
Use: "prune [pruning-method]",
2828
Short: "Prune app history states by keeping the recent heights and deleting old heights",

client/snapshot/cmd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
)
88

99
// Cmd returns the snapshots group command
10-
func Cmd(appCreator servertypes.AppCreator) *cobra.Command {
10+
func Cmd[T servertypes.Application](appCreator servertypes.AppCreator[T]) *cobra.Command {
1111
cmd := &cobra.Command{
1212
Use: "snapshots",
1313
Short: "Manage local snapshots",

client/snapshot/export.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
)
1111

1212
// ExportSnapshotCmd returns a command to take a snapshot of the application state
13-
func ExportSnapshotCmd(appCreator servertypes.AppCreator) *cobra.Command {
13+
func ExportSnapshotCmd[T servertypes.Application](appCreator servertypes.AppCreator[T]) *cobra.Command {
1414
cmd := &cobra.Command{
1515
Use: "export",
1616
Short: "Export app state to snapshot store",

client/snapshot/restore.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
)
1515

1616
// RestoreSnapshotCmd returns a command to restore a snapshot
17-
func RestoreSnapshotCmd(appCreator servertypes.AppCreator) *cobra.Command {
17+
func RestoreSnapshotCmd[T servertypes.Application](appCreator servertypes.AppCreator[T]) *cobra.Command {
1818
cmd := &cobra.Command{
1919
Use: "restore <height> <format>",
2020
Short: "Restore app state from local snapshot",

server/cmt_cmds.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ func parseOptionalHeight(heightStr string) (*int64, error) {
356356
return &tmp, nil
357357
}
358358

359-
func BootstrapStateCmd(appCreator types.AppCreator) *cobra.Command {
359+
func BootstrapStateCmd[T types.Application](appCreator types.AppCreator[T]) *cobra.Command {
360360
cmd := &cobra.Command{
361361
Use: "bootstrap-state",
362362
Short: "Bootstrap CometBFT state at an arbitrary block height using a light client",

server/rollback.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
)
1111

1212
// NewRollbackCmd creates a command to rollback CometBFT and multistore state by one height.
13-
func NewRollbackCmd(appCreator types.AppCreator) *cobra.Command {
13+
func NewRollbackCmd[T types.Application](appCreator types.AppCreator[T]) *cobra.Command {
1414
var removeBlock bool
1515

1616
cmd := &cobra.Command{

server/start.go

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -108,26 +108,28 @@ const (
108108
)
109109

110110
// StartCmdOptions defines options that can be customized in `StartCmdWithOptions`,
111-
type StartCmdOptions struct {
111+
type StartCmdOptions[T types.Application] struct {
112112
// DBOpener can be used to customize db opening, for example customize db options or support different db backends,
113113
// default to the builtin db opener.
114114
DBOpener func(rootDir string, backendType dbm.BackendType) (dbm.DB, error)
115115
// PostSetup can be used to setup extra services under the same cancellable context,
116116
// it's not called in stand-alone mode, only for in-process mode.
117-
PostSetup func(svrCtx *Context, clientCtx client.Context, ctx context.Context, g *errgroup.Group) error
117+
PostSetup func(app T, svrCtx *Context, clientCtx client.Context, ctx context.Context, g *errgroup.Group) error
118+
// PostSetupStandalone can be used to setup extra services under the same cancellable context,
119+
PostSetupStandalone func(app T, svrCtx *Context, clientCtx client.Context, ctx context.Context, g *errgroup.Group) error
118120
// AddFlags add custom flags to start cmd
119121
AddFlags func(cmd *cobra.Command)
120122
}
121123

122124
// StartCmd runs the service passed in, either stand-alone or in-process with
123125
// CometBFT.
124-
func StartCmd(appCreator types.AppCreator) *cobra.Command {
125-
return StartCmdWithOptions(appCreator, StartCmdOptions{})
126+
func StartCmd[T types.Application](appCreator types.AppCreator[T]) *cobra.Command {
127+
return StartCmdWithOptions(appCreator, StartCmdOptions[T]{})
126128
}
127129

128130
// StartCmdWithOptions runs the service passed in, either stand-alone or in-process with
129131
// CometBFT.
130-
func StartCmdWithOptions(appCreator types.AppCreator, opts StartCmdOptions) *cobra.Command {
132+
func StartCmdWithOptions[T types.Application](appCreator types.AppCreator[T], opts StartCmdOptions[T]) *cobra.Command {
131133
if opts.DBOpener == nil {
132134
opts.DBOpener = OpenDB
133135
}
@@ -199,13 +201,13 @@ is performed. Note, when enabled, gRPC will also be automatically enabled.
199201
return cmd
200202
}
201203

202-
func start(svrCtx *Context, clientCtx client.Context, appCreator types.AppCreator, withCmt bool, opts StartCmdOptions) error {
204+
func start[T types.Application](svrCtx *Context, clientCtx client.Context, appCreator types.AppCreator[T], withCmt bool, opts StartCmdOptions[T]) error {
203205
svrCfg, err := getAndValidateConfig(svrCtx)
204206
if err != nil {
205207
return err
206208
}
207209

208-
app, appCleanupFn, err := startApp(svrCtx, appCreator, opts)
210+
app, appCleanupFn, err := startApp[T](svrCtx, appCreator, opts)
209211
if err != nil {
210212
return err
211213
}
@@ -219,12 +221,12 @@ func start(svrCtx *Context, clientCtx client.Context, appCreator types.AppCreato
219221
emitServerInfoMetrics()
220222

221223
if !withCmt {
222-
return startStandAlone(svrCtx, svrCfg, clientCtx, app, metrics, opts)
224+
return startStandAlone[T](svrCtx, svrCfg, clientCtx, app, metrics, opts)
223225
}
224-
return startInProcess(svrCtx, svrCfg, clientCtx, app, metrics, opts)
226+
return startInProcess[T](svrCtx, svrCfg, clientCtx, app, metrics, opts)
225227
}
226228

227-
func startStandAlone(svrCtx *Context, svrCfg serverconfig.Config, clientCtx client.Context, app types.Application, metrics *telemetry.Metrics, opts StartCmdOptions) error {
229+
func startStandAlone[T types.Application](svrCtx *Context, svrCfg serverconfig.Config, clientCtx client.Context, app T, metrics *telemetry.Metrics, opts StartCmdOptions[T]) error {
228230
addr := svrCtx.Viper.GetString(flagAddress)
229231
transport := svrCtx.Viper.GetString(flagTransport)
230232

@@ -271,6 +273,12 @@ func startStandAlone(svrCtx *Context, svrCfg serverconfig.Config, clientCtx clie
271273
return err
272274
}
273275

276+
if opts.PostSetup != nil {
277+
if err := opts.PostSetupStandalone(app, svrCtx, clientCtx, ctx, g); err != nil {
278+
return err
279+
}
280+
}
281+
274282
g.Go(func() error {
275283
if err := svr.Start(); err != nil {
276284
svrCtx.Logger.Error("failed to start out-of-process ABCI server", "err", err)
@@ -287,8 +295,8 @@ func startStandAlone(svrCtx *Context, svrCfg serverconfig.Config, clientCtx clie
287295
return g.Wait()
288296
}
289297

290-
func startInProcess(svrCtx *Context, svrCfg serverconfig.Config, clientCtx client.Context, app types.Application,
291-
metrics *telemetry.Metrics, opts StartCmdOptions,
298+
func startInProcess[T types.Application](svrCtx *Context, svrCfg serverconfig.Config, clientCtx client.Context, app T,
299+
metrics *telemetry.Metrics, opts StartCmdOptions[T],
292300
) error {
293301
cmtCfg := svrCtx.Config
294302
home := cmtCfg.RootDir
@@ -334,7 +342,7 @@ func startInProcess(svrCtx *Context, svrCfg serverconfig.Config, clientCtx clien
334342
}
335343

336344
if opts.PostSetup != nil {
337-
if err := opts.PostSetup(svrCtx, clientCtx, ctx, g); err != nil {
345+
if err := opts.PostSetup(app, svrCtx, clientCtx, ctx, g); err != nil {
338346
return err
339347
}
340348
}
@@ -585,7 +593,7 @@ func getCtx(svrCtx *Context, block bool) (*errgroup.Group, context.Context) {
585593
return g, ctx
586594
}
587595

588-
func startApp(svrCtx *Context, appCreator types.AppCreator, opts StartCmdOptions) (app types.Application, cleanupFn func(), err error) {
596+
func startApp[T types.Application](svrCtx *Context, appCreator types.AppCreator[T], opts StartCmdOptions[T]) (app T, cleanupFn func(), err error) {
589597
traceWriter, traceCleanupFn, err := SetupTraceWriter(svrCtx.Logger, svrCtx.Viper.GetString(flagTraceStore))
590598
if err != nil {
591599
return app, traceCleanupFn, err
@@ -598,10 +606,12 @@ func startApp(svrCtx *Context, appCreator types.AppCreator, opts StartCmdOptions
598606
}
599607

600608
if isTestnet, ok := svrCtx.Viper.Get(KeyIsTestnet).(bool); ok && isTestnet {
601-
app, err = testnetify(svrCtx, home, appCreator, db, traceWriter)
609+
var appPtr *T
610+
appPtr, err = testnetify[T](svrCtx, home, appCreator, db, traceWriter)
602611
if err != nil {
603612
return app, traceCleanupFn, err
604613
}
614+
app = *appPtr
605615
} else {
606616
app = appCreator(svrCtx.Logger, db, traceWriter, svrCtx.Viper)
607617
}
@@ -618,8 +628,8 @@ func startApp(svrCtx *Context, appCreator types.AppCreator, opts StartCmdOptions
618628
// InPlaceTestnetCreator utilizes the provided chainID and operatorAddress as well as the local private validator key to
619629
// control the network represented in the data folder. This is useful to create testnets nearly identical to your
620630
// mainnet environment.
621-
func InPlaceTestnetCreator(testnetAppCreator types.AppCreator) *cobra.Command {
622-
opts := StartCmdOptions{}
631+
func InPlaceTestnetCreator[T types.Application](testnetAppCreator types.AppCreator[T]) *cobra.Command {
632+
opts := StartCmdOptions[T]{}
623633
if opts.DBOpener == nil {
624634
opts.DBOpener = OpenDB
625635
}
@@ -711,7 +721,7 @@ you want to test the upgrade handler itself.
711721

712722
// testnetify modifies both state and blockStore, allowing the provided operator address and local validator key to control the network
713723
// that the state in the data folder represents. The chainID of the local genesis file is modified to match the provided chainID.
714-
func testnetify(ctx *Context, home string, testnetAppCreator types.AppCreator, db dbm.DB, traceWriter io.WriteCloser) (types.Application, error) {
724+
func testnetify[T types.Application](ctx *Context, home string, testnetAppCreator types.AppCreator[T], db dbm.DB, traceWriter io.WriteCloser) (*T, error) {
715725
config := ctx.Config
716726

717727
newChainID, ok := ctx.Viper.Get(KeyNewChainID).(string)
@@ -933,11 +943,11 @@ func testnetify(ctx *Context, home string, testnetAppCreator types.AppCreator, d
933943
return nil, err
934944
}
935945

936-
return testnetApp, err
946+
return &testnetApp, err
937947
}
938948

939949
// addStartNodeFlags should be added to any CLI commands that start the network.
940-
func addStartNodeFlags(cmd *cobra.Command, opts StartCmdOptions) {
950+
func addStartNodeFlags[T types.Application](cmd *cobra.Command, opts StartCmdOptions[T]) {
941951
cmd.Flags().Bool(flagWithComet, true, "Run abci app embedded in-process with CometBFT")
942952
cmd.Flags().String(flagAddress, "tcp://127.0.0.1:26658", "Listen address")
943953
cmd.Flags().String(flagTransport, "socket", "Transport protocol: socket, grpc")

server/types/app.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ type (
6666

6767
// AppCreator is a function that allows us to lazily initialize an
6868
// application using various configurations.
69-
AppCreator func(log.Logger, dbm.DB, io.Writer, AppOptions) Application
69+
AppCreator[T Application] func(log.Logger, dbm.DB, io.Writer, AppOptions) T
7070

7171
// ModuleInitFlags takes a start command and adds modules specific init flags.
7272
ModuleInitFlags func(startCmd *cobra.Command)

server/util.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ func interceptConfigs(rootViper *viper.Viper, customAppTemplate string, customCo
324324
}
325325

326326
// add server commands
327-
func AddCommands(rootCmd *cobra.Command, appCreator types.AppCreator, addStartFlags types.ModuleInitFlags) {
327+
func AddCommands[T types.Application](rootCmd *cobra.Command, appCreator types.AppCreator[T], addStartFlags types.ModuleInitFlags) {
328328
cometCmd := &cobra.Command{
329329
Use: "comet",
330330
Aliases: []string{"cometbft", "tendermint"},
@@ -355,7 +355,7 @@ func AddCommands(rootCmd *cobra.Command, appCreator types.AppCreator, addStartFl
355355
}
356356

357357
// AddTestnetCreatorCommand allows chains to create a testnet from the state existing in their node's data directory.
358-
func AddTestnetCreatorCommand(rootCmd *cobra.Command, appCreator types.AppCreator, addStartFlags types.ModuleInitFlags) {
358+
func AddTestnetCreatorCommand[T types.Application](rootCmd *cobra.Command, appCreator types.AppCreator[T], addStartFlags types.ModuleInitFlags) {
359359
testnetCreateCmd := InPlaceTestnetCreator(appCreator)
360360
addStartFlags(testnetCreateCmd)
361361
rootCmd.AddCommand(testnetCreateCmd)

0 commit comments

Comments
 (0)