From bb1f6d6280bf46fa08c43dde223103aa83cc6939 Mon Sep 17 00:00:00 2001 From: Troy Kessler <43882936+troykessler@users.noreply.github.com> Date: Wed, 13 Nov 2024 15:49:18 +0100 Subject: [PATCH] test: introduce e2e tests (#85) --- .github/workflows/main.yml | 17 +++++++ Dockerfile | 11 +++++ Makefile | 9 +++- blocksync/blocksync.go | 51 ++++++++------------ blocksync/executor.go | 2 +- cmd/ksync/commands/backup.go | 23 +++++---- cmd/ksync/commands/blocksync.go | 57 +++++++++++----------- cmd/ksync/commands/engines.go | 5 +- cmd/ksync/commands/heightsync.go | 52 ++++++++++---------- cmd/ksync/commands/info.go | 11 ++--- cmd/ksync/commands/resetall.go | 9 ++-- cmd/ksync/commands/root.go | 10 ++-- cmd/ksync/commands/serveblocks.go | 43 +++++++++-------- cmd/ksync/commands/servesnapshots.go | 45 +++++++++-------- cmd/ksync/commands/statesync.go | 32 ++++++------- cmd/ksync/commands/version.go | 5 +- engines/engines.go | 12 ++--- go.mod | 20 +++++--- go.sum | 47 ++++++++++-------- heightsync/heightsync.go | 72 ++++++++++++++++------------ servesnapshots/servesnapshots.go | 65 +++++++++++++------------ sources/version.go | 26 +++++----- statesync/executor.go | 4 +- statesync/statesync.go | 25 ++++------ tests/Dockerfile | 57 ++++++++++++++++++++++ tests/block_sync_test.bats | 39 +++++++++++++++ tests/height_sync_test.bats | 29 +++++++++++ tests/info_test.bats | 14 ++++++ tests/state_sync_test.bats | 24 ++++++++++ tests/version_test.bats | 4 ++ 30 files changed, 519 insertions(+), 301 deletions(-) create mode 100644 .github/workflows/main.yml create mode 100644 Dockerfile create mode 100644 tests/Dockerfile create mode 100644 tests/block_sync_test.bats create mode 100644 tests/height_sync_test.bats create mode 100644 tests/info_test.bats create mode 100644 tests/state_sync_test.bats create mode 100644 tests/version_test.bats diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..f5bec8d --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,17 @@ +name: ci + +on: + pull_request: + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and Test Docker Image + uses: docker/build-push-action@v6 + with: + platforms: linux/amd64 + tags: ksync:test diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ce922af --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +FROM kyve/ksync-e2e-tests:latest + +WORKDIR /app + +COPY go.mod go.sum ./ +RUN go mod download + +COPY . . + +RUN make build +RUN bats -T --print-output-on-failure --verbose-run tests diff --git a/Makefile b/Makefile index b99fc40..da15f64 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,13 @@ GO_VERSION := $(shell go version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f1,2) build: ensure_version go build -mod=readonly -o ./build/ksync ./cmd/ksync/main.go +############################################################################### +### Tests ### +############################################################################### + +test: + docker build --platform linux/amd64 --no-cache -t ksync:test . + ############################################################################### ### Checks ### ############################################################################### @@ -14,4 +21,4 @@ build: ensure_version ensure_version: ifneq ($(GO_VERSION),1.22) $(error ❌ Please run Go v1.22.x..) -endif \ No newline at end of file +endif diff --git a/blocksync/blocksync.go b/blocksync/blocksync.go index 883c802..0f5bea2 100644 --- a/blocksync/blocksync.go +++ b/blocksync/blocksync.go @@ -7,7 +7,6 @@ import ( "github.com/KYVENetwork/ksync/bootstrap" "github.com/KYVENetwork/ksync/types" "github.com/KYVENetwork/ksync/utils" - "os" "strings" "time" ) @@ -16,40 +15,31 @@ var ( logger = utils.KsyncLogger("block-sync") ) -func StartBlockSync(engine types.Engine, chainRest, storageRest string, blockRpcConfig *types.BlockRpcConfig, poolId *int64, targetHeight int64, backupCfg *types.BackupConfig) error { - return StartDBExecutor(engine, chainRest, storageRest, blockRpcConfig, poolId, targetHeight, 0, 0, false, false, backupCfg) -} - -func PerformBlockSyncValidationChecks(engine types.Engine, chainRest string, blockRpcConfig *types.BlockRpcConfig, blockPoolId *int64, targetHeight int64, checkEndHeight, userInput bool) (continuationHeight int64, err error) { - continuationHeight, err = engine.GetContinuationHeight() - if err != nil { - return continuationHeight, fmt.Errorf("failed to get continuation height from engine: %w", err) - } - +func PerformBlockSyncValidationChecks(chainRest string, blockRpcConfig *types.BlockRpcConfig, blockPoolId *int64, continuationHeight, targetHeight int64, checkEndHeight, userInput bool) error { logger.Info().Msg(fmt.Sprintf("loaded current block height of node: %d", continuationHeight-1)) // perform boundary checks _, startHeight, endHeight, err := helpers.GetBlockBoundaries(chainRest, blockRpcConfig, blockPoolId) if err != nil { - return continuationHeight, fmt.Errorf("failed to get block boundaries: %w", err) + return fmt.Errorf("failed to get block boundaries: %w", err) } logger.Info().Msg(fmt.Sprintf("retrieved block boundaries, earliest block height = %d, latest block height %d", startHeight, endHeight)) if continuationHeight < startHeight { - return continuationHeight, fmt.Errorf("app is currently at height %d but first available block on pool is %d", continuationHeight, startHeight) + return fmt.Errorf("app is currently at height %d but first available block on pool is %d", continuationHeight, startHeight) } if continuationHeight > endHeight { - return continuationHeight, fmt.Errorf("app is currently at height %d but last available block on pool is %d", continuationHeight, endHeight) + return fmt.Errorf("app is currently at height %d but last available block on pool is %d", continuationHeight, endHeight) } if targetHeight > 0 && continuationHeight > targetHeight { - return continuationHeight, fmt.Errorf("requested target height is %d but app is already at block height %d", targetHeight, continuationHeight) + return fmt.Errorf("requested target height is %d but app is already at block height %d", targetHeight, continuationHeight) } if checkEndHeight && targetHeight > 0 && targetHeight > endHeight { - return continuationHeight, fmt.Errorf("requested target height is %d but last available block on pool is %d", targetHeight, endHeight) + return fmt.Errorf("requested target height is %d but last available block on pool is %d", targetHeight, endHeight) } if targetHeight == 0 { @@ -66,34 +56,32 @@ func PerformBlockSyncValidationChecks(engine types.Engine, chainRest string, blo } if _, err := fmt.Scan(&answer); err != nil { - return continuationHeight, fmt.Errorf("failed to read in user input: %s", err) + return fmt.Errorf("failed to read in user input: %s", err) } if strings.ToLower(answer) != "y" { - return continuationHeight, errors.New("aborted block-sync") + return errors.New("aborted block-sync") } } - return + return nil } -func StartBlockSyncWithBinary(engine types.Engine, binaryPath, homePath, chainId, chainRest, storageRest string, blockRpcConfig *types.BlockRpcConfig, blockPoolId *int64, targetHeight int64, backupCfg *types.BackupConfig, appFlags string, rpcServer, optOut, debug bool) { +func StartBlockSyncWithBinary(engine types.Engine, binaryPath, homePath, chainId, chainRest, storageRest string, blockRpcConfig *types.BlockRpcConfig, blockPoolId *int64, targetHeight int64, backupCfg *types.BackupConfig, appFlags string, rpcServer, optOut, debug bool) error { logger.Info().Msg("starting block-sync") if err := bootstrap.StartBootstrapWithBinary(engine, binaryPath, homePath, chainRest, storageRest, blockRpcConfig, blockPoolId, appFlags, debug); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to bootstrap node: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to bootstrap node: %w", err) } // start binary process thread processId, err := utils.StartBinaryProcessForDB(engine, binaryPath, debug, strings.Split(appFlags, ",")) if err != nil { - panic(err) + return fmt.Errorf("failed to start binary process: %w", err) } if err := engine.OpenDBs(); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to open dbs in engine: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to open dbs in engine: %w", err) } if rpcServer { @@ -107,14 +95,15 @@ func StartBlockSyncWithBinary(engine types.Engine, binaryPath, homePath, chainId currentHeight := engine.GetHeight() // db executes blocks against app until target height is reached - if err := StartBlockSync(engine, chainRest, storageRest, blockRpcConfig, blockPoolId, targetHeight, backupCfg); err != nil { + if err := StartBlockSyncExecutor(engine, chainRest, storageRest, blockRpcConfig, blockPoolId, targetHeight, 0, 0, false, false, backupCfg); err != nil { logger.Error().Msg(fmt.Sprintf("%s", err)) // stop binary process thread if err := utils.StopProcessByProcessId(processId); err != nil { - panic(err) + return fmt.Errorf("failed to stop process by process id: %w", err) } - os.Exit(1) + + return fmt.Errorf("failed to start block-sync executor: %w", err) } elapsed := time.Since(start).Seconds() @@ -122,14 +111,14 @@ func StartBlockSyncWithBinary(engine types.Engine, binaryPath, homePath, chainId // stop binary process thread if err := utils.StopProcessByProcessId(processId); err != nil { - panic(err) + return fmt.Errorf("failed to stop process by process id: %w", err) } if err := engine.CloseDBs(); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to close dbs in engine: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to close dbs in engine: %w", err) } logger.Info().Msg(fmt.Sprintf("block-synced from %d to %d (%d blocks) in %.2f seconds", currentHeight, targetHeight, targetHeight-currentHeight, elapsed)) logger.Info().Msg(fmt.Sprintf("successfully finished block-sync")) + return nil } diff --git a/blocksync/executor.go b/blocksync/executor.go index 079a37b..4d56623 100644 --- a/blocksync/executor.go +++ b/blocksync/executor.go @@ -16,7 +16,7 @@ var ( errorCh = make(chan error) ) -func StartDBExecutor(engine types.Engine, chainRest, storageRest string, blockRpcConfig *types.BlockRpcConfig, blockPoolId *int64, targetHeight int64, snapshotPoolId, snapshotInterval int64, pruning, skipWaiting bool, backupCfg *types.BackupConfig) error { +func StartBlockSyncExecutor(engine types.Engine, chainRest, storageRest string, blockRpcConfig *types.BlockRpcConfig, blockPoolId *int64, targetHeight int64, snapshotPoolId, snapshotInterval int64, pruning, skipWaiting bool, backupCfg *types.BackupConfig) error { continuationHeight, err := engine.GetContinuationHeight() if err != nil { return fmt.Errorf("failed to get continuation height from engine: %w", err) diff --git a/cmd/ksync/commands/backup.go b/cmd/ksync/commands/backup.go index 25f1a92..67a6b46 100644 --- a/cmd/ksync/commands/backup.go +++ b/cmd/ksync/commands/backup.go @@ -25,13 +25,13 @@ func init() { backupCmd.Flags().BoolVar(&optOut, "opt-out", false, "disable the collection of anonymous usage data") - rootCmd.AddCommand(backupCmd) + RootCmd.AddCommand(backupCmd) } var backupCmd = &cobra.Command{ Use: "backup", Short: "Backup data directory", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { utils.TrackBackupEvent(backupCompression, backupKeepRecent, optOut) // if no home path was given get the default one @@ -42,8 +42,7 @@ var backupCmd = &cobra.Command{ // load tendermint config config, err := tendermint_v34.LoadConfig(homePath) if err != nil { - logger.Error().Str("err", err.Error()).Msg("failed to load config.toml") - return + return fmt.Errorf("failed to load config.toml: %w", err) } // load block store @@ -51,8 +50,7 @@ var backupCmd = &cobra.Command{ defer blockStoreDB.Close() if err != nil { - logger.Error().Str("err", err.Error()).Msg("failed to load blockstore db") - return + return fmt.Errorf("fail to load blockstore db: %w", err) } // load state store @@ -60,27 +58,28 @@ var backupCmd = &cobra.Command{ defer stateDB.Close() if err != nil { - logger.Error().Str("err", err.Error()).Msg("failed to load state db") - return + return fmt.Errorf("fail to load state db: %w", err) } // load genesis file defaultDocProvider := nm.DefaultGenesisDocProviderFunc(config) _, genDoc, err := nm.LoadStateFromDBOrGenesisDocProvider(stateDB, defaultDocProvider) + if err != nil { + return fmt.Errorf("fail to load state from database: %w", err) + } // create backup config backupCfg, err := backup.GetBackupConfig(homePath, 2, backupKeepRecent, backupCompression, backupDest) if err != nil { - logger.Error().Str("err", err.Error()).Msg("failed to create backup config") - return + return fmt.Errorf("fail to load backup config: %w", err) } // create backup if err = backup.CreateBackup(backupCfg, genDoc.ChainID, blockStore.Height(), false); err != nil { - logger.Error().Str("err", err.Error()).Msg("failed to create backup") - return + return fmt.Errorf("fail to create backup: %w", err) } logger.Info().Int64("height", blockStore.Height()).Msg("finished backup at block height") + return nil }, } diff --git a/cmd/ksync/commands/blocksync.go b/cmd/ksync/commands/blocksync.go index f5d9a33..ea2d130 100644 --- a/cmd/ksync/commands/blocksync.go +++ b/cmd/ksync/commands/blocksync.go @@ -1,6 +1,7 @@ package commands import ( + "errors" "fmt" "github.com/KYVENetwork/ksync/backup" "github.com/KYVENetwork/ksync/blocksync" @@ -8,7 +9,6 @@ import ( "github.com/KYVENetwork/ksync/sources" "github.com/KYVENetwork/ksync/utils" "github.com/spf13/cobra" - "os" "strings" ) @@ -46,29 +46,28 @@ func init() { blockSyncCmd.Flags().BoolVarP(&debug, "debug", "d", false, "show logs from tendermint app") blockSyncCmd.Flags().BoolVarP(&y, "yes", "y", false, "automatically answer yes for all questions") - rootCmd.AddCommand(blockSyncCmd) + RootCmd.AddCommand(blockSyncCmd) } var blockSyncCmd = &cobra.Command{ Use: "block-sync", Short: "Start fast syncing blocks with KSYNC", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { chainRest = utils.GetChainRest(chainId, chainRest) storageRest = strings.TrimSuffix(storageRest, "/") // if no binary was provided at least the home path needs to be defined if binaryPath == "" && homePath == "" { - logger.Error().Msg(fmt.Sprintf("flag 'home' is required")) - os.Exit(1) + return errors.New("flag 'home' is required") } if binaryPath == "" { - logger.Info().Msg("To start the syncing process, start your chain binary with --with-tendermint=false") + logger.Info().Msg("to start the syncing process, start your chain binary with --with-tendermint=false") } if homePath == "" { homePath = utils.GetHomePathFromBinary(binaryPath) - logger.Info().Msgf("Loaded home path \"%s\" from binary path", homePath) + logger.Info().Msgf("loaded home path \"%s\" from binary path", homePath) } defaultEngine := engines.EngineFactory(engine, homePath, rpcServerPort) @@ -76,58 +75,60 @@ var blockSyncCmd = &cobra.Command{ if source == "" && blockPoolId == "" { s, err := defaultEngine.GetChainId() if err != nil { - logger.Error().Msgf("Failed to load chain-id from engine: %s", err.Error()) - os.Exit(1) + return fmt.Errorf("failed to load chain-id from engine: %w", err) } source = s - logger.Info().Msgf("Loaded source \"%s\" from genesis file", source) + logger.Info().Msgf("loaded source \"%s\" from genesis file", source) } if engine == "" && binaryPath != "" { engine = utils.GetEnginePathFromBinary(binaryPath) - logger.Info().Msgf("Loaded engine \"%s\" from binary path", engine) + logger.Info().Msgf("loaded engine \"%s\" from binary path", engine) } bId, _, err := sources.GetPoolIds(chainId, source, blockPoolId, "", registryUrl, true, false) if err != nil { - logger.Error().Msg(fmt.Sprintf("failed to load pool-ids: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to load pool-ids: %w", err) } backupCfg, err := backup.GetBackupConfig(homePath, backupInterval, backupKeepRecent, backupCompression, backupDest) if err != nil { - logger.Error().Str("err", err.Error()).Msg("could not get backup config") - return + return fmt.Errorf("could not get backup config: %w", err) } if reset { if err := defaultEngine.ResetAll(true); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to reset tendermint application: %s", err)) - os.Exit(1) + return fmt.Errorf("could not reset tendermint application: %w", err) } } if err := defaultEngine.OpenDBs(); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to open dbs in engine: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to open dbs in engine: %w", err) } - // perform validation checks before booting state-sync process - continuationHeight, err := blocksync.PerformBlockSyncValidationChecks(defaultEngine, chainRest, nil, &bId, targetHeight, true, !y) + continuationHeight, err := defaultEngine.GetContinuationHeight() if err != nil { - logger.Error().Msg(fmt.Sprintf("block-sync validation checks failed: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to get continuation height: %w", err) + } + + // perform validation checks before booting state-sync process + if err := blocksync.PerformBlockSyncValidationChecks(chainRest, nil, &bId, continuationHeight, targetHeight, true, !y); err != nil { + return fmt.Errorf("block-sync validation checks failed: %w", err) } if err := defaultEngine.CloseDBs(); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to close dbs in engine: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to close dbs in engine: %w", err) } - sources.IsBinaryRecommendedVersion(binaryPath, registryUrl, source, continuationHeight, !y) + if err := sources.IsBinaryRecommendedVersion(binaryPath, registryUrl, source, continuationHeight, !y); err != nil { + return fmt.Errorf("failed to check if binary has the recommended version: %w", err) + } - consensusEngine := engines.EngineSourceFactory(engine, homePath, registryUrl, source, rpcServerPort, continuationHeight) + consensusEngine, err := engines.EngineSourceFactory(engine, homePath, registryUrl, source, rpcServerPort, continuationHeight) + if err != nil { + return fmt.Errorf("failed to create consensus engine for source: %w", err) + } - blocksync.StartBlockSyncWithBinary(consensusEngine, binaryPath, homePath, chainId, chainRest, storageRest, nil, &bId, targetHeight, backupCfg, appFlags, rpcServer, optOut, debug) + return blocksync.StartBlockSyncWithBinary(consensusEngine, binaryPath, homePath, chainId, chainRest, storageRest, nil, &bId, targetHeight, backupCfg, appFlags, rpcServer, optOut, debug) }, } diff --git a/cmd/ksync/commands/engines.go b/cmd/ksync/commands/engines.go index e6f09e1..8da2006 100644 --- a/cmd/ksync/commands/engines.go +++ b/cmd/ksync/commands/engines.go @@ -9,17 +9,18 @@ import ( func init() { enginesCmd.Flags().BoolVar(&optOut, "opt-out", false, "disable the collection of anonymous usage data") - rootCmd.AddCommand(enginesCmd) + RootCmd.AddCommand(enginesCmd) } var enginesCmd = &cobra.Command{ Use: "engines", Short: "Print all available engines for KSYNC", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { utils.TrackEnginesEvent(optOut) fmt.Printf("%s - %s\n", utils.EngineTendermintV34, "github.com/tendermint/tendermint v0.34.x") fmt.Printf("%s - %s\n", utils.EngineCometBFTV37, "github.com/cometbft/cometbft v0.37.x") fmt.Printf("%s - %s\n", utils.EngineCometBFTV38, "github.com/cometbft/cometbft v0.38.x") fmt.Printf("%s - %s\n", utils.EngineCelestiaCoreV34, "github.com/celestiaorg/celestia-core v0.34.x-celestia") + return nil }, } diff --git a/cmd/ksync/commands/heightsync.go b/cmd/ksync/commands/heightsync.go index 175c7c2..3825e74 100644 --- a/cmd/ksync/commands/heightsync.go +++ b/cmd/ksync/commands/heightsync.go @@ -1,6 +1,7 @@ package commands import ( + "errors" "fmt" "github.com/KYVENetwork/ksync/blocksync" blocksyncHelpers "github.com/KYVENetwork/ksync/blocksync/helpers" @@ -9,7 +10,6 @@ import ( "github.com/KYVENetwork/ksync/sources" "github.com/KYVENetwork/ksync/utils" "github.com/spf13/cobra" - "os" "strings" ) @@ -40,20 +40,19 @@ func init() { heightSyncCmd.Flags().BoolVarP(&debug, "debug", "d", false, "show logs from tendermint app") heightSyncCmd.Flags().BoolVarP(&y, "assumeyes", "y", false, "automatically answer yes for all questions") - rootCmd.AddCommand(heightSyncCmd) + RootCmd.AddCommand(heightSyncCmd) } var heightSyncCmd = &cobra.Command{ Use: "height-sync", Short: "Sync fast to any height with state- and block-sync", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { chainRest = utils.GetChainRest(chainId, chainRest) storageRest = strings.TrimSuffix(storageRest, "/") // if no binary was provided at least the home path needs to be defined if binaryPath == "" && homePath == "" { - logger.Error().Msg(fmt.Sprintf("flag 'home' is required")) - os.Exit(1) + return errors.New("flag 'home' is required") } if binaryPath == "" { @@ -75,8 +74,7 @@ var heightSyncCmd = &cobra.Command{ if source == "" && blockPoolId == "" && snapshotPoolId == "" { s, err := defaultEngine.GetChainId() if err != nil { - logger.Error().Msgf("Failed to load chain-id from engine: %s", err.Error()) - os.Exit(1) + return fmt.Errorf("failed to load chain-id from engine: %w", err) } source = s logger.Info().Msgf("Loaded source \"%s\" from genesis file", source) @@ -84,26 +82,22 @@ var heightSyncCmd = &cobra.Command{ bId, sId, err := sources.GetPoolIds(chainId, source, blockPoolId, snapshotPoolId, registryUrl, true, true) if err != nil { - logger.Error().Msg(fmt.Sprintf("failed to load pool-ids: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to load pool-ids: %w", err) } if reset { if err := defaultEngine.ResetAll(true); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to reset tendermint application: %s", err)) - os.Exit(1) + return fmt.Errorf("could not reset tendermint application: %w", err) } } if err := defaultEngine.OpenDBs(); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to open dbs in engine: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to open dbs in engine: %w", err) } _, _, blockEndHeight, err := blocksyncHelpers.GetBlockBoundaries(chainRest, nil, &bId) if err != nil { - logger.Error().Msg(fmt.Sprintf("failed to get block boundaries: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to get block boundaries: %w", err) } // if target height was not specified we sync to the latest available height @@ -115,29 +109,35 @@ var heightSyncCmd = &cobra.Command{ // perform validation checks before booting state-sync process snapshotBundleId, snapshotHeight, err := heightsync.PerformHeightSyncValidationChecks(defaultEngine, chainRest, sId, &bId, targetHeight, !y) if err != nil { - logger.Error().Msg(fmt.Sprintf("block-sync validation checks failed: %s", err)) - os.Exit(1) + return fmt.Errorf("height-sync validation checks failed: %w", err) } continuationHeight := snapshotHeight - if continuationHeight == 0 { - continuationHeight, err = blocksync.PerformBlockSyncValidationChecks(defaultEngine, chainRest, nil, &bId, targetHeight, true, false) + c, err := defaultEngine.GetContinuationHeight() if err != nil { - logger.Error().Msg(fmt.Sprintf("block-sync validation checks failed: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to get continuation height: %w", err) } + continuationHeight = c + } + + if err := blocksync.PerformBlockSyncValidationChecks(chainRest, nil, &bId, continuationHeight, targetHeight, true, false); err != nil { + return fmt.Errorf("block-sync validation checks failed: %w", err) } if err := defaultEngine.CloseDBs(); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to close dbs in engine: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to close dbs in engine: %w", err) } - sources.IsBinaryRecommendedVersion(binaryPath, registryUrl, source, continuationHeight, !y) + if err := sources.IsBinaryRecommendedVersion(binaryPath, registryUrl, source, continuationHeight, !y); err != nil { + return fmt.Errorf("failed to check if binary has the recommended version: %w", err) + } - consensusEngine := engines.EngineSourceFactory(engine, homePath, registryUrl, source, rpcServerPort, continuationHeight) + consensusEngine, err := engines.EngineSourceFactory(engine, homePath, registryUrl, source, rpcServerPort, continuationHeight) + if err != nil { + return fmt.Errorf("failed to create consensus engine for source: %w", err) + } - heightsync.StartHeightSyncWithBinary(consensusEngine, binaryPath, homePath, chainId, chainRest, storageRest, sId, &bId, targetHeight, snapshotBundleId, snapshotHeight, appFlags, optOut, debug) + return heightsync.StartHeightSyncWithBinary(consensusEngine, binaryPath, homePath, chainId, chainRest, storageRest, sId, &bId, targetHeight, snapshotBundleId, snapshotHeight, appFlags, optOut, debug) }, } diff --git a/cmd/ksync/commands/info.go b/cmd/ksync/commands/info.go index 7908815..45cfefb 100644 --- a/cmd/ksync/commands/info.go +++ b/cmd/ksync/commands/info.go @@ -21,24 +21,22 @@ func init() { infoCmd.Flags().BoolVar(&optOut, "opt-out", false, "disable the collection of anonymous usage data") - rootCmd.AddCommand(infoCmd) + RootCmd.AddCommand(infoCmd) } var infoCmd = &cobra.Command{ Use: "info", Short: "Get KSYNC chain support information", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { utils.TrackInfoEvent(chainId, optOut) if chainId != utils.ChainIdMainnet && chainId != utils.ChainIdKaon { - logger.Error().Str("chain-id", chainId).Msg("chain information not supported") - return + return fmt.Errorf("chain-id %s not supported", chainId) } sourceRegistry, err := helpers.GetSourceRegistry(registryUrl) if err != nil { - logger.Error().Str("err", err.Error()).Msg("failed to get source registry") - return + return fmt.Errorf("failed to get source registry: %w", err) } // Sort SourceRegistry @@ -117,5 +115,6 @@ var infoCmd = &cobra.Command{ t.SetStyle(table.StyleRounded) t.Render() + return nil }, } diff --git a/cmd/ksync/commands/resetall.go b/cmd/ksync/commands/resetall.go index 003fe14..f9d2885 100644 --- a/cmd/ksync/commands/resetall.go +++ b/cmd/ksync/commands/resetall.go @@ -5,7 +5,6 @@ import ( "github.com/KYVENetwork/ksync/engines" "github.com/KYVENetwork/ksync/utils" "github.com/spf13/cobra" - "os" ) func init() { @@ -20,20 +19,20 @@ func init() { resetCmd.Flags().BoolVar(&optOut, "opt-out", false, "disable the collection of anonymous usage data") - rootCmd.AddCommand(resetCmd) + RootCmd.AddCommand(resetCmd) } var resetCmd = &cobra.Command{ Use: "reset-all", Short: "Removes all the data and WAL, reset this node's validator to genesis state", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { utils.TrackResetEvent(optOut) if err := engines.EngineFactory(engine, homePath, rpcServerPort).ResetAll(keepAddrBook); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to reset tendermint application: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to reset tendermint application: %w", err) } logger.Info().Msg("successfully reset tendermint application") + return nil }, } diff --git a/cmd/ksync/commands/root.go b/cmd/ksync/commands/root.go index ea10d18..a46c26d 100644 --- a/cmd/ksync/commands/root.go +++ b/cmd/ksync/commands/root.go @@ -1,9 +1,9 @@ package commands import ( - "fmt" "github.com/KYVENetwork/ksync/utils" "github.com/spf13/cobra" + "os" ) var ( @@ -44,7 +44,7 @@ var ( ) // RootCmd is the root command for KSYNC. -var rootCmd = &cobra.Command{ +var RootCmd = &cobra.Command{ Use: "ksync", Short: "Fast Sync validated and archived blocks from KYVE to every Tendermint based Blockchain Application", } @@ -61,9 +61,9 @@ func Execute() { versionCmd.Flags().SortFlags = false // overwrite help command so we can use -h as a shortcut - rootCmd.PersistentFlags().BoolP("help", "", false, "help for this command") + RootCmd.PersistentFlags().BoolP("help", "", false, "help for this command") - if err := rootCmd.Execute(); err != nil { - panic(fmt.Errorf("failed to execute root command: %w", err)) + if err := RootCmd.Execute(); err != nil { + os.Exit(1) } } diff --git a/cmd/ksync/commands/serveblocks.go b/cmd/ksync/commands/serveblocks.go index d622e0f..8d9e668 100644 --- a/cmd/ksync/commands/serveblocks.go +++ b/cmd/ksync/commands/serveblocks.go @@ -5,10 +5,10 @@ import ( "github.com/KYVENetwork/ksync/backup" "github.com/KYVENetwork/ksync/blocksync" "github.com/KYVENetwork/ksync/engines" + "github.com/KYVENetwork/ksync/sources" "github.com/KYVENetwork/ksync/types" "github.com/KYVENetwork/ksync/utils" "github.com/spf13/cobra" - "os" "time" ) @@ -44,13 +44,13 @@ func init() { serveBlocksCmd.Flags().BoolVarP(&debug, "debug", "d", false, "show logs from tendermint app") serveBlocksCmd.Flags().BoolVarP(&y, "yes", "y", false, "automatically answer yes for all questions") - rootCmd.AddCommand(serveBlocksCmd) + RootCmd.AddCommand(serveBlocksCmd) } var serveBlocksCmd = &cobra.Command{ Use: "serve-blocks", Short: "Start fast syncing blocks from RPC endpoints with KSYNC", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { chainRest = "" storageRest = "" @@ -74,8 +74,7 @@ var serveBlocksCmd = &cobra.Command{ if source == "" && blockPoolId == "" { s, err := defaultEngine.GetChainId() if err != nil { - logger.Error().Msgf("Failed to load chain-id from engine: %s", err.Error()) - os.Exit(1) + return fmt.Errorf("failed to load chain-id from engine: %w", err) } source = s logger.Info().Msgf("Loaded source \"%s\" from genesis file", source) @@ -83,36 +82,42 @@ var serveBlocksCmd = &cobra.Command{ backupCfg, err := backup.GetBackupConfig(homePath, backupInterval, backupKeepRecent, backupCompression, backupDest) if err != nil { - logger.Error().Str("err", err.Error()).Msg("could not get backup config") - return + return fmt.Errorf("could not get backup config: %w", err) } if reset { if err := defaultEngine.ResetAll(true); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to reset tendermint application: %s", err)) - os.Exit(1) + return fmt.Errorf("could not reset tendermint application: %w", err) } } if err := defaultEngine.OpenDBs(); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to open dbs in engine: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to open dbs in engine: %w", err) } - // perform validation checks before booting block-sync process - continuationHeight, err := blocksync.PerformBlockSyncValidationChecks(defaultEngine, chainRest, &blockRpcConfig, nil, targetHeight, true, !y) + continuationHeight, err := defaultEngine.GetContinuationHeight() if err != nil { - logger.Error().Msg(fmt.Sprintf("block-sync validation checks failed: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to get continuation height: %w", err) + } + + // perform validation checks before booting block-sync process + if err := blocksync.PerformBlockSyncValidationChecks(chainRest, &blockRpcConfig, nil, continuationHeight, targetHeight, true, !y); err != nil { + return fmt.Errorf("block-sync validation checks failed: %w", err) } if err := defaultEngine.CloseDBs(); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to close dbs in engine: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to close dbs in engine: %w", err) } - consensusEngine := engines.EngineSourceFactory(engine, homePath, registryUrl, source, rpcServerPort, continuationHeight) + if err := sources.IsBinaryRecommendedVersion(binaryPath, registryUrl, source, continuationHeight, !y); err != nil { + return fmt.Errorf("failed to check if binary has the recommended version: %w", err) + } + + consensusEngine, err := engines.EngineSourceFactory(engine, homePath, registryUrl, source, rpcServerPort, continuationHeight) + if err != nil { + return fmt.Errorf("failed to create consensus engine for source: %w", err) + } - blocksync.StartBlockSyncWithBinary(consensusEngine, binaryPath, homePath, chainId, chainRest, storageRest, &blockRpcConfig, nil, targetHeight, backupCfg, appFlags, rpcServer, optOut, debug) + return blocksync.StartBlockSyncWithBinary(consensusEngine, binaryPath, homePath, chainId, chainRest, storageRest, &blockRpcConfig, nil, targetHeight, backupCfg, appFlags, rpcServer, optOut, debug) }, } diff --git a/cmd/ksync/commands/servesnapshots.go b/cmd/ksync/commands/servesnapshots.go index 5e8d181..2078a7f 100644 --- a/cmd/ksync/commands/servesnapshots.go +++ b/cmd/ksync/commands/servesnapshots.go @@ -8,7 +8,6 @@ import ( "github.com/KYVENetwork/ksync/sources" "github.com/KYVENetwork/ksync/utils" "github.com/spf13/cobra" - "os" "strings" ) @@ -51,13 +50,13 @@ func init() { servesnapshotsCmd.Flags().BoolVar(&optOut, "opt-out", false, "disable the collection of anonymous usage data") servesnapshotsCmd.Flags().BoolVarP(&debug, "debug", "d", false, "show logs from tendermint app") - rootCmd.AddCommand(servesnapshotsCmd) + RootCmd.AddCommand(servesnapshotsCmd) } var servesnapshotsCmd = &cobra.Command{ Use: "serve-snapshots", Short: "Serve snapshots for running KYVE state-sync pools", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { chainRest = utils.GetChainRest(chainId, chainRest) storageRest = strings.TrimSuffix(storageRest, "/") @@ -76,8 +75,7 @@ var servesnapshotsCmd = &cobra.Command{ if source == "" && blockPoolId == "" && snapshotPoolId == "" { s, err := defaultEngine.GetChainId() if err != nil { - logger.Error().Msgf("Failed to load chain-id from engine: %s", err.Error()) - os.Exit(1) + return fmt.Errorf("failed to close dbs in engine: %w", err) } source = s logger.Info().Msgf("Loaded source \"%s\" from genesis file", source) @@ -85,49 +83,54 @@ var servesnapshotsCmd = &cobra.Command{ bId, sId, err := sources.GetPoolIds(chainId, source, blockPoolId, snapshotPoolId, registryUrl, true, true) if err != nil { - logger.Error().Msg(fmt.Sprintf("failed to load pool-ids: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to load pool-ids: %w", err) } if reset { if err := defaultEngine.ResetAll(true); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to reset tendermint application: %s", err)) - os.Exit(1) + return fmt.Errorf("could not reset tendermint application: %w", err) } } if err := defaultEngine.OpenDBs(); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to open dbs in engine: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to open dbs in engine: %w", err) } // perform validation checks before booting state-sync process snapshotBundleId, snapshotHeight, err := servesnapshots.PerformServeSnapshotsValidationChecks(defaultEngine, chainRest, sId, bId, startHeight, targetHeight) if err != nil { - logger.Error().Msg(fmt.Sprintf("block-sync validation checks failed: %s", err)) - os.Exit(1) + return fmt.Errorf("serve-snapshots validation checks failed: %w", err) } height := defaultEngine.GetHeight() continuationHeight := snapshotHeight - if continuationHeight == 0 { - continuationHeight, err = blocksync.PerformBlockSyncValidationChecks(defaultEngine, chainRest, nil, &bId, targetHeight, false, false) + c, err := defaultEngine.GetContinuationHeight() if err != nil { - logger.Error().Msg(fmt.Sprintf("block-sync validation checks failed: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to get continuation height: %w", err) } + continuationHeight = c + } + + if err := blocksync.PerformBlockSyncValidationChecks(chainRest, nil, &bId, continuationHeight, targetHeight, true, false); err != nil { + return fmt.Errorf("block-sync validation checks failed: %w", err) } utils.TrackServeSnapshotsEvent(defaultEngine, chainId, chainRest, storageRest, snapshotPort, rpcServer, rpcServerPort, startHeight, pruning, keepSnapshots, debug, optOut) if err := defaultEngine.CloseDBs(); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to close dbs in engine: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to close dbs in engine: %w", err) } - consensusEngine := engines.EngineSourceFactory(engine, homePath, registryUrl, source, rpcServerPort, continuationHeight) + if err := sources.IsBinaryRecommendedVersion(binaryPath, registryUrl, source, continuationHeight, !y); err != nil { + return fmt.Errorf("failed to check if binary has the recommended version: %w", err) + } + + consensusEngine, err := engines.EngineSourceFactory(engine, homePath, registryUrl, source, rpcServerPort, continuationHeight) + if err != nil { + return fmt.Errorf("failed to create consensus engine for source: %w", err) + } - servesnapshots.StartServeSnapshotsWithBinary(consensusEngine, binaryPath, homePath, chainRest, storageRest, &bId, sId, targetHeight, height, snapshotBundleId, snapshotHeight, snapshotPort, appFlags, rpcServer, pruning, keepSnapshots, skipWaiting, debug) + return servesnapshots.StartServeSnapshotsWithBinary(consensusEngine, binaryPath, homePath, chainRest, storageRest, &bId, sId, targetHeight, height, snapshotBundleId, snapshotHeight, snapshotPort, appFlags, rpcServer, pruning, keepSnapshots, skipWaiting, debug) }, } diff --git a/cmd/ksync/commands/statesync.go b/cmd/ksync/commands/statesync.go index d2337d4..b796c04 100644 --- a/cmd/ksync/commands/statesync.go +++ b/cmd/ksync/commands/statesync.go @@ -1,13 +1,13 @@ package commands import ( + "errors" "fmt" "github.com/KYVENetwork/ksync/engines" "github.com/KYVENetwork/ksync/sources" "github.com/KYVENetwork/ksync/statesync" "github.com/KYVENetwork/ksync/utils" "github.com/spf13/cobra" - "os" "strings" ) @@ -37,20 +37,19 @@ func init() { stateSyncCmd.Flags().BoolVarP(&debug, "debug", "d", false, "show logs from tendermint app") stateSyncCmd.Flags().BoolVarP(&y, "yes", "y", false, "automatically answer yes for all questions") - rootCmd.AddCommand(stateSyncCmd) + RootCmd.AddCommand(stateSyncCmd) } var stateSyncCmd = &cobra.Command{ Use: "state-sync", Short: "Apply a state-sync snapshot", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { chainRest = utils.GetChainRest(chainId, chainRest) storageRest = strings.TrimSuffix(storageRest, "/") // if no binary was provided at least the home path needs to be defined if binaryPath == "" && homePath == "" { - logger.Error().Msg(fmt.Sprintf("flag 'home' is required")) - os.Exit(1) + return errors.New("flag 'home' is required") } if binaryPath == "" { @@ -72,8 +71,7 @@ var stateSyncCmd = &cobra.Command{ if source == "" && snapshotPoolId == "" { s, err := defaultEngine.GetChainId() if err != nil { - logger.Error().Msgf("Failed to load chain-id from engine: %s", err.Error()) - os.Exit(1) + return fmt.Errorf("failed to load chain-id from engine: %w", err) } source = s logger.Info().Msgf("Loaded source \"%s\" from genesis file", source) @@ -81,28 +79,30 @@ var stateSyncCmd = &cobra.Command{ _, sId, err := sources.GetPoolIds(chainId, source, "", snapshotPoolId, registryUrl, false, true) if err != nil { - logger.Error().Msg(fmt.Sprintf("failed to load pool-ids: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to load pool-ids: %w", err) } if reset { if err := defaultEngine.ResetAll(true); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to reset tendermint application: %s", err)) - os.Exit(1) + return fmt.Errorf("could not reset tendermint application: %w", err) } } // perform validation checks before booting state-sync process snapshotBundleId, snapshotHeight, err := statesync.PerformStateSyncValidationChecks(chainRest, sId, targetHeight, !y) if err != nil { - logger.Error().Msg(fmt.Sprintf("state-sync validation checks failed: %s", err)) - os.Exit(1) + return fmt.Errorf("state-sync validation checks failed: %w", err) } - sources.IsBinaryRecommendedVersion(binaryPath, registryUrl, source, snapshotHeight, !y) + if err := sources.IsBinaryRecommendedVersion(binaryPath, registryUrl, source, snapshotHeight, !y); err != nil { + return fmt.Errorf("failed to check if binary has the recommended version: %w", err) + } - consensusEngine := engines.EngineSourceFactory(engine, homePath, registryUrl, source, rpcServerPort, snapshotHeight) + consensusEngine, err := engines.EngineSourceFactory(engine, homePath, registryUrl, source, rpcServerPort, snapshotHeight) + if err != nil { + return fmt.Errorf("failed to create consensus engine for source: %w", err) + } - statesync.StartStateSyncWithBinary(consensusEngine, binaryPath, chainId, chainRest, storageRest, sId, targetHeight, snapshotBundleId, snapshotHeight, appFlags, optOut, debug) + return statesync.StartStateSyncWithBinary(consensusEngine, binaryPath, chainId, chainRest, storageRest, sId, targetHeight, snapshotBundleId, snapshotHeight, appFlags, optOut, debug) }, } diff --git a/cmd/ksync/commands/version.go b/cmd/ksync/commands/version.go index fef2558..859f1af 100644 --- a/cmd/ksync/commands/version.go +++ b/cmd/ksync/commands/version.go @@ -9,14 +9,15 @@ import ( func init() { versionCmd.Flags().BoolVar(&optOut, "opt-out", false, "disable the collection of anonymous usage data") - rootCmd.AddCommand(versionCmd) + RootCmd.AddCommand(versionCmd) } var versionCmd = &cobra.Command{ Use: "version", Short: "Print the version of KSYNC", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { utils.TrackVersionEvent(optOut) fmt.Println(utils.GetVersion()) + return nil }, } diff --git a/engines/engines.go b/engines/engines.go index 28f7dd7..8811001 100644 --- a/engines/engines.go +++ b/engines/engines.go @@ -17,23 +17,21 @@ var ( logger = utils.KsyncLogger("engines") ) -func EngineSourceFactory(engine, homePath, registryUrl, source string, rpcServerPort, continuationHeight int64) types.Engine { +func EngineSourceFactory(engine, homePath, registryUrl, source string, rpcServerPort, continuationHeight int64) (types.Engine, error) { // if the engine was specified by the user or the source is empty we determine the engine by the engine input if engine != "" || source == "" { - return EngineFactory(engine, homePath, rpcServerPort) + return EngineFactory(engine, homePath, rpcServerPort), nil } entry, err := helpers.GetSourceRegistryEntry(registryUrl, source) if err != nil { - logger.Error().Msg(fmt.Sprintf("failed to get source registry entry: %s", err)) - os.Exit(1) + return nil, fmt.Errorf("failed to get source registry entry: %w", err) } for _, upgrade := range entry.Codebase.Settings.Upgrades { height, err := strconv.ParseInt(upgrade.Height, 10, 64) if err != nil { - logger.Error().Msg(fmt.Sprintf("failed to parse upgrade height %s: %s", upgrade.Height, err)) - os.Exit(1) + return nil, fmt.Errorf("failed to parse upgrade height %s: %w", upgrade.Height, err) } if continuationHeight < height { @@ -44,7 +42,7 @@ func EngineSourceFactory(engine, homePath, registryUrl, source string, rpcServer } logger.Info().Msg(fmt.Sprintf("using \"%s\" as consensus engine", engine)) - return EngineFactory(engine, homePath, rpcServerPort) + return EngineFactory(engine, homePath, rpcServerPort), nil } func EngineFactory(engine, homePath string, rpcServerPort int64) types.Engine { diff --git a/go.mod b/go.mod index 0817bfe..7ac1b49 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,8 @@ require ( github.com/gin-gonic/gin v1.9.1 github.com/google/uuid v1.4.0 github.com/jedib0t/go-pretty/v6 v6.4.7 + github.com/onsi/ginkgo/v2 v2.21.0 + github.com/onsi/gomega v1.34.2 github.com/rs/zerolog v1.30.0 github.com/segmentio/analytics-go v3.1.0+incompatible github.com/spf13/cobra v1.8.0 @@ -17,6 +19,7 @@ require ( github.com/tendermint/tendermint v0.34.14 github.com/tendermint/tm-db v0.6.7 gopkg.in/yaml.v2 v2.4.0 + gotest.tools v2.2.0+incompatible ) require ( @@ -46,11 +49,12 @@ require ( github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect - github.com/go-logr/logr v1.3.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.14.0 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.1.2 // indirect @@ -59,6 +63,7 @@ require ( github.com/google/btree v1.1.2 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/orderedcode v0.0.1 // indirect + github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grafana/otel-profiling-go v0.5.1 // indirect github.com/grafana/pyroscope-go v1.1.1 // indirect @@ -119,15 +124,16 @@ require ( go.opentelemetry.io/otel/trace v1.21.0 // indirect go.uber.org/multierr v1.10.0 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.21.0 // indirect + golang.org/x/crypto v0.28.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/sync v0.5.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/net v0.30.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect + golang.org/x/tools v0.26.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect google.golang.org/grpc v1.60.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index b225ecd..a16ad47 100644 --- a/go.sum +++ b/go.sum @@ -233,8 +233,9 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= @@ -247,6 +248,8 @@ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -306,6 +309,8 @@ github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -495,11 +500,14 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= +github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= +github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -763,8 +771,8 @@ golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +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= @@ -788,8 +796,8 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -818,8 +826,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -830,8 +838,8 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -885,8 +893,8 @@ golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBc 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.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.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-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -894,8 +902,8 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +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-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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= @@ -926,14 +934,12 @@ golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -985,8 +991,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 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= @@ -1016,6 +1022,7 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/heightsync/heightsync.go b/heightsync/heightsync.go index e9bd01d..834b69e 100644 --- a/heightsync/heightsync.go +++ b/heightsync/heightsync.go @@ -7,7 +7,6 @@ import ( "github.com/KYVENetwork/ksync/statesync" "github.com/KYVENetwork/ksync/types" "github.com/KYVENetwork/ksync/utils" - "os" "strings" "time" ) @@ -19,9 +18,24 @@ var ( // PerformHeightSyncValidationChecks checks if the targetHeight lies in the range of available blocks and checks // if a state-sync snapshot is available right before the targetHeight func PerformHeightSyncValidationChecks(engine types.Engine, chainRest string, snapshotPoolId int64, blockPoolId *int64, targetHeight int64, userInput bool) (snapshotBundleId, snapshotHeight int64, err error) { - if _, err := blocksync.PerformBlockSyncValidationChecks(engine, chainRest, nil, blockPoolId, targetHeight, true, false); err != nil { - logger.Error().Msg(fmt.Sprintf("block-sync validation checks failed: %s", err)) - os.Exit(1) + height := engine.GetHeight() + + // only if the app has not indexed any blocks yet we state-sync to the specified startHeight + if height == 0 { + snapshotBundleId, snapshotHeight, _ = statesync.PerformStateSyncValidationChecks(chainRest, snapshotPoolId, targetHeight, false) + } + + continuationHeight := snapshotHeight + if continuationHeight == 0 { + c, err := engine.GetContinuationHeight() + if err != nil { + return 0, 0, fmt.Errorf("failed to get continuation height: %w", err) + } + continuationHeight = c + } + + if err := blocksync.PerformBlockSyncValidationChecks(chainRest, nil, blockPoolId, continuationHeight, targetHeight, true, false); err != nil { + return 0, 0, fmt.Errorf("block-sync validation checks failed: %w", err) } // we ignore if the state-sync validation checks fail because if there are no available snapshots we simply block-sync @@ -37,20 +51,18 @@ func PerformHeightSyncValidationChecks(engine types.Engine, chainRest string, sn } if _, err := fmt.Scan(&answer); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to read in user input: %s", err)) - os.Exit(1) + return 0, 0, fmt.Errorf("failed to read in user input: %w", err) } if strings.ToLower(answer) != "y" { - logger.Error().Msg("aborted state-sync") - os.Exit(0) + return 0, 0, fmt.Errorf("aborted state-sync") } } return } -func StartHeightSyncWithBinary(engine types.Engine, binaryPath, homePath, chainId, chainRest, storageRest string, snapshotPoolId int64, blockPoolId *int64, targetHeight, snapshotBundleId, snapshotHeight int64, appFlags string, optOut, debug bool) { +func StartHeightSyncWithBinary(engine types.Engine, binaryPath, homePath, chainId, chainRest, storageRest string, snapshotPoolId int64, blockPoolId *int64, targetHeight, snapshotBundleId, snapshotHeight int64, appFlags string, optOut, debug bool) error { logger.Info().Msg("starting height-sync") start := time.Now() @@ -63,42 +75,40 @@ func StartHeightSyncWithBinary(engine types.Engine, binaryPath, homePath, chainI // start binary process thread processId, err = utils.StartBinaryProcessForDB(engine, binaryPath, debug, args) if err != nil { - panic(err) + return fmt.Errorf("failed to start binary process: %w", err) } if err := engine.OpenDBs(); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to open dbs in engine: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to open dbs in engine: %w", err) } utils.TrackSyncStartEvent(engine, utils.HEIGHT_SYNC, chainId, chainRest, storageRest, targetHeight, optOut) // apply state sync snapshot - if err := statesync.StartStateSync(engine, chainRest, storageRest, snapshotPoolId, snapshotBundleId); err != nil { + if err := statesync.StartStateSyncExecutor(engine, chainRest, storageRest, snapshotPoolId, snapshotBundleId); err != nil { logger.Error().Msg(fmt.Sprintf("failed to apply state-sync: %s", err)) // stop binary process thread if err := utils.StopProcessByProcessId(processId); err != nil { - panic(err) + return fmt.Errorf("failed to stop process by process id: %w", err) } - os.Exit(1) + + return fmt.Errorf("failed to start state-sync executor: %w", err) } } else { // if we have to sync from genesis we first bootstrap the node if err := bootstrap.StartBootstrapWithBinary(engine, binaryPath, homePath, chainRest, storageRest, nil, blockPoolId, appFlags, debug); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to bootstrap node: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to bootstrap node: %w", err) } // after the node is bootstrapped we start the binary process thread processId, err = utils.StartBinaryProcessForDB(engine, binaryPath, debug, args) if err != nil { - panic(err) + return fmt.Errorf("failed to start binary process: %w", err) } if err := engine.OpenDBs(); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to open dbs in engine: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to open dbs in engine: %w", err) } utils.TrackSyncStartEvent(engine, utils.HEIGHT_SYNC, chainId, chainRest, storageRest, targetHeight, optOut) @@ -111,7 +121,7 @@ func StartHeightSyncWithBinary(engine types.Engine, binaryPath, homePath, chainI _ = e if err := utils.StopProcessByProcessId(processId); err != nil { - panic(err) + return fmt.Errorf("failed to stop binary process: %w", err) } // wait until process has properly shut down @@ -119,7 +129,7 @@ func StartHeightSyncWithBinary(engine types.Engine, binaryPath, homePath, chainI processId, err = utils.StartBinaryProcessForDB(engine, binaryPath, debug, args) if err != nil { - panic(err) + return fmt.Errorf("failed to start binary process: %w", err) } // wait until process has properly started @@ -130,23 +140,25 @@ func StartHeightSyncWithBinary(engine types.Engine, binaryPath, homePath, chainI // stop binary process thread if err := utils.StopProcessByProcessId(processId); err != nil { - panic(err) + return fmt.Errorf("failed to stop binary process: %w", err) } - os.Exit(1) + + return fmt.Errorf("failed to close dbs in engine: %w", err) } } // if we have not reached our target height yet we block-sync the remaining ones if remaining := targetHeight - snapshotHeight; remaining > 0 { logger.Info().Msg(fmt.Sprintf("block-syncing remaining %d blocks", remaining)) - if err := blocksync.StartBlockSync(engine, chainRest, storageRest, nil, blockPoolId, targetHeight, nil); err != nil { + if err := blocksync.StartBlockSyncExecutor(engine, chainRest, storageRest, nil, blockPoolId, targetHeight, 0, 0, false, false, nil); err != nil { logger.Error().Msg(fmt.Sprintf("failed to apply block-sync: %s", err)) // stop binary process thread if err := utils.StopProcessByProcessId(processId); err != nil { - panic(err) + return fmt.Errorf("failed to stop process by process id: %w", err) } - os.Exit(1) + + return fmt.Errorf("failed to start block-sync executor: %w", err) } } @@ -155,14 +167,14 @@ func StartHeightSyncWithBinary(engine types.Engine, binaryPath, homePath, chainI // stop binary process thread if err := utils.StopProcessByProcessId(processId); err != nil { - panic(err) + return fmt.Errorf("failed to stop process by process id: %w", err) } if err := engine.CloseDBs(); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to close dbs in engine: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to close dbs in engine: %w", err) } logger.Info().Msg(fmt.Sprintf("reached target height %d with applying state-sync snapshot at %d and block-syncing the remaining %d blocks in %.2f seconds", targetHeight, snapshotHeight, targetHeight-snapshotHeight, elapsed)) logger.Info().Msg(fmt.Sprintf("successfully reached target height with height-sync")) + return nil } diff --git a/servesnapshots/servesnapshots.go b/servesnapshots/servesnapshots.go index acf8d5e..5d3d78f 100644 --- a/servesnapshots/servesnapshots.go +++ b/servesnapshots/servesnapshots.go @@ -10,7 +10,6 @@ import ( "github.com/KYVENetwork/ksync/statesync" "github.com/KYVENetwork/ksync/types" "github.com/KYVENetwork/ksync/utils" - "os" "strconv" "strings" "time" @@ -30,20 +29,27 @@ func PerformServeSnapshotsValidationChecks(engine types.Engine, chainRest string snapshotBundleId, snapshotHeight, _ = statesync.PerformStateSyncValidationChecks(chainRest, snapshotPoolId, startHeight, false) } - if _, err = blocksync.PerformBlockSyncValidationChecks(engine, chainRest, nil, &blockPoolId, targetHeight, false, false); err != nil { - logger.Error().Msg(fmt.Sprintf("block-sync validation checks failed: %s", err)) - os.Exit(1) + continuationHeight := snapshotHeight + if continuationHeight == 0 { + c, err := engine.GetContinuationHeight() + if err != nil { + return 0, 0, fmt.Errorf("failed to get continuation height: %w", err) + } + continuationHeight = c + } + + if err := blocksync.PerformBlockSyncValidationChecks(chainRest, nil, &blockPoolId, continuationHeight, targetHeight, false, false); err != nil { + return 0, 0, fmt.Errorf("block-sync validation checks failed: %w", err) } return } -func StartServeSnapshotsWithBinary(engine types.Engine, binaryPath, homePath, chainRest, storageRest string, blockPoolId *int64, snapshotPoolId, targetHeight, height, snapshotBundleId, snapshotHeight, snapshotPort int64, appFlags string, rpcServer, pruning, keepSnapshots, skipWaiting, debug bool) { +func StartServeSnapshotsWithBinary(engine types.Engine, binaryPath, homePath, chainRest, storageRest string, blockPoolId *int64, snapshotPoolId, targetHeight, height, snapshotBundleId, snapshotHeight, snapshotPort int64, appFlags string, rpcServer, pruning, keepSnapshots, skipWaiting, debug bool) error { logger.Info().Msg("starting serve-snapshots") if pruning && skipWaiting { - logger.Error().Msg("pruning has to be disabled with --pruning=false if --skip-waiting is true") - os.Exit(1) + return fmt.Errorf("pruning has to be disabled with --pruning=false if --skip-waiting is true") } // get snapshot interval from pool @@ -51,8 +57,7 @@ func StartServeSnapshotsWithBinary(engine types.Engine, binaryPath, homePath, ch snapshotPool, err := pool.GetPoolInfo(chainRest, snapshotPoolId) if err := json.Unmarshal([]byte(snapshotPool.Pool.Data.Config), &config); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to read pool config: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to read pool config: %w", err) } logger.Info().Msg(fmt.Sprintf("found snapshot interval of %d on snapshot pool", config.Interval)) @@ -99,23 +104,23 @@ func StartServeSnapshotsWithBinary(engine types.Engine, binaryPath, homePath, ch // start binary process thread processId, err = utils.StartBinaryProcessForDB(engine, binaryPath, debug, snapshotArgs) if err != nil { - panic(err) + return fmt.Errorf("failed to start binary process: %w", err) } if err := engine.OpenDBs(); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to open dbs engine: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to open dbs in engine: %w", err) } // found snapshot, applying it and continuing block-sync from here - if err := statesync.StartStateSync(engine, chainRest, storageRest, snapshotPoolId, snapshotBundleId); err != nil { + if err := statesync.StartStateSyncExecutor(engine, chainRest, storageRest, snapshotPoolId, snapshotBundleId); err != nil { logger.Error().Msg(fmt.Sprintf("state-sync failed with: %s", err)) // stop binary process thread if err := utils.StopProcessByProcessId(processId); err != nil { - panic(err) + return fmt.Errorf("failed to stop process by process id: %w", err) } - os.Exit(1) + + return fmt.Errorf("failed to start state-sync executor: %w", err) } // TODO: does app has to be restarted after a state-sync? @@ -125,7 +130,7 @@ func StartServeSnapshotsWithBinary(engine types.Engine, binaryPath, homePath, ch _ = e if err := utils.StopProcessByProcessId(processId); err != nil { - panic(err) + return fmt.Errorf("failed to stop process by process id: %w", err) } // wait until process has properly shut down @@ -133,7 +138,7 @@ func StartServeSnapshotsWithBinary(engine types.Engine, binaryPath, homePath, ch processId, err = utils.StartBinaryProcessForDB(engine, binaryPath, debug, snapshotArgs) if err != nil { - panic(err) + return fmt.Errorf("failed to start process: %w", err) } // wait until process has properly started @@ -144,27 +149,26 @@ func StartServeSnapshotsWithBinary(engine types.Engine, binaryPath, homePath, ch // stop binary process thread if err := utils.StopProcessByProcessId(processId); err != nil { - panic(err) + return fmt.Errorf("failed to stop process by process id: %w", err) } - os.Exit(1) + + return fmt.Errorf("failed to open dbs in engine: %w", err) } } } else { // if we have to sync from genesis we first bootstrap the node if err := bootstrap.StartBootstrapWithBinary(engine, binaryPath, homePath, chainRest, storageRest, nil, blockPoolId, appFlags, debug); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to bootstrap node: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to bootstrap node: %w", err) } // after the node is bootstrapped we start the binary process thread processId, err = utils.StartBinaryProcessForDB(engine, binaryPath, debug, snapshotArgs) if err != nil { - panic(err) + return fmt.Errorf("failed to start binary process: %w", err) } if err := engine.OpenDBs(); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to open dbs engine: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to open dbs in engine: %w", err) } } @@ -175,25 +179,26 @@ func StartServeSnapshotsWithBinary(engine types.Engine, binaryPath, homePath, ch go server.StartSnapshotApiServer(engine, snapshotPort) // db executes blocks against app until target height - if err := blocksync.StartDBExecutor(engine, chainRest, storageRest, nil, blockPoolId, targetHeight, snapshotPoolId, config.Interval, pruning, skipWaiting, nil); err != nil { + if err := blocksync.StartBlockSyncExecutor(engine, chainRest, storageRest, nil, blockPoolId, targetHeight, snapshotPoolId, config.Interval, pruning, skipWaiting, nil); err != nil { logger.Error().Msg(fmt.Sprintf("failed to start db executor: %s", err)) // stop binary process thread if err := utils.StopProcessByProcessId(processId); err != nil { - panic(err) + return fmt.Errorf("failed to stop process by process id: %w", err) } - os.Exit(1) + + return fmt.Errorf("failed to start block-sync executor: %w", err) } // stop binary process thread if err := utils.StopProcessByProcessId(processId); err != nil { - panic(err) + return fmt.Errorf("failed to stop process by process id: %w", err) } if err := engine.CloseDBs(); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to close dbs in engine: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to close dbs in engine: %w", err) } logger.Info().Msg(fmt.Sprintf("finished serve-snapshots")) + return nil } diff --git a/sources/version.go b/sources/version.go index 8d5b64b..25a5209 100644 --- a/sources/version.go +++ b/sources/version.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/KYVENetwork/ksync/sources/helpers" log "github.com/KYVENetwork/ksync/utils" - "os" "os/exec" "strconv" "strings" @@ -14,15 +13,14 @@ var ( logger = log.KsyncLogger("sources") ) -func IsBinaryRecommendedVersion(binaryPath, registryUrl, source string, continuationHeight int64, userInput bool) { +func IsBinaryRecommendedVersion(binaryPath, registryUrl, source string, continuationHeight int64, userInput bool) error { if source == "" || !userInput { - return + return nil } cmdPath, err := exec.LookPath(binaryPath) if err != nil { - logger.Error().Msg(fmt.Sprintf("failed to lookup binary path: %s", err.Error())) - os.Exit(1) + return fmt.Errorf("failed to lookup binary path: %w", err) } startArgs := make([]string, 0) @@ -36,8 +34,7 @@ func IsBinaryRecommendedVersion(binaryPath, registryUrl, source string, continua out, err := exec.Command(cmdPath, startArgs...).Output() if err != nil { - logger.Error().Msg("failed to get output of binary") - os.Exit(1) + return fmt.Errorf("failed to get output of binary: %w", err) } binaryVersion := strings.TrimSuffix(string(out), "\n") @@ -47,15 +44,13 @@ func IsBinaryRecommendedVersion(binaryPath, registryUrl, source string, continua entry, err := helpers.GetSourceRegistryEntry(registryUrl, source) if err != nil { - logger.Error().Msg(fmt.Sprintf("failed to get source registry entry: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to get source registry entry: %w", err) } for _, upgrade := range entry.Codebase.Settings.Upgrades { height, err := strconv.ParseInt(upgrade.Height, 10, 64) if err != nil { - logger.Error().Msg(fmt.Sprintf("failed to parse upgrade height %s: %s", upgrade.Height, err)) - os.Exit(1) + return fmt.Errorf("failed to parse upgrade height %s: %w", upgrade.Height, err) } if continuationHeight < height { @@ -66,19 +61,20 @@ func IsBinaryRecommendedVersion(binaryPath, registryUrl, source string, continua } if binaryVersion == recommendedVersion || binaryVersionFormatted == recommendedVersion { - return + return nil } fmt.Printf("\u001B[36m[KSYNC]\u001B[0m The recommended binary version for the current height %d is %s while the provided binary has the following version: %s. Proceed anyway? [y/N]: ", continuationHeight, recommendedVersion, binaryVersion) answer := "" if _, err := fmt.Scan(&answer); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to read in user input: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to read user input: %w", err) } if strings.ToLower(answer) != "y" { logger.Error().Msg("abort") - os.Exit(0) + return nil } + + return nil } diff --git a/statesync/executor.go b/statesync/executor.go index 3dd2dcd..155bf33 100644 --- a/statesync/executor.go +++ b/statesync/executor.go @@ -7,8 +7,8 @@ import ( "github.com/KYVENetwork/ksync/utils" ) -// startStateSyncExecutor takes the bundle id of the first snapshot chunk and applies the snapshot from there -func startStateSyncExecutor(engine types.Engine, chainRest, storageRest string, snapshotPoolId, snapshotBundleId int64) error { +// StartStateSyncExecutor takes the bundle id of the first snapshot chunk and applies the snapshot from there +func StartStateSyncExecutor(engine types.Engine, chainRest, storageRest string, snapshotPoolId, snapshotBundleId int64) error { logger.Info().Msg(fmt.Sprintf("applying state-sync snapshot")) appHeight, err := engine.GetAppHeight() diff --git a/statesync/statesync.go b/statesync/statesync.go index a97b44c..4c25d44 100644 --- a/statesync/statesync.go +++ b/statesync/statesync.go @@ -7,7 +7,6 @@ import ( "github.com/KYVENetwork/ksync/statesync/helpers" "github.com/KYVENetwork/ksync/types" "github.com/KYVENetwork/ksync/utils" - "os" "strings" "time" ) @@ -16,10 +15,6 @@ var ( logger = utils.KsyncLogger("state-sync") ) -func StartStateSync(engine types.Engine, chainRest, storageRest string, snapshotPoolId, snapshotBundleId int64) error { - return startStateSyncExecutor(engine, chainRest, storageRest, snapshotPoolId, snapshotBundleId) -} - // PerformStateSyncValidationChecks checks if a snapshot is available for the targetHeight and if not returns // the nearest available snapshot below the targetHeight. It also returns the bundle id for the snapshot func PerformStateSyncValidationChecks(chainRest string, snapshotPoolId, targetHeight int64, userInput bool) (snapshotBundleId, snapshotHeight int64, err error) { @@ -75,47 +70,47 @@ func PerformStateSyncValidationChecks(chainRest string, snapshotPoolId, targetHe return snapshotBundleId, snapshotHeight, nil } -func StartStateSyncWithBinary(engine types.Engine, binaryPath, chainId, chainRest, storageRest string, snapshotPoolId, targetHeight, snapshotBundleId, snapshotHeight int64, appFlags string, optOut, debug bool) { +func StartStateSyncWithBinary(engine types.Engine, binaryPath, chainId, chainRest, storageRest string, snapshotPoolId, targetHeight, snapshotBundleId, snapshotHeight int64, appFlags string, optOut, debug bool) error { logger.Info().Msg("starting state-sync") // start binary process thread processId, err := utils.StartBinaryProcessForDB(engine, binaryPath, debug, strings.Split(appFlags, ",")) if err != nil { - panic(err) + return fmt.Errorf("failed to start binary process: %w", err) } if err := engine.OpenDBs(); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to open dbs in engine: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to open dbs in engine: %w", err) } utils.TrackSyncStartEvent(engine, utils.STATE_SYNC, chainId, chainRest, storageRest, targetHeight, optOut) start := time.Now() - if err := StartStateSync(engine, chainRest, storageRest, snapshotPoolId, snapshotBundleId); err != nil { + if err := StartStateSyncExecutor(engine, chainRest, storageRest, snapshotPoolId, snapshotBundleId); err != nil { logger.Error().Msg(fmt.Sprintf("failed to start state-sync: %s", err)) // stop binary process thread if err := utils.StopProcessByProcessId(processId); err != nil { - panic(err) + return fmt.Errorf("failed to stop process by process id: %w", err) } - os.Exit(1) + + return fmt.Errorf("failed to start state-sync executor: %w", err) } // stop binary process thread if err := utils.StopProcessByProcessId(processId); err != nil { - panic(err) + return fmt.Errorf("failed to stop process by process id: %w", err) } elapsed := time.Since(start).Seconds() utils.TrackSyncCompletedEvent(snapshotHeight, 0, targetHeight, elapsed, optOut) if err := engine.CloseDBs(); err != nil { - logger.Error().Msg(fmt.Sprintf("failed to close dbs in engine: %s", err)) - os.Exit(1) + return fmt.Errorf("failed to close dbs in engine: %w", err) } logger.Info().Msg(fmt.Sprintf("state-synced at height %d in %.2f seconds", snapshotHeight, elapsed)) logger.Info().Msg(fmt.Sprintf("successfully applied state-sync snapshot")) + return nil } diff --git a/tests/Dockerfile b/tests/Dockerfile new file mode 100644 index 0000000..68a8d82 --- /dev/null +++ b/tests/Dockerfile @@ -0,0 +1,57 @@ +FROM golang:1.22 + +WORKDIR /app + +# install latest updates +RUN apt update && apt upgrade -y + +# install testing framework "bats" from source +RUN git clone --depth 1 --branch v1.11.0 https://github.com/bats-core/bats-core \ + && cd bats-core \ + && ./install.sh /usr/local \ + && cd .. + +# create folder for all binaries +RUN mkdir ~/bins + +# install kyved +RUN wget -qO- https://github.com/KYVENetwork/chain/releases/download/v1.0.0/kyved_linux_amd64.tar.gz | tar -xzv \ + && mv kyved ~/bins/kyved-v1.0.0 \ + && ~/bins/kyved-v1.0.0 init ksync --chain-id kyve-1 \ + && wget https://raw.githubusercontent.com/KYVENetwork/networks/main/kyve-1/genesis.json -O ~/.kyve/config/genesis.json + +# install dydxprotocold +RUN wget -qO- https://github.com/dydxprotocol/v4-chain/releases/download/protocol%2Fv2.0.1/dydxprotocold-v2.0.1-linux-amd64.tar.gz | tar -xzv \ + && mv build/dydxprotocold-v2.0.1-linux-amd64 ~/bins/dydxprotocold-v2.0.1 \ + && ~/bins/dydxprotocold-v2.0.1 init ksync --chain-id dydx-mainnet-1 \ + && wget https://raw.githubusercontent.com/dydxopsdao/networks/main/dydx-mainnet-1/genesis.json -O ~/.dydxprotocol/config/genesis.json + +# install archwayd +RUN git clone --depth 1 --branch v1.0.1 https://github.com/archway-network/archway.git \ + && cd archway \ + && make build \ + && mv build/archwayd ~/bins/archwayd-v1.0.1 \ + && ~/bins/archwayd-v1.0.1 init ksync --chain-id archway-1 \ + && wget -qO- https://github.com/archway-network/networks/raw/main/archway/genesis/genesis.json.gz | gunzip > ~/.archway/config/genesis.json \ + && cd .. \ + && rm -r archway + +# install celestia-appd +RUN wget -qO- https://github.com/celestiaorg/celestia-app/releases/download/v1.3.0/celestia-app_Linux_x86_64.tar.gz | tar -xzv \ + && mv celestia-appd ~/bins/celestia-appd-v1.3.0 \ + && ~/bins/celestia-appd-v1.3.0 init ksync --chain-id celestia \ + && wget https://raw.githubusercontent.com/celestiaorg/networks/master/celestia/genesis.json -O ~/.celestia-app/config/genesis.json \ + && sed -i -r 's/pyroscope_profile_types = .*/pyroscope_profile_types = ""/' ~/.celestia-app/config/config.toml \ + && rm LICENSE README.md + +# install andromedad +RUN git clone --depth 1 --branch v0.1.1-beta-patch https://github.com/andromedaprotocol/andromedad.git \ + && cd andromedad \ + && sed -i -r 's/GO_VERSION := "1.21"/GO_VERSION := "1.22"/' ./Makefile \ + && make build \ + && mv bin/andromedad ~/bins/andromedad-1-v0.1.1-beta-patch \ + && ~/bins/andromedad-1-v0.1.1-beta-patch init ksync --chain-id andromeda-1 \ + && wget https://files.kyve.network/infrastructure/andromeda/genesis.json -O ~/.andromeda/config/genesis.json \ + && cd .. \ + && rm -r andromedad \ + && sed -i -r 's/minimum-gas-prices = ""/minimum-gas-prices = "0uandr"/' ~/.andromeda/config/app.toml diff --git a/tests/block_sync_test.bats b/tests/block_sync_test.bats new file mode 100644 index 0000000..00b63e9 --- /dev/null +++ b/tests/block_sync_test.bats @@ -0,0 +1,39 @@ +@test "KYVE: block sync 50 blocks from genesis" { + run ./build/ksync block-sync -b $HOME/bins/kyved-v1.0.0 -c kaon-1 -t 50 -r -d -y + [ "$status" -eq 0 ] +} + +@test "KYVE: continue block sync from height 50" { + run ./build/ksync block-sync -b $HOME/bins/kyved-v1.0.0 -c kaon-1 -t 100 -d -y + [ "$status" -eq 0 ] +} + +@test "KYVE: try to block-sync with target height lower than current one" { + run ./build/ksync block-sync -b $HOME/bins/kyved-v1.0.0 -c kaon-1 -t 50 -d -y + [ "$status" -eq 1 ] +} + +@test "dYdX: block sync 50 blocks from genesis" { + run ./build/ksync block-sync -b $HOME/bins/dydxprotocold-v2.0.1 -t 50 -r -d -y + [ "$status" -eq 0 ] +} + +@test "dYdX: continue block sync from height 50" { + run ./build/ksync block-sync -b $HOME/bins/dydxprotocold-v2.0.1 -t 100 -d -y + [ "$status" -eq 0 ] +} + +@test "Archway: block sync 50 blocks from genesis with p2p bootstrap" { + run ./build/ksync block-sync -b $HOME/bins/archwayd-v1.0.1 -t 50 -r -d -y + [ "$status" -eq 0 ] +} + +@test "Archway: continue block sync from height 50" { + run ./build/ksync block-sync -b $HOME/bins/archwayd-v1.0.1 -t 100 -d -y + [ "$status" -eq 0 ] +} + +@test "Celestia: block sync 10 blocks from genesis" { + run ./build/ksync block-sync -b $HOME/bins/celestia-appd-v1.3.0 -t 10 -r -d -y + [ "$status" -eq 0 ] +} diff --git a/tests/height_sync_test.bats b/tests/height_sync_test.bats new file mode 100644 index 0000000..628c0bc --- /dev/null +++ b/tests/height_sync_test.bats @@ -0,0 +1,29 @@ +@test "KYVE: height sync below first snapshot height" { + run ./build/ksync height-sync -b $HOME/bins/kyved-v1.0.0 -c kaon-1 -t 50 -r -d -y + [ "$status" -eq 0 ] +} + +@test "KYVE: try to height-sync if the app has not been resetted" { + run ./build/ksync height-sync -b $HOME/bins/kyved-v1.0.0 -c kaon-1 -t 12178 -d -y + [ "$status" -eq 1 ] +} + +@test "dYdX: height sync to specific height" { + run ./build/ksync height-sync -b $HOME/bins/dydxprotocold-v2.0.1 -c kaon-1 -t 5935178 -r -d -y + [ "$status" -eq 0 ] +} + +@test "Archway: height sync below first snapshot height" { + run ./build/ksync height-sync -b $HOME/bins/archwayd-v1.0.1 -t 50 -r -d -y + [ "$status" -eq 0 ] +} + +@test "Celestia: height sync to specific height" { + run ./build/ksync height-sync -b $HOME/bins/celestia-appd-v1.3.0 -t 10010 -r -d -y + [ "$status" -eq 0 ] +} + +@test "Andromeda: height-sync to specific height" { + run ./build/ksync height-sync -b $HOME/bins/andromedad-1-v0.1.1-beta-patch -c kaon-1 -t 2700020 -r -d -y + [ "$status" -eq 0 ] +} diff --git a/tests/info_test.bats b/tests/info_test.bats new file mode 100644 index 0000000..fcf1066 --- /dev/null +++ b/tests/info_test.bats @@ -0,0 +1,14 @@ +@test "KYVE: info on mainnet" { + run ./build/ksync info + [ "$status" -eq 0 ] +} + +@test "KYVE: info on testnet" { + run ./build/ksync info --chain-id kaon-1 + [ "$status" -eq 0 ] +} + +@test "KYVE: info on devnet" { + run ./build/ksync info --chain-id korellia-2 + [ "$status" -eq 1 ] +} diff --git a/tests/state_sync_test.bats b/tests/state_sync_test.bats new file mode 100644 index 0000000..9090bec --- /dev/null +++ b/tests/state_sync_test.bats @@ -0,0 +1,24 @@ +@test "KYVE: state-sync exact height" { + run ./build/ksync state-sync -b $HOME/bins/kyved-v1.0.0 -c kaon-1 -t 12000 -r -d -y + [ "$status" -eq 0 ] +} + +@test "KYVE: state-sync recommended nearest height" { + run ./build/ksync state-sync -b $HOME/bins/kyved-v1.0.0 -c kaon-1 -t 15302 -r -d -y + [ "$status" -eq 0 ] +} + +@test "KYVE: try to state-sync if the app has not been resetted" { + run ./build/ksync state-sync -b $HOME/bins/kyved-v1.0.0 -c kaon-1 -t 12000 -d -y + [ "$status" -eq 1 ] +} + +@test "dYdX: state-sync exact height" { + run ./build/ksync state-sync -b $HOME/bins/dydxprotocold-v2.0.1 -c kaon-1 -t 500000 -r -d -y + [ "$status" -eq 0 ] +} + +@test "Celestia: state-sync exact height" { + run ./build/ksync state-sync -b $HOME/bins/celestia-appd-v1.3.0 -t 10000 -r -d -y + [ "$status" -eq 0 ] +} diff --git a/tests/version_test.bats b/tests/version_test.bats new file mode 100644 index 0000000..a332f27 --- /dev/null +++ b/tests/version_test.bats @@ -0,0 +1,4 @@ +@test "KYVE: version" { + run ./build/ksync version + [ "$status" -eq 0 ] +}