-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
…#22336) Co-authored-by: marbar3778 <[email protected]> Co-authored-by: Marko <[email protected]> Co-authored-by: Alex | Interchain Labs <[email protected]> (cherry picked from commit 064c9ba) # Conflicts: # scripts/init-simapp-v2.sh # server/v2/server.go # simapp/v2/app_config.go # store/v2/commitment/iavl/exporter.go # store/v2/commitment/iavl/tree.go # store/v2/commitment/metadata.go # store/v2/commitment/store.go # store/v2/commitment/store_test_suite.go # store/v2/go.mod # store/v2/migration/manager.go # store/v2/migration/manager_test.go # store/v2/proof/commit_info.go # store/v2/proof/commit_info_test.go # store/v2/root/factory.go # store/v2/root/factory_test.go # store/v2/root/store.go # tests/systemtests/bankv2_test.go
- Loading branch information
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
syntax = "proto3"; | ||
package cosmos.store.v2; | ||
|
||
import "gogoproto/gogo.proto"; | ||
import "google/protobuf/timestamp.proto"; | ||
|
||
option go_package = "cosmossdk.io/store/v2/proof"; | ||
|
||
// CommitInfo defines commit information used by the multi-store when committing | ||
// a version/height. | ||
message CommitInfo { | ||
int64 version = 1; | ||
repeated StoreInfo store_infos = 2; | ||
google.protobuf.Timestamp timestamp = 3 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; | ||
bytes commit_hash = 4; | ||
} | ||
|
||
// StoreInfo defines store-specific commit information. It contains a reference | ||
// between a store name and the commit ID. | ||
// | ||
message StoreInfo { | ||
string name = 1; | ||
CommitID commit_id = 2; | ||
string structure = 3; | ||
} | ||
|
||
// CommitID defines the commitment information when a specific store is | ||
// committed. | ||
message CommitID { | ||
option (gogoproto.goproto_stringer) = false; | ||
|
||
int64 version = 1; | ||
bytes hash = 2; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,251 @@ | ||
package serverv2 | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
|
||
"github.com/pelletier/go-toml/v2" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/pflag" | ||
|
||
"cosmossdk.io/core/transaction" | ||
"cosmossdk.io/log" | ||
) | ||
|
||
// ServerComponent is a server component that can be started and stopped. | ||
type ServerComponent[T transaction.Tx] interface { | ||
// Name returns the name of the server component. | ||
Name() string | ||
|
||
// Start starts the server component. | ||
Start(context.Context) error | ||
// Stop stops the server component. | ||
// Once Stop has been called on a server component, it may not be reused. | ||
Stop(context.Context) error | ||
} | ||
|
||
// HasStartFlags is a server component that has start flags. | ||
type HasStartFlags interface { | ||
// StartCmdFlags returns server start flags. | ||
// Those flags should be prefixed with the server name. | ||
// They are then merged with the server config in one viper instance. | ||
StartCmdFlags() *pflag.FlagSet | ||
} | ||
|
||
// HasConfig is a server component that has a config. | ||
type HasConfig interface { | ||
Config() any | ||
} | ||
|
||
// ConfigWriter is a server component that can write its config to a file. | ||
type ConfigWriter interface { | ||
WriteConfig(path string) error | ||
} | ||
|
||
// HasCLICommands is a server component that has CLI commands. | ||
type HasCLICommands interface { | ||
CLICommands() CLIConfig | ||
} | ||
|
||
// CLIConfig defines the CLI configuration for a component server. | ||
type CLIConfig struct { | ||
// Commands defines the main command of a server component. | ||
Commands []*cobra.Command | ||
// Queries defines the query commands of a server component. | ||
// Those commands are meant to be added in the root query command. | ||
Queries []*cobra.Command | ||
// Txs defines the tx commands of a server component. | ||
// Those commands are meant to be added in the root tx command. | ||
Txs []*cobra.Command | ||
} | ||
|
||
const ( | ||
serverName = "server" | ||
) | ||
|
||
var _ ServerComponent[transaction.Tx] = (*Server[transaction.Tx])(nil) | ||
|
||
// Server is the top-level server component which contains all other server components. | ||
type Server[T transaction.Tx] struct { | ||
components []ServerComponent[T] | ||
config ServerConfig | ||
Check failure on line 75 in server/v2/server.go
|
||
} | ||
|
||
func NewServer[T transaction.Tx]( | ||
config ServerConfig, | ||
Check failure on line 79 in server/v2/server.go
|
||
components ...ServerComponent[T], | ||
) *Server[T] { | ||
return &Server[T]{ | ||
config: config, | ||
components: components, | ||
} | ||
} | ||
|
||
func (s *Server[T]) Name() string { | ||
return serverName | ||
} | ||
|
||
// Start starts all components concurrently. | ||
func (s *Server[T]) Start(ctx context.Context) error { | ||
logger := GetLoggerFromContext(ctx).With(log.ModuleKey, s.Name()) | ||
Check failure on line 94 in server/v2/server.go
|
||
logger.Info("starting servers...") | ||
|
||
resCh := make(chan error, len(s.components)) | ||
for _, mod := range s.components { | ||
go func() { | ||
resCh <- mod.Start(ctx) | ||
}() | ||
} | ||
|
||
for i := 0; i < len(s.components); i++ { | ||
select { | ||
case err := <-resCh: | ||
if err != nil { | ||
return fmt.Errorf("failed to start servers: %w", err) | ||
} | ||
case <-ctx.Done(): | ||
return nil | ||
} | ||
} | ||
|
||
<-ctx.Done() | ||
|
||
return nil | ||
} | ||
|
||
// Stop stops all server components synchronously. | ||
func (s *Server[T]) Stop(ctx context.Context) error { | ||
logger := GetLoggerFromContext(ctx).With(log.ModuleKey, s.Name()) | ||
Check failure on line 122 in server/v2/server.go
|
||
logger.Info("stopping servers...") | ||
|
||
var err error | ||
for _, mod := range s.components { | ||
err = errors.Join(err, mod.Stop(ctx)) | ||
} | ||
|
||
return err | ||
} | ||
|
||
// CLICommands returns all CLI commands of all components. | ||
func (s *Server[T]) CLICommands() CLIConfig { | ||
compart := func(name string, cmds ...*cobra.Command) *cobra.Command { | ||
if len(cmds) == 1 && strings.HasPrefix(cmds[0].Use, name) { | ||
return cmds[0] | ||
} | ||
|
||
subCmd := &cobra.Command{ | ||
Use: name, | ||
Short: fmt.Sprintf("Commands from the %s server component", name), | ||
} | ||
subCmd.AddCommand(cmds...) | ||
|
||
return subCmd | ||
} | ||
|
||
commands := CLIConfig{} | ||
for _, mod := range s.components { | ||
if climod, ok := mod.(HasCLICommands); ok { | ||
srvCmd := climod.CLICommands() | ||
|
||
if len(srvCmd.Commands) > 0 { | ||
commands.Commands = append(commands.Commands, compart(mod.Name(), srvCmd.Commands...)) | ||
} | ||
|
||
if len(srvCmd.Txs) > 0 { | ||
commands.Txs = append(commands.Txs, compart(mod.Name(), srvCmd.Txs...)) | ||
} | ||
|
||
if len(srvCmd.Queries) > 0 { | ||
commands.Queries = append(commands.Queries, compart(mod.Name(), srvCmd.Queries...)) | ||
} | ||
} | ||
} | ||
|
||
return commands | ||
} | ||
|
||
// Config returns config of the server component | ||
func (s *Server[T]) Config() ServerConfig { | ||
Check failure on line 172 in server/v2/server.go
|
||
return s.config | ||
} | ||
|
||
// Configs returns all configs of all server components. | ||
func (s *Server[T]) Configs() map[string]any { | ||
cfgs := make(map[string]any) | ||
|
||
// add server component config | ||
cfgs[s.Name()] = s.config | ||
|
||
// add other components' config | ||
for _, mod := range s.components { | ||
if configmod, ok := mod.(HasConfig); ok { | ||
cfg := configmod.Config() | ||
cfgs[mod.Name()] = cfg | ||
} | ||
} | ||
|
||
return cfgs | ||
} | ||
|
||
func (s *Server[T]) StartCmdFlags() *pflag.FlagSet { | ||
flags := pflag.NewFlagSet(s.Name(), pflag.ExitOnError) | ||
flags.String(FlagMinGasPrices, "", "Minimum gas prices to accept for transactions; Any fee in a tx must meet this minimum (e.g. 0.01photino;0.0001stake)") | ||
Check failure on line 196 in server/v2/server.go
|
||
flags.String(FlagCPUProfiling, "", "Enable CPU profiling and write to the specified file") | ||
Check failure on line 197 in server/v2/server.go
|
||
flags.IntSlice(FlagUnsafeSkipUpgrades, []int{}, "Skip a set of upgrade heights to continue the old binary") | ||
Check failure on line 198 in server/v2/server.go
|
||
|
||
return flags | ||
} | ||
|
||
// WriteConfig writes the config to the given path. | ||
// Note: it does not use viper.WriteConfigAs because we do not want to store flag values in the config. | ||
func (s *Server[T]) WriteConfig(configPath string) error { | ||
cfgs := s.Configs() | ||
b, err := toml.Marshal(cfgs) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if _, err := os.Stat(configPath); os.IsNotExist(err) { | ||
if err := os.MkdirAll(configPath, os.ModePerm); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
if err := os.WriteFile(filepath.Join(configPath, "app.toml"), b, 0o600); err != nil { | ||
return fmt.Errorf("failed to write config: %w", err) | ||
} | ||
|
||
for _, component := range s.components { | ||
// undocumented interface to write the component default config in another file than app.toml | ||
// it is used by cometbft for backward compatibility | ||
// it should not be used by other components | ||
if mod, ok := component.(interface{ WriteCustomConfigAt(string) error }); ok { | ||
if err := mod.WriteCustomConfigAt(configPath); err != nil { | ||
return err | ||
} | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// StartFlags returns all flags of all server components. | ||
func (s *Server[T]) StartFlags() []*pflag.FlagSet { | ||
flags := []*pflag.FlagSet{} | ||
|
||
// add server component flags | ||
flags = append(flags, s.StartCmdFlags()) | ||
|
||
// add other components' start cmd flags | ||
for _, mod := range s.components { | ||
if startmod, ok := mod.(HasStartFlags); ok { | ||
flags = append(flags, startmod.StartCmdFlags()) | ||
} | ||
} | ||
|
||
return flags | ||
} |