diff --git a/server/v2/cometbft/abci.go b/server/v2/cometbft/abci.go index 06c1e43e5ecb..c38bf7fc18cd 100644 --- a/server/v2/cometbft/abci.go +++ b/server/v2/cometbft/abci.go @@ -33,15 +33,14 @@ import ( var _ abci.Application = (*Consensus[transaction.Tx])(nil) type Consensus[T transaction.Tx] struct { - logger log.Logger - appName, version string - consensusAuthority string // Set by the application to grant authority to the consensus engine to send messages to the consensus module - app *appmanager.AppManager[T] - txCodec transaction.Codec[T] - store types.Store - streaming streaming.Manager - snapshotManager *snapshots.Manager - mempool mempool.Mempool[T] + logger log.Logger + appName, version string + app *appmanager.AppManager[T] + txCodec transaction.Codec[T] + store types.Store + streaming streaming.Manager + snapshotManager *snapshots.Manager + mempool mempool.Mempool[T] cfg Config indexedEvents map[string]struct{} @@ -67,7 +66,6 @@ type Consensus[T transaction.Tx] struct { func NewConsensus[T transaction.Tx]( logger log.Logger, appName string, - consensusAuthority string, // TODO remove app *appmanager.AppManager[T], mp mempool.Mempool[T], indexedEvents map[string]struct{}, @@ -80,7 +78,6 @@ func NewConsensus[T transaction.Tx]( return &Consensus[T]{ appName: appName, version: getCometBFTServerVersion(), - consensusAuthority: consensusAuthority, grpcMethodsMap: gRPCMethodsMap, app: app, cfg: cfg, @@ -246,7 +243,6 @@ func (c *Consensus[T]) InitChain(ctx context.Context, req *abciproto.InitChainRe if req.ConsensusParams != nil { ctx = context.WithValue(ctx, corecontext.CometParamsInitInfoKey, &consensustypes.MsgUpdateParams{ - Authority: c.consensusAuthority, Block: req.ConsensusParams.Block, Evidence: req.ConsensusParams.Evidence, Validator: req.ConsensusParams.Validator, diff --git a/server/v2/cometbft/abci_test.go b/server/v2/cometbft/abci_test.go index 0a4f1b16f975..4386a52b9042 100644 --- a/server/v2/cometbft/abci_test.go +++ b/server/v2/cometbft/abci_test.go @@ -694,7 +694,7 @@ func setUpConsensus(t *testing.T, gasLimit uint64, mempool mempool.Mempool[mock. am, err := b.Build() require.NoError(t, err) - return NewConsensus[mock.Tx](log.NewNopLogger(), "testing-app", "authority", am, mempool, map[string]struct{}{}, nil, mockStore, Config{AppTomlConfig: DefaultAppTomlConfig()}, mock.TxCodec{}, "test") + return NewConsensus[mock.Tx](log.NewNopLogger(), "testing-app", am, mempool, map[string]struct{}{}, nil, mockStore, Config{AppTomlConfig: DefaultAppTomlConfig()}, mock.TxCodec{}, "test") } // Check target version same with store's latest version diff --git a/server/v2/cometbft/server.go b/server/v2/cometbft/server.go index 717a3dfe7629..09742b9b3003 100644 --- a/server/v2/cometbft/server.go +++ b/server/v2/cometbft/server.go @@ -104,7 +104,6 @@ func (s *CometBFTServer[T]) Init(appI serverv2.AppI[T], cfg map[string]any, logg consensus := NewConsensus( s.logger, appI.Name(), - appI.GetConsensusAuthority(), appI.GetAppManager(), s.serverOptions.Mempool(cfg), indexEvents, diff --git a/server/v2/types.go b/server/v2/types.go new file mode 100644 index 000000000000..afa82969131a --- /dev/null +++ b/server/v2/types.go @@ -0,0 +1,21 @@ +package serverv2 + +import ( + gogoproto "github.com/cosmos/gogoproto/proto" + "github.com/spf13/viper" + + "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] + GetGPRCMethodsToMessageMap() map[string]func() gogoproto.Message + GetStore() any +} diff --git a/simapp/v2/app_config.go b/simapp/v2/app_config.go index bd60f1a0aa56..9fd6b2a7c231 100644 --- a/simapp/v2/app_config.go +++ b/simapp/v2/app_config.go @@ -262,10 +262,8 @@ var ( Config: appconfig.WrapAny(&govmodulev1.Module{}), }, { - Name: consensustypes.ModuleName, - Config: appconfig.WrapAny(&consensusmodulev1.Module{ - Authority: "consensus", // TODO remove. - }), + Name: consensustypes.ModuleName, + Config: appconfig.WrapAny(&consensusmodulev1.Module{}), }, { Name: accounts.ModuleName, diff --git a/simapp/v2/app_di.go b/simapp/v2/app_di.go index 733ab1ffc829..3a3245627639 100644 --- a/simapp/v2/app_di.go +++ b/simapp/v2/app_di.go @@ -13,7 +13,6 @@ import ( "cosmossdk.io/log" "cosmossdk.io/runtime/v2" "cosmossdk.io/store/v2/root" - consensuskeeper "cosmossdk.io/x/consensus/keeper" upgradekeeper "cosmossdk.io/x/upgrade/keeper" "github.com/cosmos/cosmos-sdk/client" @@ -38,8 +37,7 @@ type SimApp[T transaction.Tx] struct { // required keepers during wiring // others keepers are all in the app - UpgradeKeeper *upgradekeeper.Keeper - ConsensusParamsKeeper consensuskeeper.Keeper + UpgradeKeeper *upgradekeeper.Keeper } func init() { @@ -135,7 +133,6 @@ func NewSimApp[T transaction.Tx]( &app.txConfig, &app.interfaceRegistry, &app.UpgradeKeeper, - &app.ConsensusParamsKeeper, ); err != nil { panic(err) } @@ -186,11 +183,6 @@ func (app *SimApp[T]) TxConfig() client.TxConfig { return app.txConfig } -// GetConsensusAuthority gets the consensus authority. -func (app *SimApp[T]) GetConsensusAuthority() string { - return app.ConsensusParamsKeeper.GetAuthority() -} - // GetStore gets the app store. func (app *SimApp[T]) GetStore() any { return app.App.GetStore() diff --git a/store/v2/root/factory.go b/store/v2/root/factory.go new file mode 100644 index 000000000000..e6f86917ab0d --- /dev/null +++ b/store/v2/root/factory.go @@ -0,0 +1,181 @@ +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" +) + +// app.toml config options +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) +}