From b49aa3d79ffd4c1b85a2b635f1654740da6ce230 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Tue, 8 Oct 2024 21:21:19 +0200 Subject: [PATCH] updates --- runtime/v2/app.go | 103 --------- runtime/v2/builder.go | 223 ------------------- runtime/v2/module.go | 254 ---------------------- runtime/v2/store.go | 155 -------------- server/v2/cometbft/go.mod | 16 +- server/v2/cometbft/go.sum | 32 +-- server/v2/commands.go | 213 ------------------- server/v2/config_test.go | 48 ----- server/v2/server.go | 260 ----------------------- server/v2/server_test.go | 121 ----------- server/v2/store/server.go | 100 --------- server/v2/store/snapshot.go | 412 ------------------------------------ server/v2/types.go | 20 -- simapp/v2/go.mod | 18 +- simapp/v2/go.sum | 36 ++-- store/v2/root/builder.go | 95 --------- store/v2/root/config.go | 14 -- store/v2/root/factory.go | 181 ---------------- store/v2/store.go | 112 ---------- 19 files changed, 51 insertions(+), 2362 deletions(-) delete mode 100644 runtime/v2/app.go delete mode 100644 runtime/v2/builder.go delete mode 100644 runtime/v2/module.go delete mode 100644 runtime/v2/store.go delete mode 100644 server/v2/commands.go delete mode 100644 server/v2/config_test.go delete mode 100644 server/v2/server.go delete mode 100644 server/v2/server_test.go delete mode 100644 server/v2/store/server.go delete mode 100644 server/v2/store/snapshot.go delete mode 100644 server/v2/types.go delete mode 100644 store/v2/root/builder.go delete mode 100644 store/v2/root/config.go delete mode 100644 store/v2/root/factory.go delete mode 100644 store/v2/store.go diff --git a/runtime/v2/app.go b/runtime/v2/app.go deleted file mode 100644 index f62795f53f3c..000000000000 --- a/runtime/v2/app.go +++ /dev/null @@ -1,103 +0,0 @@ -package runtime - -import ( - "encoding/json" - - runtimev2 "cosmossdk.io/api/cosmos/app/runtime/v2" - appmodulev2 "cosmossdk.io/core/appmodule/v2" - "cosmossdk.io/core/registry" - "cosmossdk.io/core/transaction" - "cosmossdk.io/log" - "cosmossdk.io/server/v2/appmanager" - "cosmossdk.io/server/v2/stf" -) - -// App is a wrapper around AppManager and ModuleManager that can be used in hybrid -// app.go/app config scenarios or directly as a servertypes.Application instance. -// To get an instance of *App, *AppBuilder must be requested as a dependency -// in a container which declares the runtime module and the AppBuilder.Build() -// method must be called. -// -// App can be used to create a hybrid app.go setup where some configuration is -// done declaratively with an app config and the rest of it is done the old way. -// See simapp/app_v2.go for an example of this setup. -type App[T transaction.Tx] struct { - *appmanager.AppManager[T] - - // app manager dependencies - stf *stf.STF[T] - msgRouterBuilder *stf.MsgRouterBuilder - queryRouterBuilder *stf.MsgRouterBuilder - db Store - - // app configuration - logger log.Logger - config *runtimev2.Module - - interfaceRegistrar registry.InterfaceRegistrar - amino registry.AminoRegistrar - moduleManager *MM[T] - - // QueryHandlers defines the query handlers - QueryHandlers map[string]appmodulev2.Handler - - storeLoader StoreLoader -} - -// Name returns the app name. -func (a *App[T]) Name() string { - return a.config.AppName -} - -// Logger returns the app logger. -func (a *App[T]) Logger() log.Logger { - return a.logger -} - -// ModuleManager returns the module manager. -func (a *App[T]) ModuleManager() *MM[T] { - return a.moduleManager -} - -// DefaultGenesis returns a default genesis from the registered modules. -func (a *App[T]) DefaultGenesis() map[string]json.RawMessage { - return a.moduleManager.DefaultGenesis() -} - -// SetStoreLoader sets the store loader. -func (a *App[T]) SetStoreLoader(loader StoreLoader) { - a.storeLoader = loader -} - -// LoadLatest loads the latest version. -func (a *App[T]) LoadLatest() error { - return a.storeLoader(a.db) -} - -// LoadHeight loads a particular height -func (a *App[T]) LoadHeight(height uint64) error { - return a.db.LoadVersion(height) -} - -// LoadLatestHeight loads the latest height. -func (a *App[T]) LoadLatestHeight() (uint64, error) { - return a.db.GetLatestVersion() -} - -// Close is called in start cmd to gracefully cleanup resources. -func (a *App[T]) Close() error { - return nil -} - -// GetStore returns the app store. -func (a *App[T]) GetStore() Store { - return a.db -} - -func (a *App[T]) GetAppManager() *appmanager.AppManager[T] { - return a.AppManager -} - -func (a *App[T]) GetQueryHandlers() map[string]appmodulev2.Handler { - return a.QueryHandlers -} diff --git a/runtime/v2/builder.go b/runtime/v2/builder.go deleted file mode 100644 index e74d6ff34f22..000000000000 --- a/runtime/v2/builder.go +++ /dev/null @@ -1,223 +0,0 @@ -package runtime - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "io" - - "cosmossdk.io/core/appmodule" - appmodulev2 "cosmossdk.io/core/appmodule/v2" - "cosmossdk.io/core/store" - "cosmossdk.io/core/transaction" - "cosmossdk.io/runtime/v2/services" - "cosmossdk.io/server/v2/appmanager" - "cosmossdk.io/server/v2/stf" - "cosmossdk.io/server/v2/stf/branch" - "cosmossdk.io/store/v2/root" -) - -// AppBuilder is a type that is injected into a container by the runtime/v2 module -// (as *AppBuilder) which can be used to create an app which is compatible with -// the existing app.go initialization conventions. -type AppBuilder[T transaction.Tx] struct { - app *App[T] - storeBuilder root.Builder - - // the following fields are used to overwrite the default - branch func(state store.ReaderMap) store.WriterMap - txValidator func(ctx context.Context, tx T) error - postTxExec func(ctx context.Context, tx T, success bool) error -} - -// DefaultGenesis returns a default genesis from the registered AppModule's. -func (a *AppBuilder[T]) DefaultGenesis() map[string]json.RawMessage { - return a.app.moduleManager.DefaultGenesis() -} - -// RegisterModules registers the provided modules with the module manager. -// This is the primary hook for integrating with modules which are not registered using the app config. -func (a *AppBuilder[T]) RegisterModules(modules map[string]appmodulev2.AppModule) error { - for name, appModule := range modules { - // if a (legacy) module implements the HasName interface, check that the name matches - if mod, ok := appModule.(interface{ Name() string }); ok { - if name != mod.Name() { - a.app.logger.Warn(fmt.Sprintf("module name %q does not match name returned by HasName: %q", name, mod.Name())) - } - } - - if _, ok := a.app.moduleManager.modules[name]; ok { - return fmt.Errorf("module named %q already exists", name) - } - a.app.moduleManager.modules[name] = appModule - - if mod, ok := appModule.(appmodulev2.HasRegisterInterfaces); ok { - mod.RegisterInterfaces(a.app.interfaceRegistrar) - } - - if mod, ok := appModule.(appmodule.HasAminoCodec); ok { - mod.RegisterLegacyAminoCodec(a.app.amino) - } - } - - return nil -} - -// Build builds an *App instance. -func (a *AppBuilder[T]) Build(opts ...AppBuilderOption[T]) (*App[T], error) { - for _, opt := range opts { - opt(a) - } - - // default branch - if a.branch == nil { - a.branch = branch.DefaultNewWriterMap - } - - // default tx validator - if a.txValidator == nil { - a.txValidator = a.app.moduleManager.TxValidators() - } - - // default post tx exec - if a.postTxExec == nil { - a.postTxExec = func(ctx context.Context, tx T, success bool) error { - return nil - } - } - - a.app.db = a.storeBuilder.Get() - if a.app.db == nil { - return nil, fmt.Errorf("storeBuilder did not return a db") - } - - if err := a.app.moduleManager.RegisterServices(a.app); err != nil { - return nil, err - } - - endBlocker, valUpdate := a.app.moduleManager.EndBlock() - - stf, err := stf.NewSTF[T]( - a.app.logger.With("module", "stf"), - a.app.msgRouterBuilder, - a.app.queryRouterBuilder, - a.app.moduleManager.PreBlocker(), - a.app.moduleManager.BeginBlock(), - endBlocker, - a.txValidator, - valUpdate, - a.postTxExec, - a.branch, - ) - if err != nil { - return nil, fmt.Errorf("failed to create STF: %w", err) - } - a.app.stf = stf - - appManagerBuilder := appmanager.Builder[T]{ - STF: a.app.stf, - DB: a.app.db, - ValidateTxGasLimit: a.app.config.GasConfig.ValidateTxGasLimit, - QueryGasLimit: a.app.config.GasConfig.QueryGasLimit, - SimulationGasLimit: a.app.config.GasConfig.SimulationGasLimit, - InitGenesis: func( - ctx context.Context, - src io.Reader, - txHandler func(json.RawMessage) error, - ) (store.WriterMap, error) { - // this implementation assumes that the state is a JSON object - bz, err := io.ReadAll(src) - if err != nil { - return nil, fmt.Errorf("failed to read import state: %w", err) - } - var genesisJSON map[string]json.RawMessage - if err = json.Unmarshal(bz, &genesisJSON); err != nil { - return nil, err - } - - v, zeroState, err := a.app.db.StateLatest() - if err != nil { - return nil, fmt.Errorf("unable to get latest state: %w", err) - } - if v != 0 { // TODO: genesis state may be > 0, we need to set version on store - return nil, errors.New("cannot init genesis on non-zero state") - } - genesisCtx := services.NewGenesisContext(a.branch(zeroState)) - genesisState, err := genesisCtx.Run(ctx, func(ctx context.Context) error { - err = a.app.moduleManager.InitGenesisJSON(ctx, genesisJSON, txHandler) - if err != nil { - return fmt.Errorf("failed to init genesis: %w", err) - } - return nil - }) - - return genesisState, err - }, - ExportGenesis: func(ctx context.Context, version uint64) ([]byte, error) { - state, err := a.app.db.StateAt(version) - if err != nil { - return nil, fmt.Errorf("unable to get state at given version: %w", err) - } - - genesisJson, err := a.app.moduleManager.ExportGenesisForModules( - ctx, - func() store.WriterMap { - return a.branch(state) - }, - ) - if err != nil { - return nil, fmt.Errorf("failed to export genesis: %w", err) - } - - bz, err := json.Marshal(genesisJson) - if err != nil { - return nil, fmt.Errorf("failed to marshal genesis: %w", err) - } - - return bz, nil - }, - } - - appManager, err := appManagerBuilder.Build() - if err != nil { - return nil, fmt.Errorf("failed to build app manager: %w", err) - } - a.app.AppManager = appManager - - return a.app, nil -} - -// AppBuilderOption is a function that can be passed to AppBuilder.Build to customize the resulting app. -type AppBuilderOption[T transaction.Tx] func(*AppBuilder[T]) - -// AppBuilderWithBranch sets a custom branch implementation for the app. -func AppBuilderWithBranch[T transaction.Tx](branch func(state store.ReaderMap) store.WriterMap) AppBuilderOption[T] { - return func(a *AppBuilder[T]) { - a.branch = branch - } -} - -// AppBuilderWithTxValidator sets the tx validator for the app. -// It overrides all default tx validators defined by modules. -func AppBuilderWithTxValidator[T transaction.Tx]( - txValidators func( - ctx context.Context, tx T, - ) error, -) AppBuilderOption[T] { - return func(a *AppBuilder[T]) { - a.txValidator = txValidators - } -} - -// AppBuilderWithPostTxExec sets logic that will be executed after each transaction. -// When not provided, a no-op function will be used. -func AppBuilderWithPostTxExec[T transaction.Tx]( - postTxExec func( - ctx context.Context, tx T, success bool, - ) error, -) AppBuilderOption[T] { - return func(a *AppBuilder[T]) { - a.postTxExec = postTxExec - } -} diff --git a/runtime/v2/module.go b/runtime/v2/module.go deleted file mode 100644 index 11cd7037fff3..000000000000 --- a/runtime/v2/module.go +++ /dev/null @@ -1,254 +0,0 @@ -package runtime - -import ( - "fmt" - "os" - "slices" - - "github.com/cosmos/gogoproto/proto" - "google.golang.org/grpc" - "google.golang.org/protobuf/reflect/protodesc" - "google.golang.org/protobuf/reflect/protoregistry" - - runtimev2 "cosmossdk.io/api/cosmos/app/runtime/v2" - appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1" - autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" - reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" - appmodulev2 "cosmossdk.io/core/appmodule/v2" - "cosmossdk.io/core/comet" - "cosmossdk.io/core/event" - "cosmossdk.io/core/header" - "cosmossdk.io/core/registry" - "cosmossdk.io/core/store" - "cosmossdk.io/core/transaction" - "cosmossdk.io/depinject" - "cosmossdk.io/depinject/appconfig" - "cosmossdk.io/log" - "cosmossdk.io/runtime/v2/services" - "cosmossdk.io/server/v2/stf" - "cosmossdk.io/store/v2/root" -) - -var ( - _ appmodulev2.AppModule = appModule[transaction.Tx]{} - _ hasServicesV1 = appModule[transaction.Tx]{} -) - -type appModule[T transaction.Tx] struct { - app *App[T] -} - -func (m appModule[T]) IsOnePerModuleType() {} -func (m appModule[T]) IsAppModule() {} - -func (m appModule[T]) RegisterServices(registrar grpc.ServiceRegistrar) error { - autoCliQueryService, err := services.NewAutoCLIQueryService(m.app.moduleManager.modules) - if err != nil { - return err - } - - autocliv1.RegisterQueryServer(registrar, autoCliQueryService) - - reflectionSvc, err := services.NewReflectionService() - if err != nil { - return err - } - reflectionv1.RegisterReflectionServiceServer(registrar, reflectionSvc) - - return nil -} - -func (m appModule[T]) AutoCLIOptions() *autocliv1.ModuleOptions { - return &autocliv1.ModuleOptions{ - Query: &autocliv1.ServiceCommandDescriptor{ - Service: appv1alpha1.Query_ServiceDesc.ServiceName, - RpcCommandOptions: []*autocliv1.RpcCommandOptions{ - { - RpcMethod: "Config", - Short: "Query the current app config", - }, - }, - SubCommands: map[string]*autocliv1.ServiceCommandDescriptor{ - "autocli": { - Service: autocliv1.Query_ServiceDesc.ServiceName, - RpcCommandOptions: []*autocliv1.RpcCommandOptions{ - { - RpcMethod: "AppOptions", - Short: "Query the custom autocli options", - }, - }, - }, - "reflection": { - Service: reflectionv1.ReflectionService_ServiceDesc.ServiceName, - RpcCommandOptions: []*autocliv1.RpcCommandOptions{ - { - RpcMethod: "FileDescriptors", - Short: "Query the app's protobuf file descriptors", - }, - }, - }, - }, - }, - } -} - -func init() { - appconfig.Register(&runtimev2.Module{}, - appconfig.Provide( - ProvideAppBuilder[transaction.Tx], - ProvideModuleManager[transaction.Tx], - ProvideEnvironment, - ProvideKVService, - ), - appconfig.Invoke(SetupAppBuilder), - ) -} - -func ProvideAppBuilder[T transaction.Tx]( - interfaceRegistrar registry.InterfaceRegistrar, - amino registry.AminoRegistrar, - storeBuilder root.Builder, -) ( - *AppBuilder[T], - *stf.MsgRouterBuilder, - appmodulev2.AppModule, - protodesc.Resolver, - protoregistry.MessageTypeResolver, -) { - protoFiles := proto.HybridResolver - protoTypes := protoregistry.GlobalTypes - - // At startup, check that all proto annotations are correct. - if err := validateProtoAnnotations(protoFiles); err != nil { - // Once we switch to using protoreflect-based ante handlers, we might - // want to panic here instead of logging a warning. - _, _ = fmt.Fprintln(os.Stderr, err.Error()) - } - - msgRouterBuilder := stf.NewMsgRouterBuilder() - app := &App[T]{ - interfaceRegistrar: interfaceRegistrar, - amino: amino, - msgRouterBuilder: msgRouterBuilder, - queryRouterBuilder: stf.NewMsgRouterBuilder(), // TODO dedicated query router - QueryHandlers: map[string]appmodulev2.Handler{}, - storeLoader: DefaultStoreLoader, - } - appBuilder := &AppBuilder[T]{app: app, storeBuilder: storeBuilder} - - return appBuilder, msgRouterBuilder, appModule[T]{app}, protoFiles, protoTypes -} - -type AppInputs struct { - depinject.In - - Config *runtimev2.Module - AppBuilder *AppBuilder[transaction.Tx] - ModuleManager *MM[transaction.Tx] - InterfaceRegistrar registry.InterfaceRegistrar - LegacyAmino registry.AminoRegistrar - Logger log.Logger - StoreBuilder root.Builder -} - -func SetupAppBuilder(inputs AppInputs) { - app := inputs.AppBuilder.app - app.config = inputs.Config - app.logger = inputs.Logger - app.moduleManager = inputs.ModuleManager - app.moduleManager.RegisterInterfaces(inputs.InterfaceRegistrar) - app.moduleManager.RegisterLegacyAminoCodec(inputs.LegacyAmino) - // STF requires some state to run - inputs.StoreBuilder.RegisterKey("stf") -} - -func ProvideModuleManager[T transaction.Tx]( - logger log.Logger, - config *runtimev2.Module, - modules map[string]appmodulev2.AppModule, -) *MM[T] { - return NewModuleManager[T](logger, config, modules) -} - -func ProvideKVService( - config *runtimev2.Module, - key depinject.ModuleKey, - kvFactory store.KVStoreServiceFactory, - storeBuilder root.Builder, -) (store.KVStoreService, store.MemoryStoreService) { - // skips modules that have no store - if slices.Contains(config.SkipStoreKeys, key.Name()) { - return &failingStoreService{}, &failingStoreService{} - } - var kvStoreKey string - override := storeKeyOverride(config, key.Name()) - if override != nil { - kvStoreKey = override.KvStoreKey - } else { - kvStoreKey = key.Name() - } - - storeBuilder.RegisterKey(kvStoreKey) - return kvFactory([]byte(kvStoreKey)), stf.NewMemoryStoreService([]byte(fmt.Sprintf("memory:%s", kvStoreKey))) -} - -func storeKeyOverride(config *runtimev2.Module, moduleName string) *runtimev2.StoreKeyConfig { - for _, cfg := range config.OverrideStoreKeys { - if cfg.ModuleName == moduleName { - return cfg - } - } - return nil -} - -// ProvideEnvironment provides the environment for keeper modules, while maintaining backward compatibility and provide services directly as well. -func ProvideEnvironment( - logger log.Logger, - key depinject.ModuleKey, - kvService store.KVStoreService, - memKvService store.MemoryStoreService, - headerService header.Service, - eventService event.Service, -) appmodulev2.Environment { - return appmodulev2.Environment{ - Logger: logger, - BranchService: stf.BranchService{}, - EventService: eventService, - GasService: stf.NewGasMeterService(), - HeaderService: headerService, - QueryRouterService: stf.NewQueryRouterService(), - MsgRouterService: stf.NewMsgRouterService([]byte(key.Name())), - TransactionService: services.NewContextAwareTransactionService(), - KVStoreService: kvService, - MemStoreService: memKvService, - } -} - -// DefaultServiceBindings provides default services for the following service interfaces: -// - store.KVStoreServiceFactory -// - header.Service -// - comet.Service -// - event.Service -// -// They are all required. For most use cases these default services bindings should be sufficient. -// Power users (or tests) may wish to provide their own services bindings, in which case they must -// supply implementations for each of the above interfaces. -func DefaultServiceBindings() depinject.Config { - var ( - kvServiceFactory store.KVStoreServiceFactory = func(actor []byte) store.KVStoreService { - return services.NewGenesisKVService( - actor, - stf.NewKVStoreService(actor), - ) - } - headerService header.Service = services.NewGenesisHeaderService(stf.HeaderService{}) - cometService comet.Service = &services.ContextAwareCometInfoService{} - eventService = stf.NewEventService() - ) - return depinject.Supply( - kvServiceFactory, - headerService, - cometService, - eventService, - ) -} diff --git a/runtime/v2/store.go b/runtime/v2/store.go deleted file mode 100644 index 7f7b2135c809..000000000000 --- a/runtime/v2/store.go +++ /dev/null @@ -1,155 +0,0 @@ -package runtime - -import ( - "errors" - "fmt" - "sync" - - "cosmossdk.io/core/store" - "cosmossdk.io/server/v2/stf" - storev2 "cosmossdk.io/store/v2" - "cosmossdk.io/store/v2/proof" - "cosmossdk.io/store/v2/root" -) - -var ( - storeBuilderSingleton root.Builder - storeBuilderSingletonOnce sync.Once -) - -// ProvideSingletonScopedStoreBuilder returns a store builder that is a singleton -// in the scope of the process lifetime. -func ProvideSingletonScopedStoreBuilder() root.Builder { - storeBuilderSingletonOnce.Do(func() { - storeBuilderSingleton = root.NewBuilder() - }) - return storeBuilderSingleton -} - -// ResetSingletonScopedStoreBuilder resets the singleton store builder. Applications -// should not ever need to call this, but it may be useful in tests. -func ResetSingletonScopedStoreBuilder() { - storeBuilderSingletonOnce = sync.Once{} -} - -// NewKVStoreService creates a new KVStoreService. -// This wrapper is kept for backwards compatibility. -// When migrating from runtime to runtime/v2, use runtimev2.NewKVStoreService(storeKey.Name()) instead of runtime.NewKVStoreService(storeKey). -func NewKVStoreService(storeKey string) store.KVStoreService { - return stf.NewKVStoreService([]byte(storeKey)) -} - -type Store interface { - // GetLatestVersion returns the latest version that consensus has been made on - GetLatestVersion() (uint64, error) - // StateLatest returns a readonly view over the latest - // committed state of the store. Alongside the version - // associated with it. - StateLatest() (uint64, store.ReaderMap, error) - - // StateAt returns a readonly view over the provided - // version. Must error when the version does not exist. - StateAt(version uint64) (store.ReaderMap, error) - - // SetInitialVersion sets the initial version of the store. - SetInitialVersion(uint64) error - - // WorkingHash writes the provided changeset to the state and returns - // the working hash of the state. - WorkingHash(changeset *store.Changeset) (store.Hash, error) - - // Commit commits the provided changeset and returns the new state root of the state. - Commit(changeset *store.Changeset) (store.Hash, error) - - // Query is a key/value query directly to the underlying database. This skips the appmanager - Query(storeKey []byte, version uint64, key []byte, prove bool) (storev2.QueryResult, error) - - // GetStateStorage returns the SS backend. - GetStateStorage() storev2.VersionedDatabase - - // GetStateCommitment returns the SC backend. - GetStateCommitment() storev2.Committer - - // LoadVersion loads the RootStore to the given version. - LoadVersion(version uint64) error - - // LoadLatestVersion behaves identically to LoadVersion except it loads the - // latest version implicitly. - LoadLatestVersion() error - - // LastCommitID returns the latest commit ID - LastCommitID() (proof.CommitID, error) -} - -// StoreLoader allows for custom loading of the store, this is useful when upgrading the store from a previous version -type StoreLoader func(store Store) error - -// DefaultStoreLoader just calls LoadLatestVersion on the store -func DefaultStoreLoader(store Store) error { - return store.LoadLatestVersion() -} - -// UpgradeStoreLoader upgrades the store if the upgrade height matches the current version, it is used as a replacement -// for the DefaultStoreLoader when there are store upgrades -func UpgradeStoreLoader(upgradeHeight int64, storeUpgrades *store.StoreUpgrades) StoreLoader { - // sanity checks on store upgrades - if err := checkStoreUpgrade(storeUpgrades); err != nil { - panic(err) - } - - return func(store Store) error { - latestVersion, err := store.GetLatestVersion() - if err != nil { - return err - } - - if uint64(upgradeHeight) == latestVersion+1 { - if len(storeUpgrades.Deleted) > 0 || len(storeUpgrades.Added) > 0 { - if upgrader, ok := store.(storev2.UpgradeableStore); ok { - return upgrader.LoadVersionAndUpgrade(latestVersion, storeUpgrades) - } - - return fmt.Errorf("store does not support upgrades") - } - } - - return DefaultStoreLoader(store) - } -} - -// checkStoreUpgrade performs sanity checks on the store upgrades -func checkStoreUpgrade(storeUpgrades *store.StoreUpgrades) error { - if storeUpgrades == nil { - return errors.New("store upgrades cannot be nil") - } - - // check for duplicates - addedFilter := make(map[string]struct{}) - deletedFilter := make(map[string]struct{}) - - for _, key := range storeUpgrades.Added { - if _, ok := addedFilter[key]; ok { - return fmt.Errorf("store upgrade has duplicate key %s in added", key) - } - addedFilter[key] = struct{}{} - } - for _, key := range storeUpgrades.Deleted { - if _, ok := deletedFilter[key]; ok { - return fmt.Errorf("store upgrade has duplicate key %s in deleted", key) - } - deletedFilter[key] = struct{}{} - } - - for _, key := range storeUpgrades.Added { - if _, ok := deletedFilter[key]; ok { - return fmt.Errorf("store upgrade has key %s in both added and deleted", key) - } - } - for _, key := range storeUpgrades.Deleted { - if _, ok := addedFilter[key]; ok { - return fmt.Errorf("store upgrade has key %s in both added and deleted", key) - } - } - - return nil -} diff --git a/server/v2/cometbft/go.mod b/server/v2/cometbft/go.mod index 7b0e5d5000fc..2ed1f1c365a7 100644 --- a/server/v2/cometbft/go.mod +++ b/server/v2/cometbft/go.mod @@ -21,9 +21,9 @@ require ( cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5 cosmossdk.io/log v1.4.1 - cosmossdk.io/server/v2 v2.0.0-20241003112707-72f771638528 // main - cosmossdk.io/server/v2/appmanager v0.0.0-20241003101412-c5889a418ae2 // main - cosmossdk.io/server/v2/stf v0.0.0-20241003101412-c5889a418ae2 // main + cosmossdk.io/server/v2 v2.0.0-20241008175849-325728a9fd6c // main + cosmossdk.io/server/v2/appmanager v0.0.0-20241008175849-325728a9fd6c // main + cosmossdk.io/server/v2/stf v0.0.0-20241008175849-325728a9fd6c // main cosmossdk.io/store/v2 v2.0.0-20240916221850-7856d226038c // main cosmossdk.io/x/consensus v0.0.0-00010101000000-000000000000 github.com/cometbft/cometbft v1.0.0-rc1.0.20240908111210-ab0be101882f @@ -34,7 +34,7 @@ require ( github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 - google.golang.org/protobuf v1.34.2 + google.golang.org/protobuf v1.35.1 sigs.k8s.io/yaml v1.4.0 ) @@ -166,14 +166,14 @@ require ( go.etcd.io/bbolt v1.4.0-alpha.1 // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.27.0 // indirect + golang.org/x/crypto v0.28.0 // indirect golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.29.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/term v0.24.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/term v0.25.0 // indirect + golang.org/x/text v0.19.0 // indirect golang.org/x/tools v0.25.0 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect diff --git a/server/v2/cometbft/go.sum b/server/v2/cometbft/go.sum index fee0040b5c2c..32de404548ce 100644 --- a/server/v2/cometbft/go.sum +++ b/server/v2/cometbft/go.sum @@ -24,12 +24,12 @@ cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= -cosmossdk.io/server/v2 v2.0.0-20241003112707-72f771638528 h1:6Ht6Yg36nsbtOjdxj+fvUk5o35Nkg9vA9WQC+oNs+sI= -cosmossdk.io/server/v2 v2.0.0-20241003112707-72f771638528/go.mod h1:zXQpdRRGLQjq17VxHiieHjA0xcU2ydgjR82XOgA6Cdc= -cosmossdk.io/server/v2/appmanager v0.0.0-20241003101412-c5889a418ae2 h1:8GOXwsEQbRtpQ/bzUEly4FCOqhBhgxFFDzBGkrPjBUs= -cosmossdk.io/server/v2/appmanager v0.0.0-20241003101412-c5889a418ae2/go.mod h1:/xDfniqVtn5nraiHkNJ4e6rYU0e83YAGsSjwmUA6H8k= -cosmossdk.io/server/v2/stf v0.0.0-20241003101412-c5889a418ae2 h1:G1kMEqy4OAO/BZD9ZJa2rVVxsYSPHzKrictiOAGPuoY= -cosmossdk.io/server/v2/stf v0.0.0-20241003101412-c5889a418ae2/go.mod h1:TFpf9xrlr88CPDVDq3pcpX88brCDo5qazFd+lBU67a0= +cosmossdk.io/server/v2 v2.0.0-20241008175849-325728a9fd6c h1:SobvpV3A/LPlmQ+mM6YrJHt7rRP6Cp7aVOB2ulwEBEc= +cosmossdk.io/server/v2 v2.0.0-20241008175849-325728a9fd6c/go.mod h1:GEldDSZX6StSNMIazVU6z1dm9cSq+FNMiOCJXmgBeZE= +cosmossdk.io/server/v2/appmanager v0.0.0-20241008175849-325728a9fd6c h1:MJCOTFyL7lPlMDUFvylEu/2zyFe7NcYe4eMaZowvzk4= +cosmossdk.io/server/v2/appmanager v0.0.0-20241008175849-325728a9fd6c/go.mod h1:/xDfniqVtn5nraiHkNJ4e6rYU0e83YAGsSjwmUA6H8k= +cosmossdk.io/server/v2/stf v0.0.0-20241008175849-325728a9fd6c h1:thOij3diZWxwfKaSJNS6S1SFX+fnOW93emnuu+WSHJY= +cosmossdk.io/server/v2/stf v0.0.0-20241008175849-325728a9fd6c/go.mod h1:MjuTMonZ319tZQX6CV2O5E/+F85KrkNUj5U5ObrrkWs= cosmossdk.io/store v1.0.0-rc.0.0.20240913190136-3bc707a5a214 h1:UUW0+2UgbDwQ452o2aw4DrVSWmowcad7DB7Vln+N94I= cosmossdk.io/store v1.0.0-rc.0.0.20240913190136-3bc707a5a214/go.mod h1:ct8HATr+s48YYTRXEyP3HF33v9qEVWHMxwOL8P/v4iQ= cosmossdk.io/store/v2 v2.0.0-20240916221850-7856d226038c h1:x0NX01A+QWckckb1hi9p8mYW4OXTYEzsohQK2qBtIHg= @@ -531,8 +531,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= @@ -611,19 +611,19 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -682,8 +682,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/server/v2/commands.go b/server/v2/commands.go deleted file mode 100644 index 0357fe180d93..000000000000 --- a/server/v2/commands.go +++ /dev/null @@ -1,213 +0,0 @@ -package serverv2 - -import ( - "context" - "errors" - "os" - "os/signal" - "path/filepath" - "strings" - "syscall" - - "github.com/spf13/cobra" - "github.com/spf13/viper" - - "cosmossdk.io/core/transaction" - "cosmossdk.io/log" -) - -// Execute executes the root command of an application. -// It handles adding core CLI flags, specifically the logging flags. -func Execute(rootCmd *cobra.Command, envPrefix, defaultHome string) error { - rootCmd.PersistentFlags().String(FlagLogLevel, "info", "The logging level (trace|debug|info|warn|error|fatal|panic|disabled or '*:,:')") - rootCmd.PersistentFlags().String(FlagLogFormat, "plain", "The logging format (json|plain)") - rootCmd.PersistentFlags().Bool(FlagLogNoColor, false, "Disable colored logs") - rootCmd.PersistentFlags().StringP(FlagHome, "", defaultHome, "directory for config and data") - - // update the global viper with the root command's configuration - viper.SetEnvPrefix(envPrefix) - viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_")) - viper.AutomaticEnv() - - return rootCmd.Execute() -} - -// AddCommands add the server commands to the root command -// It configures the config handling and the logger handling -func AddCommands[T transaction.Tx]( - rootCmd *cobra.Command, - newApp AppCreator[T], - logger log.Logger, - globalServerCfg ServerConfig, - components ...ServerComponent[T], -) error { - if len(components) == 0 { - return errors.New("no components provided") - } - - server := NewServer(logger, globalServerCfg, components...) - originalPersistentPreRunE := rootCmd.PersistentPreRunE - rootCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error { - // set the default command outputs - cmd.SetOut(cmd.OutOrStdout()) - cmd.SetErr(cmd.ErrOrStderr()) - - if err := configHandle(server, cmd); err != nil { - return err - } - - // call the original PersistentPreRun(E) if it exists - if rootCmd.PersistentPreRun != nil { - rootCmd.PersistentPreRun(cmd, args) - return nil - } - - return originalPersistentPreRunE(cmd, args) - } - - cmds := server.CLICommands() - startCmd := createStartCommand(server, newApp) - startCmd.SetContext(rootCmd.Context()) - cmds.Commands = append(cmds.Commands, startCmd) - rootCmd.AddCommand(cmds.Commands...) - - if len(cmds.Queries) > 0 { - if queryCmd := findSubCommand(rootCmd, "query"); queryCmd != nil { - queryCmd.AddCommand(cmds.Queries...) - } else { - queryCmd := topLevelCmd(rootCmd.Context(), "query", "Querying subcommands") - queryCmd.Aliases = []string{"q"} - queryCmd.AddCommand(cmds.Queries...) - rootCmd.AddCommand(queryCmd) - } - } - - if len(cmds.Txs) > 0 { - if txCmd := findSubCommand(rootCmd, "tx"); txCmd != nil { - txCmd.AddCommand(cmds.Txs...) - } else { - txCmd := topLevelCmd(rootCmd.Context(), "tx", "Transactions subcommands") - txCmd.AddCommand(cmds.Txs...) - rootCmd.AddCommand(txCmd) - } - } - - return nil -} - -// createStartCommand creates the start command for the application. -func createStartCommand[T transaction.Tx]( - server *Server[T], - newApp AppCreator[T], -) *cobra.Command { - flags := server.StartFlags() - - cmd := &cobra.Command{ - Use: "start", - Short: "Run the application", - RunE: func(cmd *cobra.Command, args []string) error { - v := GetViperFromCmd(cmd) - l := GetLoggerFromCmd(cmd) - if err := v.BindPFlags(cmd.Flags()); err != nil { - return err - } - - if err := server.Init(newApp(l, v), v.AllSettings(), l); err != nil { - return err - } - - ctx, cancelFn := context.WithCancel(cmd.Context()) - go func() { - sigCh := make(chan os.Signal, 1) - signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) - sig := <-sigCh - cancelFn() - cmd.Printf("caught %s signal\n", sig.String()) - - if err := server.Stop(ctx); err != nil { - cmd.PrintErrln("failed to stop servers:", err) - } - }() - - if err := server.Start(ctx); err != nil { - return err - } - - return nil - }, - } - - // add the start flags to the command - for _, startFlags := range flags { - cmd.Flags().AddFlagSet(startFlags) - } - - return cmd -} - -// configHandle writes the default config to the home directory if it does not exist and sets the server context -func configHandle[T transaction.Tx](s *Server[T], cmd *cobra.Command) error { - home, err := cmd.Flags().GetString(FlagHome) - if err != nil { - return err - } - - configDir := filepath.Join(home, "config") - - // we need to check app.toml as the config folder can already exist for the client.toml - if _, err := os.Stat(filepath.Join(configDir, "app.toml")); os.IsNotExist(err) { - if err = s.WriteConfig(configDir); err != nil { - return err - } - } - - v, err := ReadConfig(configDir) - if err != nil { - return err - } - - if err := v.BindPFlags(cmd.Flags()); err != nil { - return err - } - - log, err := NewLogger(v, cmd.OutOrStdout()) - if err != nil { - return err - } - - return SetCmdServerContext(cmd, v, log) -} - -// findSubCommand finds a sub-command of the provided command whose Use -// string is or begins with the provided subCmdName. -// It verifies the command's aliases as well. -func findSubCommand(cmd *cobra.Command, subCmdName string) *cobra.Command { - for _, subCmd := range cmd.Commands() { - use := subCmd.Use - if use == subCmdName || strings.HasPrefix(use, subCmdName+" ") { - return subCmd - } - - for _, alias := range subCmd.Aliases { - if alias == subCmdName || strings.HasPrefix(alias, subCmdName+" ") { - return subCmd - } - } - } - return nil -} - -// topLevelCmd creates a new top-level command with the provided name and -// description. The command will have DisableFlagParsing set to false and -// SuggestionsMinimumDistance set to 2. -func topLevelCmd(ctx context.Context, use, short string) *cobra.Command { - cmd := &cobra.Command{ - Use: use, - Short: short, - DisableFlagParsing: false, - SuggestionsMinimumDistance: 2, - } - cmd.SetContext(ctx) - - return cmd -} diff --git a/server/v2/config_test.go b/server/v2/config_test.go deleted file mode 100644 index 3ddd7893a001..000000000000 --- a/server/v2/config_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package serverv2_test - -import ( - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/require" - - serverv2 "cosmossdk.io/server/v2" - grpc "cosmossdk.io/server/v2/api/grpc" - store "cosmossdk.io/server/v2/store" - "cosmossdk.io/store/v2/root" -) - -func TestReadConfig(t *testing.T) { - currentDir, err := os.Getwd() - require.NoError(t, err) - configPath := filepath.Join(currentDir, "testdata") - - v, err := serverv2.ReadConfig(configPath) - require.NoError(t, err) - - require.Equal(t, v.GetString(grpc.FlagAddress), grpc.DefaultConfig().Address) - require.Equal(t, v.GetString(store.FlagAppDBBackend), root.DefaultConfig().AppDBBackend) -} - -func TestUnmarshalSubConfig(t *testing.T) { - currentDir, err := os.Getwd() - require.NoError(t, err) - configPath := filepath.Join(currentDir, "testdata") - - v, err := serverv2.ReadConfig(configPath) - require.NoError(t, err) - cfg := v.AllSettings() - - grpcConfig := grpc.DefaultConfig() - err = serverv2.UnmarshalSubConfig(cfg, "grpc", &grpcConfig) - require.NoError(t, err) - - require.True(t, grpc.DefaultConfig().Enable) - require.False(t, grpcConfig.Enable) - - storeConfig := root.Config{} - err = serverv2.UnmarshalSubConfig(cfg, "store", &storeConfig) - require.NoError(t, err) - require.Equal(t, *root.DefaultConfig(), storeConfig) -} diff --git a/server/v2/server.go b/server/v2/server.go deleted file mode 100644 index a628fbdf1000..000000000000 --- a/server/v2/server.go +++ /dev/null @@ -1,260 +0,0 @@ -package serverv2 - -import ( - "context" - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/pelletier/go-toml/v2" - "github.com/spf13/cobra" - "github.com/spf13/pflag" - "golang.org/x/sync/errgroup" - - "cosmossdk.io/core/transaction" - "cosmossdk.io/log" -) - -// ServerComponent is a server module that can be started and stopped. -type ServerComponent[T transaction.Tx] interface { - Name() string - - Start(context.Context) error - Stop(context.Context) error - Init(AppI[T], map[string]any, log.Logger) error -} - -// HasStartFlags is a server module 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 module that has a config. -type HasConfig interface { - Config() any -} - -// HasCLICommands is a server module that has CLI commands. -type HasCLICommands interface { - CLICommands() CLIConfig -} - -// CLIConfig defines the CLI configuration for a module server. -type CLIConfig struct { - // Commands defines the main command of a module server. - Commands []*cobra.Command - // Queries defines the query commands of a module server. - // Those commands are meant to be added in the root query command. - Queries []*cobra.Command - // Txs defines the tx commands of a module server. - // 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 { - logger log.Logger - components []ServerComponent[T] - config ServerConfig -} - -func NewServer[T transaction.Tx]( - logger log.Logger, - config ServerConfig, - components ...ServerComponent[T], -) *Server[T] { - return &Server[T]{ - logger: logger, - 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 { - s.logger.Info("starting servers...") - - g, ctx := errgroup.WithContext(ctx) - for _, mod := range s.components { - g.Go(func() error { - return mod.Start(ctx) - }) - } - - if err := g.Wait(); err != nil { - return fmt.Errorf("failed to start servers: %w", err) - } - - <-ctx.Done() - - return nil -} - -// Stop stops all components concurrently. -func (s *Server[T]) Stop(ctx context.Context) error { - s.logger.Info("stopping servers...") - - g, ctx := errgroup.WithContext(ctx) - for _, mod := range s.components { - g.Go(func() error { - return mod.Stop(ctx) - }) - } - - return g.Wait() -} - -// 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 { - 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)") - return flags -} - -// Init initializes all server components with the provided application, configuration, and logger. -// It returns an error if any component fails to initialize. -func (s *Server[T]) Init(appI AppI[T], cfg map[string]any, logger log.Logger) error { - serverCfg := s.config - if len(cfg) > 0 { - if err := UnmarshalSubConfig(cfg, s.Name(), &serverCfg); err != nil { - return fmt.Errorf("failed to unmarshal config: %w", err) - } - } - - var components []ServerComponent[T] - for _, mod := range s.components { - if err := mod.Init(appI, cfg, logger); err != nil { - return err - } - - components = append(components, mod) - } - - s.config = serverCfg - s.components = components - return nil -} - -// 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 -} diff --git a/server/v2/server_test.go b/server/v2/server_test.go deleted file mode 100644 index c216824fb652..000000000000 --- a/server/v2/server_test.go +++ /dev/null @@ -1,121 +0,0 @@ -package serverv2_test - -import ( - "context" - "os" - "path/filepath" - "testing" - "time" - - gogoproto "github.com/cosmos/gogoproto/proto" - "github.com/spf13/viper" - "github.com/stretchr/testify/require" - - appmodulev2 "cosmossdk.io/core/appmodule/v2" - coreserver "cosmossdk.io/core/server" - "cosmossdk.io/core/transaction" - "cosmossdk.io/log" - serverv2 "cosmossdk.io/server/v2" - grpc "cosmossdk.io/server/v2/api/grpc" - "cosmossdk.io/server/v2/appmanager" - "cosmossdk.io/server/v2/store" - storev2 "cosmossdk.io/store/v2" - "cosmossdk.io/store/v2/root" -) - -type mockInterfaceRegistry struct{} - -func (*mockInterfaceRegistry) Resolve(typeUrl string) (gogoproto.Message, error) { - panic("not implemented") -} - -func (*mockInterfaceRegistry) ListImplementations(ifaceTypeURL string) []string { - panic("not implemented") -} -func (*mockInterfaceRegistry) ListAllInterfaces() []string { panic("not implemented") } - -type mockApp[T transaction.Tx] struct { - serverv2.AppI[T] -} - -func (*mockApp[T]) GetQueryHandlers() map[string]appmodulev2.Handler { - return map[string]appmodulev2.Handler{} -} - -func (*mockApp[T]) GetAppManager() *appmanager.AppManager[T] { - return nil -} - -func (*mockApp[T]) InterfaceRegistry() coreserver.InterfaceRegistry { - return &mockInterfaceRegistry{} -} - -var _ root.Builder = &mockStoreBuilder{} - -type mockStoreBuilder struct{} - -func (m mockStoreBuilder) Build(logger log.Logger, config *root.Config) (storev2.RootStore, error) { - return nil, nil -} - -func (m mockStoreBuilder) RegisterKey(string) {} - -func (m mockStoreBuilder) Get() storev2.RootStore { return nil } - -func TestServer(t *testing.T) { - currentDir, err := os.Getwd() - require.NoError(t, err) - configPath := filepath.Join(currentDir, "testdata") - - v, err := serverv2.ReadConfig(configPath) - if err != nil { - v = viper.New() - } - cfg := v.AllSettings() - - logger := log.NewLogger(os.Stdout) - grpcServer := grpc.New[transaction.Tx]() - err = grpcServer.Init(&mockApp[transaction.Tx]{}, cfg, logger) - require.NoError(t, err) - - storeServer := store.New[transaction.Tx](&mockStoreBuilder{}) - err = storeServer.Init(&mockApp[transaction.Tx]{}, cfg, logger) - require.NoError(t, err) - - mockServer := &mockServer{name: "mock-server-1", ch: make(chan string, 100)} - - server := serverv2.NewServer( - logger, - serverv2.DefaultServerConfig(), - grpcServer, - storeServer, - mockServer, - ) - - serverCfgs := server.Configs() - require.Equal(t, serverCfgs[grpcServer.Name()].(*grpc.Config).Address, grpc.DefaultConfig().Address) - require.Equal(t, serverCfgs[mockServer.Name()].(*mockServerConfig).MockFieldOne, MockServerDefaultConfig().MockFieldOne) - - // write config - err = server.WriteConfig(configPath) - require.NoError(t, err) - - v, err = serverv2.ReadConfig(configPath) - require.NoError(t, err) - - require.Equal(t, v.GetString(grpcServer.Name()+".address"), grpc.DefaultConfig().Address) - - // start empty - ctx, cancelFn := context.WithCancel(context.TODO()) - go func() { - // wait 5sec and cancel context - <-time.After(5 * time.Second) - cancelFn() - - err = server.Stop(ctx) - require.NoError(t, err) - }() - - err = server.Start(ctx) - require.NoError(t, err) -} diff --git a/server/v2/store/server.go b/server/v2/store/server.go deleted file mode 100644 index a793a1912dba..000000000000 --- a/server/v2/store/server.go +++ /dev/null @@ -1,100 +0,0 @@ -package store - -import ( - "context" - "fmt" - - "github.com/spf13/cobra" - - "cosmossdk.io/core/transaction" - "cosmossdk.io/log" - serverv2 "cosmossdk.io/server/v2" - storev2 "cosmossdk.io/store/v2" - "cosmossdk.io/store/v2/root" -) - -var ( - _ serverv2.ServerComponent[transaction.Tx] = (*Server[transaction.Tx])(nil) - _ serverv2.HasConfig = (*Server[transaction.Tx])(nil) - _ serverv2.HasCLICommands = (*Server[transaction.Tx])(nil) -) - -const ServerName = "store" - -// Server manages store config and contains prune & snapshot commands -type Server[T transaction.Tx] struct { - config *root.Config - builder root.Builder - backend storev2.Backend -} - -func New[T transaction.Tx](builder root.Builder) *Server[T] { - return &Server[T]{builder: builder} -} - -func (s *Server[T]) Init(_ serverv2.AppI[T], cfg map[string]any, log log.Logger) error { - var err error - s.config, err = UnmarshalConfig(cfg) - if err != nil { - return fmt.Errorf("failed to unmarshal config: %w", err) - } - s.backend, err = s.builder.Build(log, s.config) - if err != nil { - return fmt.Errorf("failed to create store backend: %w", err) - } - - return nil -} - -func (s *Server[T]) Name() string { - return ServerName -} - -func (s *Server[T]) Start(context.Context) error { - return nil -} - -func (s *Server[T]) Stop(context.Context) error { - return nil -} - -func (s *Server[T]) CLICommands() serverv2.CLIConfig { - return serverv2.CLIConfig{ - Commands: []*cobra.Command{ - s.PrunesCmd(), - s.ExportSnapshotCmd(), - s.DeleteSnapshotCmd(), - s.ListSnapshotsCmd(), - s.DumpArchiveCmd(), - s.LoadArchiveCmd(), - s.RestoreSnapshotCmd(s.backend), - }, - } -} - -func (s *Server[T]) Config() any { - if s.config == nil || s.config.AppDBBackend == "" { - return root.DefaultConfig() - } - - return s.config -} - -// UnmarshalConfig unmarshals the store config from the given map. -// If the config is not found in the map, the default config is returned. -// If the home directory is found in the map, it sets the home directory in the config. -// An empty home directory *is* permitted at this stage, but attempting to build -// the store with an empty home directory will fail. -func UnmarshalConfig(cfg map[string]any) (*root.Config, error) { - config := &root.Config{ - Options: root.DefaultStoreOptions(), - } - if err := serverv2.UnmarshalSubConfig(cfg, ServerName, config); err != nil { - return nil, fmt.Errorf("failed to unmarshal config: %w", err) - } - home := cfg[serverv2.FlagHome] - if home != nil { - config.Home = home.(string) - } - return config, nil -} diff --git a/server/v2/store/snapshot.go b/server/v2/store/snapshot.go deleted file mode 100644 index e7958068e56a..000000000000 --- a/server/v2/store/snapshot.go +++ /dev/null @@ -1,412 +0,0 @@ -package store - -import ( - "archive/tar" - "bytes" - "compress/gzip" - "errors" - "fmt" - "io" - "os" - "path/filepath" - "reflect" - "strconv" - - "github.com/spf13/cobra" - "github.com/spf13/viper" - - "cosmossdk.io/log" - serverv2 "cosmossdk.io/server/v2" - storev2 "cosmossdk.io/store/v2" - "cosmossdk.io/store/v2/snapshots" - "cosmossdk.io/store/v2/snapshots/types" -) - -const SnapshotFileName = "_snapshot" - -// ExportSnapshotCmd exports app state to snapshot store. -func (s *Server[T]) ExportSnapshotCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "export", - Short: "Export app state to snapshot store", - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, args []string) error { - v := serverv2.GetViperFromCmd(cmd) - - height, err := cmd.Flags().GetInt64("height") - if err != nil { - return err - } - - logger := log.NewLogger(cmd.OutOrStdout()) - // app := appCreator(logger, db, nil, viper) - rootStore, _, err := createRootStore(cmd, v, logger) - if err != nil { - return err - } - if height == 0 { - lastCommitId, err := rootStore.LastCommitID() - if err != nil { - return err - } - height = int64(lastCommitId.Version) - } - - cmd.Printf("Exporting snapshot for height %d\n", height) - - sm, err := createSnapshotsManager(cmd, v, logger, rootStore) - if err != nil { - return err - } - - snapshot, err := sm.Create(uint64(height)) - if err != nil { - return err - } - - cmd.Printf("Snapshot created at height %d, format %d, chunks %d\n", snapshot.Height, snapshot.Format, snapshot.Chunks) - return nil - }, - } - - addSnapshotFlagsToCmd(cmd) - cmd.Flags().Int64("height", 0, "Height to export, default to latest state height") - - return cmd -} - -// RestoreSnapshotCmd returns a command to restore a snapshot -func (s *Server[T]) RestoreSnapshotCmd(rootStore storev2.Backend) *cobra.Command { - cmd := &cobra.Command{ - Use: "restore ", - Short: "Restore app state from local snapshot", - Long: "Restore app state from local snapshot", - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - v := serverv2.GetViperFromCmd(cmd) - - height, err := strconv.ParseUint(args[0], 10, 64) - if err != nil { - return err - } - format, err := strconv.ParseUint(args[1], 10, 32) - if err != nil { - return err - } - - logger := log.NewLogger(cmd.OutOrStdout()) - - sm, err := createSnapshotsManager(cmd, v, logger, rootStore) - if err != nil { - return err - } - - return sm.RestoreLocalSnapshot(height, uint32(format)) - }, - } - - addSnapshotFlagsToCmd(cmd) - - return cmd -} - -// ListSnapshotsCmd returns the command to list local snapshots -func (s *Server[T]) ListSnapshotsCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "list", - Short: "List local snapshots", - RunE: func(cmd *cobra.Command, args []string) error { - v := serverv2.GetViperFromCmd(cmd) - snapshotStore, err := snapshots.NewStore(filepath.Join(v.GetString(serverv2.FlagHome), "data", "snapshots")) - if err != nil { - return err - } - snapshots, err := snapshotStore.List() - if err != nil { - return fmt.Errorf("failed to list snapshots: %w", err) - } - for _, snapshot := range snapshots { - cmd.Println("height:", snapshot.Height, "format:", snapshot.Format, "chunks:", snapshot.Chunks) - } - - return nil - }, - } - - return cmd -} - -// DeleteSnapshotCmd returns the command to delete a local snapshot -func (s *Server[T]) DeleteSnapshotCmd() *cobra.Command { - return &cobra.Command{ - Use: "delete ", - Short: "Delete a local snapshot", - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - v := serverv2.GetViperFromCmd(cmd) - - height, err := strconv.ParseUint(args[0], 10, 64) - if err != nil { - return err - } - format, err := strconv.ParseUint(args[1], 10, 32) - if err != nil { - return err - } - - snapshotStore, err := snapshots.NewStore(filepath.Join(v.GetString(serverv2.FlagHome), "data", "snapshots")) - if err != nil { - return err - } - - return snapshotStore.Delete(height, uint32(format)) - }, - } -} - -// DumpArchiveCmd returns a command to dump the snapshot as portable archive format -func (s *Server[T]) DumpArchiveCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "dump ", - Short: "Dump the snapshot as portable archive format", - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - v := serverv2.GetViperFromCmd(cmd) - snapshotStore, err := snapshots.NewStore(filepath.Join(v.GetString(serverv2.FlagHome), "data", "snapshots")) - if err != nil { - return err - } - - output, err := cmd.Flags().GetString("output") - if err != nil { - return err - } - - height, err := strconv.ParseUint(args[0], 10, 64) - if err != nil { - return err - } - format, err := strconv.ParseUint(args[1], 10, 32) - if err != nil { - return err - } - - if output == "" { - output = fmt.Sprintf("%d-%d.tar.gz", height, format) - } - - snapshot, err := snapshotStore.Get(height, uint32(format)) - if err != nil { - return err - } - - if snapshot == nil { - return errors.New("snapshot doesn't exist") - } - - bz, err := snapshot.Marshal() - if err != nil { - return err - } - - fp, err := os.Create(output) - if err != nil { - return err - } - defer fp.Close() - - // since the chunk files are already compressed, we just use fastest compression here - gzipWriter, err := gzip.NewWriterLevel(fp, gzip.BestSpeed) - if err != nil { - return err - } - tarWriter := tar.NewWriter(gzipWriter) - if err := tarWriter.WriteHeader(&tar.Header{ - Name: SnapshotFileName, - Mode: 0o644, - Size: int64(len(bz)), - }); err != nil { - return fmt.Errorf("failed to write snapshot header to tar: %w", err) - } - if _, err := tarWriter.Write(bz); err != nil { - return fmt.Errorf("failed to write snapshot to tar: %w", err) - } - - for i := uint32(0); i < snapshot.Chunks; i++ { - path := snapshotStore.PathChunk(height, uint32(format), i) - tarName := strconv.FormatUint(uint64(i), 10) - if err := processChunk(tarWriter, path, tarName); err != nil { - return err - } - } - - if err := tarWriter.Close(); err != nil { - return fmt.Errorf("failed to close tar writer: %w", err) - } - - if err := gzipWriter.Close(); err != nil { - return fmt.Errorf("failed to close gzip writer: %w", err) - } - - return fp.Close() - }, - } - - cmd.Flags().StringP("output", "o", "", "output file") - - return cmd -} - -// LoadArchiveCmd load a portable archive format snapshot into snapshot store -func (s *Server[T]) LoadArchiveCmd() *cobra.Command { - return &cobra.Command{ - Use: "load ", - Short: "Load a snapshot archive file (.tar.gz) into snapshot store", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - v := serverv2.GetViperFromCmd(cmd) - snapshotStore, err := snapshots.NewStore(filepath.Join(v.GetString(serverv2.FlagHome), "data", "snapshots")) - if err != nil { - return err - } - - path := args[0] - fp, err := os.Open(path) - if err != nil { - return fmt.Errorf("failed to open archive file: %w", err) - } - reader, err := gzip.NewReader(fp) - if err != nil { - return fmt.Errorf("failed to create gzip reader: %w", err) - } - - var snapshot types.Snapshot - tr := tar.NewReader(reader) - - hdr, err := tr.Next() - if err != nil { - return fmt.Errorf("failed to read snapshot file header: %w", err) - } - if hdr.Name != SnapshotFileName { - return fmt.Errorf("invalid archive, expect file: snapshot, got: %s", hdr.Name) - } - bz, err := io.ReadAll(tr) - if err != nil { - return fmt.Errorf("failed to read snapshot file: %w", err) - } - if err := snapshot.Unmarshal(bz); err != nil { - return fmt.Errorf("failed to unmarshal snapshot: %w", err) - } - - // make sure the channel is unbuffered, because the tar reader can't do concurrency - chunks := make(chan io.ReadCloser) - quitChan := make(chan *types.Snapshot) - go func() { - defer close(quitChan) - - savedSnapshot, err := snapshotStore.Save(snapshot.Height, snapshot.Format, chunks) - if err != nil { - cmd.Println("failed to save snapshot", err) - return - } - quitChan <- savedSnapshot - }() - - for i := uint32(0); i < snapshot.Chunks; i++ { - hdr, err = tr.Next() - if err != nil { - if errors.Is(err, io.EOF) { - break - } - return err - } - - if hdr.Name != strconv.FormatInt(int64(i), 10) { - return fmt.Errorf("invalid archive, expect file: %d, got: %s", i, hdr.Name) - } - - bz, err := io.ReadAll(tr) - if err != nil { - return fmt.Errorf("failed to read chunk file: %w", err) - } - chunks <- io.NopCloser(bytes.NewReader(bz)) - } - close(chunks) - - savedSnapshot := <-quitChan - if savedSnapshot == nil { - return errors.New("failed to save snapshot") - } - - if !reflect.DeepEqual(&snapshot, savedSnapshot) { - _ = snapshotStore.Delete(snapshot.Height, snapshot.Format) - return errors.New("invalid archive, the saved snapshot is not equal to the original one") - } - - return nil - }, - } -} - -func createSnapshotsManager( - cmd *cobra.Command, v *viper.Viper, logger log.Logger, store storev2.Backend, -) (*snapshots.Manager, error) { - home := v.GetString(serverv2.FlagHome) - snapshotStore, err := snapshots.NewStore(filepath.Join(home, "data", "snapshots")) - if err != nil { - return nil, err - } - var interval, keepRecent uint64 - // if flag was not passed, use as 0. - if cmd.Flags().Changed(FlagKeepRecent) { - keepRecent, err = cmd.Flags().GetUint64(FlagKeepRecent) - if err != nil { - return nil, err - } - } - if cmd.Flags().Changed(FlagInterval) { - interval, err = cmd.Flags().GetUint64(FlagInterval) - if err != nil { - return nil, err - } - } - - sm := snapshots.NewManager( - snapshotStore, snapshots.NewSnapshotOptions(interval, uint32(keepRecent)), - store.GetStateCommitment().(snapshots.CommitSnapshotter), - store.GetStateStorage().(snapshots.StorageSnapshotter), - nil, logger) - return sm, nil -} - -func addSnapshotFlagsToCmd(cmd *cobra.Command) { - cmd.Flags().Uint64(FlagKeepRecent, 0, "KeepRecent defines how many snapshots to keep in heights") - cmd.Flags().Uint64(FlagInterval, 0, "Interval defines at which heights the snapshot is taken") -} - -func processChunk(tarWriter *tar.Writer, path, tarName string) error { - file, err := os.Open(path) - if err != nil { - return fmt.Errorf("failed to open chunk file %s: %w", path, err) - } - defer file.Close() - - st, err := file.Stat() - if err != nil { - return fmt.Errorf("failed to stat chunk file %s: %w", path, err) - } - - if err := tarWriter.WriteHeader(&tar.Header{ - Name: tarName, - Mode: 0o644, - Size: st.Size(), - }); err != nil { - return fmt.Errorf("failed to write chunk header to tar: %w", err) - } - - if _, err := io.Copy(tarWriter, file); err != nil { - return fmt.Errorf("failed to write chunk to tar: %w", err) - } - - return nil -} diff --git a/server/v2/types.go b/server/v2/types.go deleted file mode 100644 index a28385922178..000000000000 --- a/server/v2/types.go +++ /dev/null @@ -1,20 +0,0 @@ -package serverv2 - -import ( - "github.com/spf13/viper" - - appmodulev2 "cosmossdk.io/core/appmodule/v2" - "cosmossdk.io/core/server" - "cosmossdk.io/core/transaction" - "cosmossdk.io/log" - "cosmossdk.io/server/v2/appmanager" -) - -type AppCreator[T transaction.Tx] func(log.Logger, *viper.Viper) AppI[T] - -type AppI[T transaction.Tx] interface { - Name() string - InterfaceRegistry() server.InterfaceRegistry - GetAppManager() *appmanager.AppManager[T] - GetQueryHandlers() map[string]appmodulev2.Handler -} diff --git a/simapp/v2/go.mod b/simapp/v2/go.mod index 00827394c8ad..2c4f8769fd3e 100644 --- a/simapp/v2/go.mod +++ b/simapp/v2/go.mod @@ -10,8 +10,8 @@ require ( cosmossdk.io/depinject v1.0.0 cosmossdk.io/log v1.4.1 cosmossdk.io/math v1.3.0 - cosmossdk.io/runtime/v2 v2.0.0-20241003101412-c5889a418ae2 // main - cosmossdk.io/server/v2 v2.0.0-20241003112707-72f771638528 // main + cosmossdk.io/runtime/v2 v2.0.0-20241008175849-325728a9fd6c // main + cosmossdk.io/server/v2 v2.0.0-20241008175849-325728a9fd6c // main cosmossdk.io/server/v2/cometbft v0.0.0-00010101000000-000000000000 cosmossdk.io/store/v2 v2.0.0-20240916221850-7856d226038c // main cosmossdk.io/tools/confix v0.0.0-00010101000000-000000000000 @@ -40,7 +40,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.9.0 - google.golang.org/protobuf v1.34.2 + google.golang.org/protobuf v1.35.1 ) require ( @@ -62,8 +62,8 @@ require ( cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5 // indirect cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect - cosmossdk.io/server/v2/appmanager v0.0.0-20241003101412-c5889a418ae2 // indirect; main - cosmossdk.io/server/v2/stf v0.0.0-20241003101412-c5889a418ae2 // indirect; main + cosmossdk.io/server/v2/appmanager v0.0.0-20241008175849-325728a9fd6c // indirect; main + cosmossdk.io/server/v2/stf v0.0.0-20241008175849-325728a9fd6c // indirect; main cosmossdk.io/store v1.1.1-0.20240909133312-50288938d1b6 // indirect; main cosmossdk.io/x/tx v0.13.4-0.20241003111526-30003f667944 // indirect; main filippo.io/edwards25519 v1.1.0 // indirect @@ -216,15 +216,15 @@ require ( go.opentelemetry.io/otel/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.27.0 // indirect + golang.org/x/crypto v0.28.0 // indirect golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.29.0 // indirect golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/term v0.24.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/term v0.25.0 // indirect + golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.25.0 // indirect google.golang.org/api v0.185.0 // indirect diff --git a/simapp/v2/go.sum b/simapp/v2/go.sum index 840d32f91b2e..36b6289ff577 100644 --- a/simapp/v2/go.sum +++ b/simapp/v2/go.sum @@ -210,16 +210,16 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/runtime/v2 v2.0.0-20241003101412-c5889a418ae2 h1:/KMBWc+mflXNv6HOkaQD2cEGlZAME/7wvU0GdMy7zYU= -cosmossdk.io/runtime/v2 v2.0.0-20241003101412-c5889a418ae2/go.mod h1:o9I/8aO/VF6RQU1OdaAE3sMhBD10vl2GEnSrYOLwYVk= +cosmossdk.io/runtime/v2 v2.0.0-20241008175849-325728a9fd6c h1:+msBeQ6/bmJOhJPV7fye1bYf86LTaRMJezwTc5LSBUs= +cosmossdk.io/runtime/v2 v2.0.0-20241008175849-325728a9fd6c/go.mod h1:pmne/XLLzEbQ6JeM/nQoZVvK19ZtMvvEMq6qOMp9MHs= cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= -cosmossdk.io/server/v2 v2.0.0-20241003112707-72f771638528 h1:6Ht6Yg36nsbtOjdxj+fvUk5o35Nkg9vA9WQC+oNs+sI= -cosmossdk.io/server/v2 v2.0.0-20241003112707-72f771638528/go.mod h1:zXQpdRRGLQjq17VxHiieHjA0xcU2ydgjR82XOgA6Cdc= -cosmossdk.io/server/v2/appmanager v0.0.0-20241003101412-c5889a418ae2 h1:8GOXwsEQbRtpQ/bzUEly4FCOqhBhgxFFDzBGkrPjBUs= -cosmossdk.io/server/v2/appmanager v0.0.0-20241003101412-c5889a418ae2/go.mod h1:/xDfniqVtn5nraiHkNJ4e6rYU0e83YAGsSjwmUA6H8k= -cosmossdk.io/server/v2/stf v0.0.0-20241003101412-c5889a418ae2 h1:G1kMEqy4OAO/BZD9ZJa2rVVxsYSPHzKrictiOAGPuoY= -cosmossdk.io/server/v2/stf v0.0.0-20241003101412-c5889a418ae2/go.mod h1:TFpf9xrlr88CPDVDq3pcpX88brCDo5qazFd+lBU67a0= +cosmossdk.io/server/v2 v2.0.0-20241008175849-325728a9fd6c h1:SobvpV3A/LPlmQ+mM6YrJHt7rRP6Cp7aVOB2ulwEBEc= +cosmossdk.io/server/v2 v2.0.0-20241008175849-325728a9fd6c/go.mod h1:GEldDSZX6StSNMIazVU6z1dm9cSq+FNMiOCJXmgBeZE= +cosmossdk.io/server/v2/appmanager v0.0.0-20241008175849-325728a9fd6c h1:MJCOTFyL7lPlMDUFvylEu/2zyFe7NcYe4eMaZowvzk4= +cosmossdk.io/server/v2/appmanager v0.0.0-20241008175849-325728a9fd6c/go.mod h1:/xDfniqVtn5nraiHkNJ4e6rYU0e83YAGsSjwmUA6H8k= +cosmossdk.io/server/v2/stf v0.0.0-20241008175849-325728a9fd6c h1:thOij3diZWxwfKaSJNS6S1SFX+fnOW93emnuu+WSHJY= +cosmossdk.io/server/v2/stf v0.0.0-20241008175849-325728a9fd6c/go.mod h1:MjuTMonZ319tZQX6CV2O5E/+F85KrkNUj5U5ObrrkWs= cosmossdk.io/store v1.0.0-rc.0.0.20240913190136-3bc707a5a214 h1:UUW0+2UgbDwQ452o2aw4DrVSWmowcad7DB7Vln+N94I= cosmossdk.io/store v1.0.0-rc.0.0.20240913190136-3bc707a5a214/go.mod h1:ct8HATr+s48YYTRXEyP3HF33v9qEVWHMxwOL8P/v4iQ= cosmossdk.io/store/v2 v2.0.0-20240916221850-7856d226038c h1:x0NX01A+QWckckb1hi9p8mYW4OXTYEzsohQK2qBtIHg= @@ -884,8 +884,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1105,13 +1105,13 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1122,8 +1122,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1417,8 +1417,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/store/v2/root/builder.go b/store/v2/root/builder.go deleted file mode 100644 index 885c41d24484..000000000000 --- a/store/v2/root/builder.go +++ /dev/null @@ -1,95 +0,0 @@ -package root - -import ( - "fmt" - "path/filepath" - - "cosmossdk.io/log" - "cosmossdk.io/store/v2" - "cosmossdk.io/store/v2/db" -) - -// Builder is the interface for a store/v2 RootStore builder. -// RootStores built by the Cosmos SDK typically involve a 2 phase initialization: -// 1. Namespace registration -// 2. Configuration and loading -// -// The Builder interface is used to facilitate this pattern. Namespaces (store keys) are registered -// by calling RegisterKey before Build is called. Build is then called with a Config -// object and a RootStore is returned. Calls to Get may return the `RootStore` if Build -// was successful, but that's left up to the implementation. -type Builder interface { - // Build creates a new store/v2 RootStore from the given Config. - Build(log.Logger, *Config) (store.RootStore, error) - // RegisterKey registers a store key (namespace) to be used when building the RootStore. - RegisterKey(string) - // Get returns the Store. Build should be called before calling Get or the result will be nil. - Get() store.RootStore -} - -var _ Builder = (*builder)(nil) - -// builder is the default builder for a store/v2 RootStore satisfying the Store interface. -// Tangibly it combines store key registration and a top-level Config to create a RootStore by calling -// the CreateRootStore factory function. -type builder struct { - // input - storeKeys map[string]struct{} - - // output - store store.RootStore -} - -func NewBuilder() Builder { - return &builder{storeKeys: make(map[string]struct{})} -} - -// Build creates a new store/v2 RootStore. -func (sb *builder) Build( - logger log.Logger, - config *Config, -) (store.RootStore, error) { - if sb.store != nil { - return sb.store, nil - } - if config.Home == "" { - return nil, fmt.Errorf("home directory is required") - } - scRawDb, err := db.NewDB( - db.DBType(config.AppDBBackend), - "application", - filepath.Join(config.Home, "data"), - nil, - ) - if err != nil { - return nil, fmt.Errorf("failed to create SCRawDB: %w", err) - } - - var storeKeys []string - for key := range sb.storeKeys { - storeKeys = append(storeKeys, key) - } - - factoryOptions := &FactoryOptions{ - Logger: logger, - RootDir: config.Home, - Options: config.Options, - StoreKeys: storeKeys, - SCRawDB: scRawDb, - } - - rs, err := CreateRootStore(factoryOptions) - if err != nil { - return nil, fmt.Errorf("failed to create root store: %w", err) - } - sb.store = rs - return sb.store, nil -} - -func (sb *builder) Get() store.RootStore { - return sb.store -} - -func (sb *builder) RegisterKey(key string) { - sb.storeKeys[key] = struct{}{} -} diff --git a/store/v2/root/config.go b/store/v2/root/config.go deleted file mode 100644 index 28f46a3879b7..000000000000 --- a/store/v2/root/config.go +++ /dev/null @@ -1,14 +0,0 @@ -package root - -func DefaultConfig() *Config { - return &Config{ - AppDBBackend: "goleveldb", - Options: DefaultStoreOptions(), - } -} - -type Config struct { - Home string `toml:"-"` // this field is omitted in the TOML file - AppDBBackend string `mapstructure:"app-db-backend" toml:"app-db-backend" comment:"The type of database for application and snapshots databases."` - Options Options `mapstructure:"options" toml:"options"` -} diff --git a/store/v2/root/factory.go b/store/v2/root/factory.go deleted file mode 100644 index 9e1f76a36ceb..000000000000 --- a/store/v2/root/factory.go +++ /dev/null @@ -1,181 +0,0 @@ -package root - -import ( - "errors" - "fmt" - "os" - - "cosmossdk.io/core/log" - corestore "cosmossdk.io/core/store" - "cosmossdk.io/store/v2" - "cosmossdk.io/store/v2/commitment" - "cosmossdk.io/store/v2/commitment/iavl" - "cosmossdk.io/store/v2/commitment/mem" - "cosmossdk.io/store/v2/db" - "cosmossdk.io/store/v2/internal" - "cosmossdk.io/store/v2/pruning" - "cosmossdk.io/store/v2/storage" - "cosmossdk.io/store/v2/storage/pebbledb" - "cosmossdk.io/store/v2/storage/rocksdb" - "cosmossdk.io/store/v2/storage/sqlite" -) - -type ( - SSType string - SCType string -) - -const ( - SSTypeSQLite SSType = "sqlite" - SSTypePebble SSType = "pebble" - SSTypeRocks SSType = "rocksdb" - SCTypeIavl SCType = "iavl" - SCTypeIavlV2 SCType = "iavl-v2" -) - -// Options are the options for creating a root store. -type Options struct { - SSType SSType `mapstructure:"ss-type" toml:"ss-type" comment:"SState storage database type. Currently we support: \"sqlite\", \"pebble\" and \"rocksdb\""` - SCType SCType `mapstructure:"sc-type" toml:"sc-type" comment:"State commitment database type. Currently we support: \"iavl\" and \"iavl-v2\""` - SSPruningOption *store.PruningOption `mapstructure:"ss-pruning-option" toml:"ss-pruning-option" comment:"Pruning options for state storage"` - SCPruningOption *store.PruningOption `mapstructure:"sc-pruning-option" toml:"sc-pruning-option" comment:"Pruning options for state commitment"` - IavlConfig *iavl.Config `mapstructure:"iavl-config" toml:"iavl-config"` -} - -// FactoryOptions are the options for creating a root store. -type FactoryOptions struct { - Logger log.Logger - RootDir string - Options Options - StoreKeys []string - SCRawDB corestore.KVStoreWithBatch -} - -// DefaultStoreOptions returns the default options for creating a root store. -func DefaultStoreOptions() Options { - return Options{ - SSType: SSTypeSQLite, - SCType: SCTypeIavl, - SCPruningOption: &store.PruningOption{ - KeepRecent: 2, - Interval: 100, - }, - SSPruningOption: &store.PruningOption{ - KeepRecent: 2, - Interval: 100, - }, - IavlConfig: &iavl.Config{ - CacheSize: 100_000, - SkipFastStorageUpgrade: true, - }, - } -} - -// CreateRootStore is a convenience function to create a root store based on the -// provided FactoryOptions. Strictly speaking app developers can create the root -// store directly by calling root.New, so this function is not -// necessary, but demonstrates the required steps and configuration to create a root store. -func CreateRootStore(opts *FactoryOptions) (store.RootStore, error) { - var ( - ssDb storage.Database - ss *storage.StorageStore - sc *commitment.CommitStore - err error - ensureDir = func(dir string) error { - if err := os.MkdirAll(dir, 0o0755); err != nil { - return fmt.Errorf("failed to create directory %s: %w", dir, err) - } - return nil - } - ) - - storeOpts := opts.Options - switch storeOpts.SSType { - case SSTypeSQLite: - dir := fmt.Sprintf("%s/data/ss/sqlite", opts.RootDir) - if err = ensureDir(dir); err != nil { - return nil, err - } - ssDb, err = sqlite.New(dir) - case SSTypePebble: - dir := fmt.Sprintf("%s/data/ss/pebble", opts.RootDir) - if err = ensureDir(dir); err != nil { - return nil, err - } - ssDb, err = pebbledb.New(dir) - case SSTypeRocks: - dir := fmt.Sprintf("%s/data/ss/rocksdb", opts.RootDir) - if err = ensureDir(dir); err != nil { - return nil, err - } - ssDb, err = rocksdb.New(dir) - default: - return nil, fmt.Errorf("unknown storage type: %s", opts.Options.SSType) - } - if err != nil { - return nil, err - } - ss = storage.NewStorageStore(ssDb, opts.Logger) - - metadata := commitment.NewMetadataStore(opts.SCRawDB) - latestVersion, err := metadata.GetLatestVersion() - if err != nil { - return nil, err - } - if len(opts.StoreKeys) == 0 { - lastCommitInfo, err := metadata.GetCommitInfo(latestVersion) - if err != nil { - return nil, err - } - if lastCommitInfo == nil { - return nil, fmt.Errorf("tried to construct a root store with no store keys specified but no commit info found for version %d", latestVersion) - } - for _, si := range lastCommitInfo.StoreInfos { - opts.StoreKeys = append(opts.StoreKeys, string(si.Name)) - } - } - removedStoreKeys, err := metadata.GetRemovedStoreKeys(latestVersion) - if err != nil { - return nil, err - } - - newTreeFn := func(key string) (commitment.Tree, error) { - if internal.IsMemoryStoreKey(key) { - return mem.New(), nil - } else { - switch storeOpts.SCType { - case SCTypeIavl: - return iavl.NewIavlTree(db.NewPrefixDB(opts.SCRawDB, []byte(key)), opts.Logger, storeOpts.IavlConfig), nil - case SCTypeIavlV2: - return nil, errors.New("iavl v2 not supported") - default: - return nil, errors.New("unsupported commitment store type") - } - } - } - - trees := make(map[string]commitment.Tree, len(opts.StoreKeys)) - for _, key := range opts.StoreKeys { - tree, err := newTreeFn(key) - if err != nil { - return nil, err - } - trees[key] = tree - } - oldTrees := make(map[string]commitment.Tree, len(opts.StoreKeys)) - for _, key := range removedStoreKeys { - tree, err := newTreeFn(string(key)) - if err != nil { - return nil, err - } - oldTrees[string(key)] = tree - } - - sc, err = commitment.NewCommitStore(trees, oldTrees, opts.SCRawDB, opts.Logger) - if err != nil { - return nil, err - } - - pm := pruning.NewManager(sc, ss, storeOpts.SCPruningOption, storeOpts.SSPruningOption) - return New(opts.Logger, ss, sc, pm, nil, nil) -} diff --git a/store/v2/store.go b/store/v2/store.go deleted file mode 100644 index 1adf44f0b89b..000000000000 --- a/store/v2/store.go +++ /dev/null @@ -1,112 +0,0 @@ -package store - -import ( - "io" - - coreheader "cosmossdk.io/core/header" - corestore "cosmossdk.io/core/store" - "cosmossdk.io/store/v2/metrics" - "cosmossdk.io/store/v2/proof" -) - -// RootStore defines an abstraction layer containing a State Storage (SS) engine -// and one or more State Commitment (SC) engines. -type RootStore interface { - Pruner - Backend - - // StateLatest returns a read-only version of the RootStore at the latest - // height, alongside the associated version. - StateLatest() (uint64, corestore.ReaderMap, error) - - // StateAt is analogous to StateLatest() except it returns a read-only version - // of the RootStore at the provided version. If such a version cannot be found, - // an error must be returned. - StateAt(version uint64) (corestore.ReaderMap, error) - - // Query performs a query on the RootStore for a given store key, version (height), - // and key tuple. Queries should be routed to the underlying SS engine. - Query(storeKey []byte, version uint64, key []byte, prove bool) (QueryResult, error) - - // LoadVersion loads the RootStore to the given version. - LoadVersion(version uint64) error - - // LoadLatestVersion behaves identically to LoadVersion except it loads the - // latest version implicitly. - LoadLatestVersion() error - - // GetLatestVersion returns the latest version, i.e. height, committed. - GetLatestVersion() (uint64, error) - - // SetInitialVersion sets the initial version on the RootStore. - SetInitialVersion(v uint64) error - - // SetCommitHeader sets the commit header for the next commit. This call and - // implementation is optional. However, it must be supported in cases where - // queries based on block time need to be supported. - SetCommitHeader(h *coreheader.Info) - - // WorkingHash returns the current WIP commitment hash by applying the Changeset - // to the SC backend. It is only used to get the hash of the intermediate state - // before committing, the typical use case is for the genesis block. - // NOTE: It also writes the changeset to the SS backend. - WorkingHash(cs *corestore.Changeset) ([]byte, error) - - // Commit should be responsible for taking the provided changeset and flushing - // it to disk. Note, it will overwrite the changeset if WorkingHash() was called. - // Commit() should ensure the changeset is committed to all SC and SS backends - // and flushed to disk. It must return a hash of the merkle-ized committed state. - Commit(cs *corestore.Changeset) ([]byte, error) - - // LastCommitID returns a CommitID pertaining to the last commitment. - LastCommitID() (proof.CommitID, error) - - // SetMetrics sets the telemetry handler on the RootStore. - SetMetrics(m metrics.Metrics) - - io.Closer -} - -// Backend defines the interface for the RootStore backends. -type Backend interface { - // GetStateStorage returns the SS backend. - GetStateStorage() VersionedDatabase - - // GetStateCommitment returns the SC backend. - GetStateCommitment() Committer -} - -// UpgradeableStore defines the interface for upgrading store keys. -type UpgradeableStore interface { - // LoadVersionAndUpgrade behaves identically to LoadVersion except it also - // accepts a StoreUpgrades object that defines a series of transformations to - // apply to store keys (if any). - // - // Note, handling StoreUpgrades is optional depending on the underlying store - // implementation. - LoadVersionAndUpgrade(version uint64, upgrades *corestore.StoreUpgrades) error -} - -// Pruner defines the interface for pruning old versions of the store or database. -type Pruner interface { - // Prune prunes the store to the provided version. - Prune(version uint64) error -} - -// PausablePruner extends the Pruner interface to include the API for pausing -// the pruning process. -type PausablePruner interface { - Pruner - - // PausePruning pauses or resumes the pruning process to avoid the parallel writes - // while committing the state. - PausePruning(pause bool) -} - -// QueryResult defines the response type to performing a query on a RootStore. -type QueryResult struct { - Key []byte - Value []byte - Version uint64 - ProofOps []proof.CommitmentOp -}