-
Notifications
You must be signed in to change notification settings - Fork 248
[DNM] feat: delete go-header store cmd #3040
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
83b25d6
ebae42f
d56115d
1e26328
915842e
bfc0701
ca8651b
9092ede
9c74889
dee6ed5
70dc901
8106374
25cc36b
dfe1071
0124c25
b0fa1e2
1300d16
9101f11
0588001
e717aa2
0cc54d0
08d8594
f1460be
514ba02
f74fcda
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| package cmd | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
|
|
||
| ds "github.com/ipfs/go-datastore" | ||
| dsq "github.com/ipfs/go-datastore/query" | ||
| "github.com/spf13/cobra" | ||
|
|
||
| rollcmd "github.com/evstack/ev-node/pkg/cmd" | ||
| "github.com/evstack/ev-node/pkg/store" | ||
| ) | ||
|
|
||
| const ( | ||
| // go-header store prefixes used prior to the unified store migration | ||
| headerSyncPrefix = "/headerSync" | ||
| dataSyncPrefix = "/dataSync" | ||
| ) | ||
|
|
||
| // NewCleanupGoHeaderCmd creates a command to delete the legacy go-header store data. | ||
| // This data is no longer needed after the migration to the unified store approach | ||
| // where HeaderStoreAdapter and DataStoreAdapter read directly from the ev-node store. | ||
| func NewCleanupGoHeaderCmd() *cobra.Command { | ||
| var dryRun bool | ||
|
|
||
| cmd := &cobra.Command{ | ||
| Use: "cleanup-goheader", | ||
| Short: "Delete legacy go-header store data from disk", | ||
| Long: `Delete the legacy go-header store data (headerSync and dataSync prefixes) from the database. | ||
|
|
||
| This command removes data that was previously duplicated by the go-header library | ||
| for P2P sync operations. After the migration to the unified store approach, | ||
| this data is no longer needed as the HeaderStoreAdapter and DataStoreAdapter | ||
| now read directly from the ev-node store. | ||
|
|
||
| WARNING: Make sure the node is stopped before running this command. | ||
| This operation is irreversible.`, | ||
| RunE: func(cmd *cobra.Command, args []string) error { | ||
| nodeConfig, err := rollcmd.ParseConfig(cmd) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| goCtx := cmd.Context() | ||
| if goCtx == nil { | ||
| goCtx = context.Background() | ||
| } | ||
|
|
||
| // Open the database | ||
| rawDB, err := store.NewDefaultKVStore(nodeConfig.RootDir, nodeConfig.DBPath, evmDbName) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to open database: %w", err) | ||
| } | ||
| defer func() { | ||
| if closeErr := rawDB.Close(); closeErr != nil { | ||
| cmd.Printf("Warning: failed to close database: %v\n", closeErr) | ||
| } | ||
| }() | ||
|
|
||
| // Delete headerSync prefix | ||
| headerCount, err := deletePrefix(goCtx, rawDB, headerSyncPrefix, dryRun) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to delete headerSync data: %w", err) | ||
| } | ||
|
|
||
| // Delete dataSync prefix | ||
| dataCount, err := deletePrefix(goCtx, rawDB, dataSyncPrefix, dryRun) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to delete dataSync data: %w", err) | ||
| } | ||
|
|
||
| totalCount := headerCount + dataCount | ||
|
|
||
| if dryRun { | ||
| cmd.Printf("Dry run: would delete %d keys (%d headerSync, %d dataSync)\n", | ||
| totalCount, headerCount, dataCount) | ||
| } else { | ||
| if totalCount == 0 { | ||
| cmd.Println("No legacy go-header store data found to delete.") | ||
| } else { | ||
| cmd.Printf("Successfully deleted %d keys (%d headerSync, %d dataSync)\n", | ||
| totalCount, headerCount, dataCount) | ||
| } | ||
| } | ||
|
|
||
| return nil | ||
| }, | ||
| } | ||
|
|
||
| cmd.Flags().BoolVar(&dryRun, "dry-run", false, "show what would be deleted without actually deleting") | ||
|
|
||
| return cmd | ||
| } | ||
|
|
||
| // deletePrefix deletes all keys with the given prefix from the datastore. | ||
| // Returns the number of keys deleted. | ||
| func deletePrefix(ctx context.Context, db ds.Batching, prefix string, dryRun bool) (int, error) { | ||
| results, err := db.Query(ctx, dsq.Query{ | ||
| Prefix: prefix, | ||
| KeysOnly: true, | ||
| }) | ||
| if err != nil { | ||
| return 0, fmt.Errorf("failed to query keys with prefix %s: %w", prefix, err) | ||
| } | ||
| defer results.Close() | ||
|
|
||
| count := 0 | ||
| batch, err := db.Batch(ctx) | ||
| if err != nil { | ||
| return 0, fmt.Errorf("failed to create batch: %w", err) | ||
| } | ||
|
|
||
| for result := range results.Next() { | ||
| if result.Error != nil { | ||
| return count, fmt.Errorf("error iterating results: %w", result.Error) | ||
| } | ||
|
|
||
| if !dryRun { | ||
| if err := batch.Delete(ctx, ds.NewKey(result.Key)); err != nil { | ||
| return count, fmt.Errorf("failed to delete key %s: %w", result.Key, err) | ||
| } | ||
| } | ||
| count++ | ||
| } | ||
|
|
||
| if !dryRun && count > 0 { | ||
| if err := batch.Commit(ctx); err != nil { | ||
| return count, fmt.Errorf("failed to commit batch delete: %w", err) | ||
| } | ||
| } | ||
|
|
||
| return count, nil | ||
| } | ||
|
Comment on lines
+98
to
+134
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function loads all delete operations for a given prefix into a single batch. If there are a very large number of keys to delete, this could lead to high memory consumption. Consider processing the deletions in smaller batches (e.g., committing every 1000 keys) to limit memory usage and make the operation more robust against large datasets. |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable
evmDbNameis not defined in this file or package, which will cause a compilation error. It should be defined, likely as a constant, representing the name of the EVM database.