@@ -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" )
0 commit comments