-
Notifications
You must be signed in to change notification settings - Fork 100
v7 to v9 config migration script #669
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: master
Are you sure you want to change the base?
Changes from 15 commits
ed3c6dc
bdc4e3c
8af24f4
bf02ca3
5367ec0
ce4392a
9e2d0e3
714fbce
d882201
9f0d675
f1aa83d
e37634f
711bbd2
67c8501
b4cc37e
b221ad3
710b4df
21e08af
8bd12e8
1ecfe57
ce726ac
f79fe03
b20842f
58ef54f
fa0774a
1007cb1
700e56d
5161f9e
0a2c4b6
17d501f
1f7af5b
f884b17
b1d2091
9c7f76a
4ba2e84
5d366dc
1fc2cb9
1dc5842
829f5e5
5bc69c7
db185ea
db87a3b
a496619
7f1330e
3f7c5ec
72be37d
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,13 @@ | ||
# Ignore all files in the ruff cache directory | ||
**/.ruff_cache | ||
|
||
**/build/ | ||
|
||
# egg-info | ||
**/*.egg-info/ | ||
|
||
# python cache | ||
**/__pycache__/ | ||
|
||
# pytest | ||
**/.hypothesis/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
|
||
### Usage Example | ||
|
||
alias rpc-v8=~/Documents/share/repo/smr-moonshot-testnet/target/devopt/rpc_node | ||
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. The node operators use Docker. 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. en.. I am thinking operator guide will be on web page not here. We can update the example here but need to have both native and docker one |
||
alias rpc-v9=~/Documents/share/repo/smr-moonshot/target/release/rpc_node | ||
|
||
alias supra-v8="~/Documents/share/repo/smr-moonshot-testnet/target/devopt/supra" | ||
alias supra-v9="~/Documents/share/repo/smr-moonshot/target/release/supra" | ||
|
||
|
||
```sh | ||
pip install . | ||
isaacdoidge marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Migrate rpc config from v7 to v9 | ||
migrate-config rpc -p v7-v9 -f config.toml -t config.toml | ||
so-schen marked this conversation as resolved.
Show resolved
Hide resolved
|
||
# Migrate db from v7 to v8 | ||
rpc-v8 migrate-db config.toml | ||
# Migrate db from v8 to v9 | ||
rpc-v9 migrate-db config.toml | ||
|
||
# Migrate cli profile from v7 to v8 | ||
supra-v8 migrate --network localnet | ||
cp validator_identity.pem node_identity.pem | ||
# Migrate cli profile from v8 to v9 | ||
supra-v9 profile migrate | ||
|
||
# Migrate smr_settings from v7 to v9 | ||
migrate-config smr -p v7-v9 -f smr_settings.toml -t smr_settings.toml | ||
# Migrate db from v7 to v9 | ||
supra-v9 data migrate -p smr_settings.toml | ||
``` | ||
|
||
#### v9 template | ||
https://testnet-snapshot.supra.com/configs/config_v9.0.7.toml | ||
https://testnet-snapshot.supra.com/configs/smr_settings.toml | ||
|
||
#### v8 template | ||
https://testnet-snapshot.supra.com/configs/config_v8.0.2.toml | ||
|
||
#### v7 template | ||
https://mainnet-data.supra.com/configs/config.toml | ||
|
||
|
||
|
||
### Migrate from v7 to v9 | ||
|
||
so-schen marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
#### rpc db migration | ||
|
||
(e2e-tests) kaiqichen@Mac:~/Documents/share/repo/smr-moonshot-mainnet/remote_env/Logs/rpc_0$ rpc-v8 migrate-db config.toml | ||
[======================================================================================================================================================================] 100/100MigrationReport { drop_cf: ["tx_block_info"], migrate_kv: {"tx_block_info__txn_hash_to_block_hash": 8537} } | ||
|
||
|
||
(e2e-tests) kaiqichen@Mac:~/Documents/share/repo/smr-moonshot-mainnet/remote_env/Logs/rpc_0$ rpc-v9 migrate-db config.toml | ||
Counting the number of entries to remove from prune_index... | ||
Cleaning up prune index: [00:00:00] ████████████████████ 0/0 00:00:00 Counting the number of entries in block_to_transaction... | ||
Migrating block_to_transaction: [00:00:00] ████████████████████ 8537/8537 00:00:00 dropped: | ||
- block_to_tx | ||
migrated: | ||
block_to_tx -> block_to_tx_ordered: Migrated 8537 records, up to 239 block height | ||
databases_checked: | ||
- chain_store | ||
- archive | ||
|
||
|
||
#### smr db migration | ||
|
||
(e2e-tests) kaiqichen@Mac:~/Documents/share/repo/smr-moonshot-mainnet/remote_env/Logs/node_0$ supra-v9 data migrate -p smr_settings.toml | ||
Counting the number of entries in certified_block... | ||
Migrating certified_block to certified_block_dehydrated: [00:00:00] ████████████████████ 69/69 00:00:00 Counting the number of entries in uncommitted_block... | ||
Preparing to clean up uncommitted_block: [00:00:00] ████████████████████ 74/74 00:00:00 | ||
Cleaning up uncommitted_block: [00:00:00] ████████████████████ 4/4 00:00:00 Counting the number of entries in certified_block... | ||
Counting the number of entries in certified_block_dehydrated... | ||
Counting the number of entries in uncommitted_block... | ||
Counting the number of entries in qc... | ||
Verifying certified_block_dehydrated: [00:00:00] ████████████████████ 70/70 00:00:00 Counting the number of entries to remove from prune_index... | ||
Cleaning up prune index: [00:00:00] ████████████████████ 70/70 00:00:00 dropped: | ||
- certified_block | ||
migrated: | ||
certified_block -> certified_block_dehydrated: Migrated 70 records, up to 244 block height | ||
databases_checked: | ||
- chain_store |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
[project] | ||
name = "migrate-config" | ||
version = "0.1.0" | ||
description = "Unified CLI tool to migrate Supra RPC and SMR configs." | ||
readme = "README.md" | ||
requires-python = ">=3.10" | ||
dependencies = [ | ||
"tomlkit>=0.13.2", | ||
"click>=8.0.0" | ||
] | ||
|
||
[project.scripts] | ||
migrate-config = "cli.main:main" | ||
|
||
[build-system] | ||
requires = ["setuptools>=61.0", "wheel"] | ||
build-backend = "setuptools.build_meta" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import click | ||
from rpc_config.migrate_path import RPC_CONFIG_MIGRATE_PATH | ||
from rpc_config.migrate_path import run_migration as migrate_rpc_config | ||
from smr_settings.migrate_path import SMR_SETTINGS_MIGRATE_PATH | ||
from smr_settings.migrate_path import run_migration as migrate_smr_config | ||
|
||
|
||
@click.group() | ||
def main(): | ||
"""Migration CLI for Supra configs.""" | ||
|
||
|
||
@main.command() | ||
@click.option( | ||
"--migrate-path", | ||
"-p", | ||
required=True, | ||
type=click.Choice(RPC_CONFIG_MIGRATE_PATH, case_sensitive=True), | ||
help=f"Migration path (choices: {', '.join(RPC_CONFIG_MIGRATE_PATH)})", | ||
) | ||
@click.option( | ||
"--from-file", | ||
"-f", | ||
required=True, | ||
type=click.Path(exists=True), | ||
help="Source config file", | ||
) | ||
@click.option( | ||
"--to-file", "-t", required=True, type=click.Path(), help="Output config file" | ||
) | ||
def rpc(migrate_path, from_file, to_file): | ||
"""Migrate RPC config.""" | ||
migrate_rpc_config(migrate_path, from_file, to_file) | ||
|
||
|
||
@main.command() | ||
@click.option( | ||
"--migrate-path", | ||
"-p", | ||
required=True, | ||
type=click.Choice(SMR_SETTINGS_MIGRATE_PATH, case_sensitive=True), | ||
help=f"Migration path (choices: {', '.join(SMR_SETTINGS_MIGRATE_PATH)})", | ||
) | ||
@click.option( | ||
"--from-file", | ||
"-f", | ||
required=True, | ||
type=click.Path(exists=True), | ||
help="Source config file", | ||
) | ||
@click.option( | ||
"--to-file", "-t", required=True, type=click.Path(), help="Output config file" | ||
) | ||
def smr(migrate_path, from_file, to_file): | ||
"""Migrate SMR config.""" | ||
migrate_smr_config(migrate_path, from_file, to_file) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
|
||
import typing as ty | ||
import tomlkit | ||
from copy import deepcopy | ||
from . import utils | ||
|
||
class MigrationPathSet: | ||
""" | ||
Base class for migration paths. | ||
""" | ||
def __init__(self, migrate_paths: ty.Dict[str, ty.List[ty.Callable]]): | ||
self.migrate_paths = migrate_paths | ||
|
||
def get_versions(self, key: str) -> ty.Tuple[str, str]: | ||
"""Split the key into from_version and to_version.""" | ||
if key not in self.migrate_paths: | ||
raise ValueError(f"Invalid key: {key}") | ||
from_version, to_version = key.split('-', 1) | ||
return from_version, to_version | ||
|
||
def get_migration_functions(self, key: str) -> ty.List[ty.Callable]: | ||
"""Get the migration functions for the given key.""" | ||
if key not in self.migrate_paths: | ||
raise ValueError(f"Unknown migration path: {key}") | ||
return self.migrate_paths[key] | ||
|
||
|
||
class Migration: | ||
""" | ||
Top level migration class that handles the migration of config files. | ||
""" | ||
def __init__(self, migrate_path: ty.Dict[str, ty.List[ty.Callable]]): | ||
self.migrate_path = MigrationPathSet(migrate_path) | ||
|
||
|
||
def migrate_config(self, migrate_choice: str, from_path: str, to_path: str): | ||
|
||
so-schen marked this conversation as resolved.
Show resolved
Hide resolved
|
||
migrate_functions = self.migrate_path.get_migration_functions(migrate_choice) | ||
|
||
so-schen marked this conversation as resolved.
Show resolved
Hide resolved
|
||
from_version, to_version = self.migrate_path.get_versions(migrate_choice) | ||
default_backup_path = f"{from_path}_{from_version}.bak" | ||
isaacdoidge marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if from_path == to_path: | ||
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. If we're not overwriting the existing config file, then won't the user still have to move it afterwards? 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. yes, it provide options, user can choose its preference |
||
print(f"Warning: The source and destination paths are the same ({from_path}).") | ||
print( | ||
f"A backup of your original config will be saved to: {default_backup_path}" | ||
) | ||
confirm = input( | ||
"This will overwrite your original config file. Continue? [y/N]: " | ||
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 confirmation seems unnecessary if a backup is created 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. when overwrite, I think it is good to explicitly hint where is the backup and overwritten will happen, otherwise, another behavior can be create a new file, similar as operating system, when download a file with same name, it will ask you if to overwrite or save to a new name |
||
) | ||
if confirm.lower() != "y": | ||
print("Aborted by user.") | ||
return | ||
|
||
with open(from_path, "r") as f: | ||
toml_data = tomlkit.parse(f.read()) | ||
|
||
# Backup old config | ||
original_toml_data = deepcopy(toml_data) | ||
|
||
for fn in migrate_functions: | ||
print(f"Running migration function: {fn.__name__}") | ||
fn(toml_data) | ||
|
||
print(f"Backing up old config to {default_backup_path}") | ||
tomlkit.dump(original_toml_data, open(default_backup_path, "w")) | ||
|
||
# Write new config | ||
print(f"Writing new config to {to_path}") | ||
with open(to_path, "w") as f: | ||
f.write(tomlkit.dumps(toml_data)) | ||
|
||
# Print the diff | ||
from_str = tomlkit.dumps(original_toml_data).splitlines(keepends=True) | ||
to_str = tomlkit.dumps(toml_data).splitlines(keepends=True) | ||
|
||
utils.unified_diff( | ||
from_str, | ||
to_str, | ||
fromfile=from_version, | ||
tofile=to_version, | ||
) | ||
|
||
print( | ||
f""" | ||
Config migrated from {from_path} to {to_path}. | ||
Please double check above for the diff between old and new config. | ||
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. How are the operators supposed to check this? What information are we providing them with that will tell them what to expect? 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. I think they can use the template as reference 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. now docs are retained from template, they can read the docs from the migrated result file |
||
Please ensure to use the new config file for target binary version. | ||
NOTE: the comments may not be preserved in the new config file, so | ||
so-schen marked this conversation as resolved.
Show resolved
Hide resolved
|
||
you would need to fix the comments manually. | ||
""" | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import difflib | ||
import typing as ty | ||
|
||
def unified_diff(from_str, to_str, fromfile, tofile): | ||
diff = difflib.unified_diff(from_str, to_str, fromfile=fromfile, tofile=tofile) | ||
__print_colored_diff(diff) | ||
|
||
|
||
def __print_colored_diff(diff): | ||
# The color is added here manually using ANSI escape codes. | ||
for line in diff: | ||
if line.startswith("+") and not line.startswith("+++"): | ||
print(f"\033[32m{line}\033[0m", end="") # Green for additions | ||
elif line.startswith("-") and not line.startswith("---"): | ||
print(f"\033[31m{line}\033[0m", end="") # Red for deletions | ||
elif line.startswith("@@"): | ||
print(f"\033[36m{line}\033[0m", end="") # Cyan for hunk headers | ||
else: | ||
print(line, end="") | ||
|
||
|
||
def print_with_checkmark(message): | ||
""" | ||
Print a message with a checkmark. | ||
""" | ||
print(f"✓ {message}") | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.