diff --git a/store/v2/storage/pebbledb/batch.go b/store/v2/storage/pebbledb/batch.go index 101986878c81..fdd58f447435 100644 --- a/store/v2/storage/pebbledb/batch.go +++ b/store/v2/storage/pebbledb/batch.go @@ -17,6 +17,17 @@ type Batch struct { batch *pebble.Batch version uint64 sync bool + size int +} + +const ( + oneIf64Bit = ^uint(0) >> 63 + maxUint32OrInt = (1<<31)< maxUint32OrInt { + // 4 GB is huge, probably genesis; flush and reset + if err := b.batch.Commit(&pebble.WriteOptions{Sync: b.sync}); err != nil { + return fmt.Errorf("max batch size exceed: failed to write PebbleDB batch: %w", err) + } + b.batch.Reset() + b.size = 0 + } + if err := b.batch.Set(prefixedKey, prefixedVal, nil); err != nil { return fmt.Errorf("failed to write PebbleDB batch: %w", err) } + b.size += size return nil } diff --git a/store/v2/storage/pebbledb/db.go b/store/v2/storage/pebbledb/db.go index 1547dba102d9..20fc3f11c7f1 100644 --- a/store/v2/storage/pebbledb/db.go +++ b/store/v2/storage/pebbledb/db.go @@ -238,11 +238,14 @@ func (db *Database) Prune(version uint64) (err error) { return fmt.Errorf("invalid PebbleDB MVCC key: %s", prefixedKey) } - keyVersion, err := decodeUint64Ascending(verBz) - if err != nil { - return fmt.Errorf("failed to decode key version: %w", err) + var keyVersion uint64 + // handle version 0 (no version prefix) + if len(verBz) > 0 { + keyVersion, err = decodeUint64Ascending(verBz) + if err != nil { + return fmt.Errorf("failed to decode key version: %w", err) + } } - // seek to next key if we are at a version which is higher than prune height if keyVersion > version { itr.NextPrefix() @@ -432,9 +435,13 @@ func getMVCCSlice(db *pebble.DB, storeKey, key []byte, version uint64) ([]byte, return nil, fmt.Errorf("invalid PebbleDB MVCC key: %s", itr.Key()) } - keyVersion, err := decodeUint64Ascending(vBz) - if err != nil { - return nil, fmt.Errorf("failed to decode key version: %w", err) + var keyVersion uint64 + // handle version 0 (no version prefix) + if len(vBz) > 0 { + keyVersion, err = decodeUint64Ascending(vBz) + if err != nil { + return nil, fmt.Errorf("failed to decode key version: %w", err) + } } if keyVersion > version { return nil, fmt.Errorf("key version too large: %d", keyVersion) diff --git a/store/v2/storage/pebbledb/iterator.go b/store/v2/storage/pebbledb/iterator.go index 6cafe196a20b..2401ab4ef000 100644 --- a/store/v2/storage/pebbledb/iterator.go +++ b/store/v2/storage/pebbledb/iterator.go @@ -216,15 +216,20 @@ func (itr *iterator) DebugRawIterate() { valid = itr.source.SeekLT(MVCCEncode(firstKey, itr.version+1)) } + var err error for valid { key, vBz, ok := SplitMVCCKey(itr.source.Key()) if !ok { panic(fmt.Sprintf("invalid PebbleDB MVCC key: %s", itr.source.Key())) } - version, err := decodeUint64Ascending(vBz) - if err != nil { - panic(fmt.Errorf("failed to decode key version: %w", err)) + var version uint64 + // handle version 0 (no version prefix) + if len(vBz) > 0 { + version, err = decodeUint64Ascending(vBz) + if err != nil { + panic(fmt.Errorf("failed to decode key version: %w", err)) + } } val, tombBz, ok := SplitMVCCKey(itr.source.Value()) diff --git a/tools/cosmovisor/CHANGELOG.md b/tools/cosmovisor/CHANGELOG.md index 3dd65d805595..2e8b454ee917 100644 --- a/tools/cosmovisor/CHANGELOG.md +++ b/tools/cosmovisor/CHANGELOG.md @@ -36,19 +36,22 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [Unreleased] +## v1.7.0 - 2024-11-18 + ### Features * [#21790](https://github.com/cosmos/cosmos-sdk/pull/21790) Add `add-batch-upgrade` command. * [#21972](https://github.com/cosmos/cosmos-sdk/pull/21972) Add `prepare-upgrade` command +* [#21932](https://github.com/cosmos/cosmos-sdk/pull/21932) Add `cosmovisor show-upgrade-info` command to display the upgrade-info.json into stdout. ### Improvements * [#21891](https://github.com/cosmos/cosmos-sdk/pull/21891) create `current` symlink as relative * [#21462](https://github.com/cosmos/cosmos-sdk/pull/21462) Pass `stdin` to binary. + +### Bug Fixes -### Features - -* [#21932](https://github.com/cosmos/cosmos-sdk/pull/21932) Add `cosmovisor show-upgrade-info` command to display the upgrade-info.json into stdout. +* [#22528](https://github.com/cosmos/cosmos-sdk/pull/22528) Fix premature upgrades on restarting cosmovisor. ## v1.6.0 - 2024-08-12 diff --git a/tools/cosmovisor/scanner.go b/tools/cosmovisor/scanner.go index 6b46f85bafa3..008c57357075 100644 --- a/tools/cosmovisor/scanner.go +++ b/tools/cosmovisor/scanner.go @@ -15,6 +15,8 @@ import ( upgradetypes "cosmossdk.io/x/upgrade/types" ) +var errUntestAble = errors.New("untestable") + type fileWatcher struct { daemonHome string filename string // full path to a watched file @@ -149,8 +151,8 @@ func (fw *fileWatcher) CheckUpdate(currentUpgrade upgradetypes.Plan) bool { } // file exist but too early in height - currentHeight, _ := fw.checkHeight() - if currentHeight != 0 && currentHeight < info.Height { + currentHeight, err := fw.checkHeight() + if (err != nil || currentHeight < info.Height) && !errors.Is(err, errUntestAble) { // ignore this check for tests return false } @@ -182,7 +184,7 @@ func (fw *fileWatcher) CheckUpdate(currentUpgrade upgradetypes.Plan) bool { // checkHeight checks if the current block height func (fw *fileWatcher) checkHeight() (int64, error) { if testing.Testing() { // we cannot test the command in the test environment - return 0, nil + return 0, errUntestAble } result, err := exec.Command(fw.currentBin, "status", "--home", fw.daemonHome).CombinedOutput() //nolint:gosec // we want to execute the status command