Skip to content

Commit

Permalink
Problem: no command to fix corrupted data in versiondb
Browse files Browse the repository at this point in the history
Closes: #1683

Solution:
- add fix command to fix corrupted data in versiondb
  • Loading branch information
yihuang committed Nov 11, 2024
1 parent 9086913 commit 7aa274d
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 0 deletions.
1 change: 1 addition & 0 deletions versiondb/client/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func ChangeSetGroupCmd(opts Options) *cobra.Command {
ChangeSetToVersionDBCmd(),
RestoreAppDBCmd(opts),
RestoreVersionDBCmd(),
FixCmd(),

Check warning on line 31 in versiondb/client/cmd.go

View check run for this annotation

Codecov / codecov/patch

versiondb/client/cmd.go#L31

Added line #L31 was not covered by tests
)
return cmd
}
83 changes: 83 additions & 0 deletions versiondb/client/fix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package client

import (
"encoding/binary"
"encoding/hex"
"fmt"

"github.com/crypto-org-chain/cronos/versiondb/tsrocksdb"
"github.com/linxGnu/grocksdb"
"github.com/spf13/cobra"
)

const (
FlagDryRun = "dryrun"
FlagStore = "store"
)

// DefaultStores is the list of store names in cronos v1.3
var DefaultStores = []string{
"acc", "bank", "staking", "mint", "dist", "slashing", "gov",
"params", "upgrade", "evidence", "capability", "consensus",
"feegrant", "crisis", "ibc", "transfer", "feeibc", "icacontroller",
"icahost", "icaauth", "evm", "feemarket", "e2ee", "cronos",
}

func FixCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "fix",
Args: cobra.ExactArgs(1),
Short: "Fix versiondb data for a specific issue, see: https://github.com/crypto-org-chain/cronos/issues/1683",
RunE: func(cmd *cobra.Command, args []string) error {
dir := args[0]
dryRun, err := cmd.Flags().GetBool(FlagDryRun)
if err != nil {
return err
}

Check warning on line 36 in versiondb/client/fix.go

View check run for this annotation

Codecov / codecov/patch

versiondb/client/fix.go#L26-L36

Added lines #L26 - L36 were not covered by tests

storeNames, err := cmd.Flags().GetStringArray(FlagStore)
if err != nil {
return err
}

Check warning on line 41 in versiondb/client/fix.go

View check run for this annotation

Codecov / codecov/patch

versiondb/client/fix.go#L38-L41

Added lines #L38 - L41 were not covered by tests

var (
db *grocksdb.DB
cfHandle *grocksdb.ColumnFamilyHandle
)
if dryRun {
db, cfHandle, err = tsrocksdb.OpenVersionDBForReadOnly(dir, false)
} else {
db, cfHandle, err = tsrocksdb.OpenVersionDB(dir)
}
if err != nil {
return fmt.Errorf("failed to open versiondb: %w", err)
}

Check warning on line 54 in versiondb/client/fix.go

View check run for this annotation

Codecov / codecov/patch

versiondb/client/fix.go#L43-L54

Added lines #L43 - L54 were not covered by tests

version := int64(0)
for _, storeName := range storeNames {
store := tsrocksdb.NewStoreWithDB(db, cfHandle)
iter, err := store.IteratorAtVersion(storeName, nil, nil, &version)
if err != nil {
return fmt.Errorf("failed to create iterator: %w", err)
}
for ; iter.Valid(); iter.Next() {
if dryRun {
// print the key value pairs
key := iter.Key()
value := iter.Value()
ts := binary.LittleEndian.Uint64(key[len(key)-8:])
key = key[:len(key)-8]
fmt.Printf("key: %s, ts: %d, value: %s\n", hex.EncodeToString(key), ts, hex.EncodeToString(value))
}

Check warning on line 71 in versiondb/client/fix.go

View check run for this annotation

Codecov / codecov/patch

versiondb/client/fix.go#L56-L71

Added lines #L56 - L71 were not covered by tests
}
if err := iter.Close(); err != nil {
return fmt.Errorf("failed to close iterator: %w", err)
}

Check warning on line 75 in versiondb/client/fix.go

View check run for this annotation

Codecov / codecov/patch

versiondb/client/fix.go#L73-L75

Added lines #L73 - L75 were not covered by tests
}
return nil

Check warning on line 77 in versiondb/client/fix.go

View check run for this annotation

Codecov / codecov/patch

versiondb/client/fix.go#L77

Added line #L77 was not covered by tests
},
}
cmd.Flags().Bool(FlagDryRun, false, "Dry run mode, do not modify the database")
cmd.Flags().StringArray(FlagStore, DefaultStores, "List of store names to fix")
return cmd

Check warning on line 82 in versiondb/client/fix.go

View check run for this annotation

Codecov / codecov/patch

versiondb/client/fix.go#L80-L82

Added lines #L80 - L82 were not covered by tests
}
13 changes: 13 additions & 0 deletions versiondb/tsrocksdb/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,19 @@ func OpenVersionDB(dir string) (*grocksdb.DB, *grocksdb.ColumnFamilyHandle, erro
return db, cfHandles[1], nil
}

// OpenVersionDBForReadOnly opens versiondb for read-only.
func OpenVersionDBForReadOnly(dir string, errorIfWalFileExists bool) (*grocksdb.DB, *grocksdb.ColumnFamilyHandle, error) {
opts := grocksdb.NewDefaultOptions()
db, cfHandles, err := grocksdb.OpenDbForReadOnlyColumnFamilies(
opts, dir, []string{"default", VersionDBCFName},
[]*grocksdb.Options{opts, NewVersionDBOpts(false)}, errorIfWalFileExists,
)
if err != nil {
return nil, nil, err
}
return db, cfHandles[1], nil

Check warning on line 77 in versiondb/tsrocksdb/opts.go

View check run for this annotation

Codecov / codecov/patch

versiondb/tsrocksdb/opts.go#L68-L77

Added lines #L68 - L77 were not covered by tests
}

// OpenVersionDBAndTrimHistory opens versiondb similar to `OpenVersionDB`,
// but it also trim the versions newer than target one, can be used for rollback.
func OpenVersionDBAndTrimHistory(dir string, version int64) (*grocksdb.DB, *grocksdb.ColumnFamilyHandle, error) {
Expand Down

0 comments on commit 7aa274d

Please sign in to comment.