Skip to content

Commit

Permalink
feat(store/v2): build the migration manager in the root store factory (
Browse files Browse the repository at this point in the history
…#22336)

Co-authored-by: marbar3778 <[email protected]>
Co-authored-by: Marko <[email protected]>
Co-authored-by: Alex | Interchain Labs <[email protected]>
(cherry picked from commit 064c9ba)

# Conflicts:
#	scripts/init-simapp-v2.sh
#	server/v2/server.go
#	simapp/v2/app_config.go
#	store/v2/commitment/iavl/exporter.go
#	store/v2/commitment/iavl/tree.go
#	store/v2/commitment/metadata.go
#	store/v2/commitment/store.go
#	store/v2/commitment/store_test_suite.go
#	store/v2/go.mod
#	store/v2/migration/manager.go
#	store/v2/migration/manager_test.go
#	store/v2/proof/commit_info.go
#	store/v2/proof/commit_info_test.go
#	store/v2/root/factory.go
#	store/v2/root/factory_test.go
#	store/v2/root/store.go
#	tests/systemtests/bankv2_test.go
  • Loading branch information
cool-develope authored and mergify[bot] committed Jan 13, 2025
1 parent 947fa79 commit 13a9cc7
Show file tree
Hide file tree
Showing 23 changed files with 7,094 additions and 3 deletions.
2,048 changes: 2,048 additions & 0 deletions api/cosmos/store/v2/commit_info.pulsar.go

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions proto/cosmos/store/v2/commit_info.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
syntax = "proto3";
package cosmos.store.v2;

import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";

option go_package = "cosmossdk.io/store/v2/proof";

// CommitInfo defines commit information used by the multi-store when committing
// a version/height.
message CommitInfo {
int64 version = 1;
repeated StoreInfo store_infos = 2;
google.protobuf.Timestamp timestamp = 3 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
bytes commit_hash = 4;
}

// StoreInfo defines store-specific commit information. It contains a reference
// between a store name and the commit ID.
//
message StoreInfo {
string name = 1;
CommitID commit_id = 2;
string structure = 3;
}

// CommitID defines the commitment information when a specific store is
// committed.
message CommitID {
option (gogoproto.goproto_stringer) = false;

int64 version = 1;
bytes hash = 2;
}
16 changes: 16 additions & 0 deletions scripts/init-simapp-v2.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,24 @@ $SIMD_BIN config set client keyring-backend test
$SIMD_BIN config set client keyring-default-keyname alice
$SIMD_BIN config set app rest.enable true
$SIMD_BIN config set app telemetry.prometheus-retention-time 600
<<<<<<< HEAD
$SIMD_BIN keys add alice --indiscreet
$SIMD_BIN keys add bob --indiscreet
=======
sed -i '' 's/timeout_commit = "5s"/timeout_commit = "1s"/' "$SIMD_HOME"/config/config.toml
sed -i '' 's/prometheus = false/prometheus = true/' "$SIMD_HOME"/config/config.toml

$SIMD_BIN keys add alice --indiscreet
$SIMD_BIN keys add bob --indiscreet
aliases=""
for i in $(seq 10); do
alias=$(dd if=/dev/urandom bs=16 count=24 2> /dev/null | base64 | head -c 32)
$SIMD_BIN keys add "$alias" --indiscreet
aliases="$aliases $alias"
done
echo "Generated aliases: $aliases"

>>>>>>> 064c9ba63 (feat(store/v2): build the migration manager in the root store factory (#22336))
$SIMD_BIN init simapp-v2-node --chain-id simapp-v2-chain
# to change the voting_period
jq '.app_state.gov.params.voting_period = "600s"' $SIMD_HOME/config/genesis.json > temp.json && mv temp.json $SIMD_HOME/config/genesis.json
Expand Down
2 changes: 1 addition & 1 deletion server/v2/cometbft/abci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -914,7 +914,7 @@ func assertStoreLatestVersion(t *testing.T, store types.Store, target uint64) {
require.Equal(t, target, version)
commitInfo, err := store.GetStateCommitment().GetCommitInfo(version)
require.NoError(t, err)
require.Equal(t, target, commitInfo.Version)
require.Equal(t, target, uint64(commitInfo.Version))
}

func TestOptimisticExecution(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions server/v2/cometbft/internal/mock/mock_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (s *MockStore) GetLatestVersion() (uint64, error) {
return 0, err
}

return lastCommitID.Version, nil
return uint64(lastCommitID.Version), nil
}

func (s *MockStore) StateLatest() (uint64, corestore.ReaderMap, error) {
Expand Down Expand Up @@ -99,7 +99,7 @@ func (s *MockStore) LastCommitID() (proof.CommitID, error) {
v, err := s.GetStateCommitment().GetLatestVersion()
bz := sha256.Sum256([]byte{})
return proof.CommitID{
Version: v,
Version: int64(v),
Hash: bz[:],
}, err
}
Expand Down
251 changes: 251 additions & 0 deletions server/v2/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
package serverv2

import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
"strings"

"github.com/pelletier/go-toml/v2"
"github.com/spf13/cobra"
"github.com/spf13/pflag"

"cosmossdk.io/core/transaction"
"cosmossdk.io/log"
)

// ServerComponent is a server component that can be started and stopped.
type ServerComponent[T transaction.Tx] interface {
// Name returns the name of the server component.
Name() string

// Start starts the server component.
Start(context.Context) error
// Stop stops the server component.
// Once Stop has been called on a server component, it may not be reused.
Stop(context.Context) error
}

// HasStartFlags is a server component that has start flags.
type HasStartFlags interface {
// StartCmdFlags returns server start flags.
// Those flags should be prefixed with the server name.
// They are then merged with the server config in one viper instance.
StartCmdFlags() *pflag.FlagSet
}

// HasConfig is a server component that has a config.
type HasConfig interface {
Config() any
}

// ConfigWriter is a server component that can write its config to a file.
type ConfigWriter interface {
WriteConfig(path string) error
}

// HasCLICommands is a server component that has CLI commands.
type HasCLICommands interface {
CLICommands() CLIConfig
}

// CLIConfig defines the CLI configuration for a component server.
type CLIConfig struct {
// Commands defines the main command of a server component.
Commands []*cobra.Command
// Queries defines the query commands of a server component.
// Those commands are meant to be added in the root query command.
Queries []*cobra.Command
// Txs defines the tx commands of a server component.
// Those commands are meant to be added in the root tx command.
Txs []*cobra.Command
}

const (
serverName = "server"
)

var _ ServerComponent[transaction.Tx] = (*Server[transaction.Tx])(nil)

// Server is the top-level server component which contains all other server components.
type Server[T transaction.Tx] struct {
components []ServerComponent[T]
config ServerConfig

Check failure on line 75 in server/v2/server.go

View workflow job for this annotation

GitHub Actions / dependency-review

undefined: ServerConfig

Check failure on line 75 in server/v2/server.go

View workflow job for this annotation

GitHub Actions / tests (01)

undefined: ServerConfig
}

func NewServer[T transaction.Tx](
config ServerConfig,

Check failure on line 79 in server/v2/server.go

View workflow job for this annotation

GitHub Actions / dependency-review

undefined: ServerConfig

Check failure on line 79 in server/v2/server.go

View workflow job for this annotation

GitHub Actions / tests (01)

undefined: ServerConfig
components ...ServerComponent[T],
) *Server[T] {
return &Server[T]{
config: config,
components: components,
}
}

func (s *Server[T]) Name() string {
return serverName
}

// Start starts all components concurrently.
func (s *Server[T]) Start(ctx context.Context) error {
logger := GetLoggerFromContext(ctx).With(log.ModuleKey, s.Name())

Check failure on line 94 in server/v2/server.go

View workflow job for this annotation

GitHub Actions / dependency-review

undefined: GetLoggerFromContext

Check failure on line 94 in server/v2/server.go

View workflow job for this annotation

GitHub Actions / tests (01)

undefined: GetLoggerFromContext
logger.Info("starting servers...")

resCh := make(chan error, len(s.components))
for _, mod := range s.components {
go func() {
resCh <- mod.Start(ctx)
}()
}

for i := 0; i < len(s.components); i++ {
select {
case err := <-resCh:
if err != nil {
return fmt.Errorf("failed to start servers: %w", err)
}
case <-ctx.Done():
return nil
}
}

<-ctx.Done()

return nil
}

// Stop stops all server components synchronously.
func (s *Server[T]) Stop(ctx context.Context) error {
logger := GetLoggerFromContext(ctx).With(log.ModuleKey, s.Name())

Check failure on line 122 in server/v2/server.go

View workflow job for this annotation

GitHub Actions / dependency-review

undefined: GetLoggerFromContext

Check failure on line 122 in server/v2/server.go

View workflow job for this annotation

GitHub Actions / tests (01)

undefined: GetLoggerFromContext
logger.Info("stopping servers...")

var err error
for _, mod := range s.components {
err = errors.Join(err, mod.Stop(ctx))
}

return err
}

// CLICommands returns all CLI commands of all components.
func (s *Server[T]) CLICommands() CLIConfig {
compart := func(name string, cmds ...*cobra.Command) *cobra.Command {
if len(cmds) == 1 && strings.HasPrefix(cmds[0].Use, name) {
return cmds[0]
}

subCmd := &cobra.Command{
Use: name,
Short: fmt.Sprintf("Commands from the %s server component", name),
}
subCmd.AddCommand(cmds...)

return subCmd
}

commands := CLIConfig{}
for _, mod := range s.components {
if climod, ok := mod.(HasCLICommands); ok {
srvCmd := climod.CLICommands()

if len(srvCmd.Commands) > 0 {
commands.Commands = append(commands.Commands, compart(mod.Name(), srvCmd.Commands...))
}

if len(srvCmd.Txs) > 0 {
commands.Txs = append(commands.Txs, compart(mod.Name(), srvCmd.Txs...))
}

if len(srvCmd.Queries) > 0 {
commands.Queries = append(commands.Queries, compart(mod.Name(), srvCmd.Queries...))
}
}
}

return commands
}

// Config returns config of the server component
func (s *Server[T]) Config() ServerConfig {

Check failure on line 172 in server/v2/server.go

View workflow job for this annotation

GitHub Actions / dependency-review

undefined: ServerConfig

Check failure on line 172 in server/v2/server.go

View workflow job for this annotation

GitHub Actions / tests (01)

undefined: 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)")

Check failure on line 196 in server/v2/server.go

View workflow job for this annotation

GitHub Actions / dependency-review

undefined: FlagMinGasPrices

Check failure on line 196 in server/v2/server.go

View workflow job for this annotation

GitHub Actions / tests (01)

undefined: FlagMinGasPrices
flags.String(FlagCPUProfiling, "", "Enable CPU profiling and write to the specified file")

Check failure on line 197 in server/v2/server.go

View workflow job for this annotation

GitHub Actions / dependency-review

undefined: FlagCPUProfiling

Check failure on line 197 in server/v2/server.go

View workflow job for this annotation

GitHub Actions / tests (01)

undefined: FlagCPUProfiling
flags.IntSlice(FlagUnsafeSkipUpgrades, []int{}, "Skip a set of upgrade heights to continue the old binary")

Check failure on line 198 in server/v2/server.go

View workflow job for this annotation

GitHub Actions / dependency-review

undefined: FlagUnsafeSkipUpgrades

Check failure on line 198 in server/v2/server.go

View workflow job for this annotation

GitHub Actions / tests (01)

undefined: FlagUnsafeSkipUpgrades

return flags
}

// WriteConfig writes the config to the given path.
// Note: it does not use viper.WriteConfigAs because we do not want to store flag values in the config.
func (s *Server[T]) WriteConfig(configPath string) error {
cfgs := s.Configs()
b, err := toml.Marshal(cfgs)
if err != nil {
return err
}

if _, err := os.Stat(configPath); os.IsNotExist(err) {
if err := os.MkdirAll(configPath, os.ModePerm); err != nil {
return err
}
}

if err := os.WriteFile(filepath.Join(configPath, "app.toml"), b, 0o600); err != nil {
return fmt.Errorf("failed to write config: %w", err)
}

for _, component := range s.components {
// undocumented interface to write the component default config in another file than app.toml
// it is used by cometbft for backward compatibility
// it should not be used by other components
if mod, ok := component.(interface{ WriteCustomConfigAt(string) error }); ok {
if err := mod.WriteCustomConfigAt(configPath); err != nil {
return err
}
}
}

return nil
}

// StartFlags returns all flags of all server components.
func (s *Server[T]) StartFlags() []*pflag.FlagSet {
flags := []*pflag.FlagSet{}

// add server component flags
flags = append(flags, s.StartCmdFlags())

// add other components' start cmd flags
for _, mod := range s.components {
if startmod, ok := mod.(HasStartFlags); ok {
flags = append(flags, startmod.StartCmdFlags())
}
}

return flags
}
15 changes: 15 additions & 0 deletions simapp/v2/app_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ import (
_ "cosmossdk.io/x/authz/module" // import for side-effects
_ "cosmossdk.io/x/bank" // import for side-effects
banktypes "cosmossdk.io/x/bank/types"
<<<<<<< HEAD
=======
_ "cosmossdk.io/x/bank/v2" // import for side-effects
>>>>>>> 064c9ba63 (feat(store/v2): build the migration manager in the root store factory (#22336))
_ "cosmossdk.io/x/circuit" // import for side-effects
circuittypes "cosmossdk.io/x/circuit/types"
_ "cosmossdk.io/x/consensus" // import for side-effects
Expand Down Expand Up @@ -153,6 +157,10 @@ var (
accounts.ModuleName,
authtypes.ModuleName,
banktypes.ModuleName,
<<<<<<< HEAD
=======
// bankv2types.ModuleName,
>>>>>>> 064c9ba63 (feat(store/v2): build the migration manager in the root store factory (#22336))
distrtypes.ModuleName,
stakingtypes.ModuleName,
slashingtypes.ModuleName,
Expand Down Expand Up @@ -293,6 +301,13 @@ var (
Name: epochstypes.ModuleName,
Config: appconfig.WrapAny(&epochsmodulev1.Module{}),
},
<<<<<<< HEAD
=======
// {
// Name: bankv2types.ModuleName,
// Config: appconfig.WrapAny(&bankmodulev2.Module{}),
// },
>>>>>>> 064c9ba63 (feat(store/v2): build the migration manager in the root store factory (#22336))
},
}
)
Loading

0 comments on commit 13a9cc7

Please sign in to comment.