From 9eab25133ddf105b3b8a738e41a5a849e0bca6d6 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 19 Sep 2023 16:21:01 -0400 Subject: [PATCH] Move deployment/registry python modules to scripts folder. Fix parameters to deploy() command to include ContractContainer value. Add check_etherscan_plugin to utils Rename ConstructorParams to DeploymentConfig; get_params to get_constructor_params. --- scripts/{testnet => configs}/lynx_config.json | 0 scripts/{testnet => }/deploy_lynx.py | 46 ++++++++--------- {utils => scripts}/deployment.py | 49 +++++++------------ {utils => scripts}/registry.py | 0 scripts/utils.py | 11 +++++ utils/__init__.py | 0 6 files changed, 51 insertions(+), 55 deletions(-) rename scripts/{testnet => configs}/lynx_config.json (100%) rename scripts/{testnet => }/deploy_lynx.py (55%) rename {utils => scripts}/deployment.py (67%) rename {utils => scripts}/registry.py (100%) delete mode 100644 utils/__init__.py diff --git a/scripts/testnet/lynx_config.json b/scripts/configs/lynx_config.json similarity index 100% rename from scripts/testnet/lynx_config.json rename to scripts/configs/lynx_config.json diff --git a/scripts/testnet/deploy_lynx.py b/scripts/deploy_lynx.py similarity index 55% rename from scripts/testnet/deploy_lynx.py rename to scripts/deploy_lynx.py index bd6891ea..743335a9 100644 --- a/scripts/testnet/deploy_lynx.py +++ b/scripts/deploy_lynx.py @@ -3,14 +3,15 @@ from ape import project from ape.cli import get_user_selected_account - -from utils.deployment import ConstructorParams -from utils.registry import registry_from_ape_deployments -from utils.misc import check_etherscan_plugin +from scripts.deployment import DeploymentConfig +from scripts.registry import registry_from_ape_deployments +from scripts.utils import check_etherscan_plugin PUBLISH = False -CONSTRUCTOR_PARAMS_FILEPATH = Path('') -DEPLOYMENT_REGISTRY_FILEPATH = Path("lynx_testnet_registry.json") # TODO: move to artifacts and make unique +DEPLOYMENT_CONFIG_FILEPATH = Path(__file__).parent / "configs" / "lynx_config.json" +DEPLOYMENT_REGISTRY_FILEPATH = ( + Path(__file__).parent.parent / "artifacts" / "lynx_testnet_registry.json" +) # TODO: make unique def main(): @@ -33,15 +34,17 @@ def main(): check_etherscan_plugin() deployer = get_user_selected_account() - config = ConstructorParams.from_file(CONSTRUCTOR_PARAMS_FILEPATH) + config = DeploymentConfig.from_file(DEPLOYMENT_CONFIG_FILEPATH) LynxRootApplication = deployer.deploy( - *config.get_params(project.LynxRootApplication, locals()), - publish=PUBLISH + project.LynxRootApplication, # TODO should the container be returned by call below? + *config.get_constructor_params(project.LynxRootApplication, locals()), + publish=PUBLISH, ) LynxTACoChildApplication = deployer.deploy( - *config.get_params(project.LynxRootApplication, locals()), + project.LynxTACoChildApplication, + *config.get_constructor_params(project.LynxTACoChildApplication, locals()), publish=PUBLISH, ) @@ -52,29 +55,22 @@ def main(): ) LynxRitualToken = deployer.deploy( - *config.get_params(project.LynxRitualToken, locals()), - publish=PUBLISH + project.LynxRitualToken, + *config.get_constructor_params(project.LynxRitualToken, locals()), + publish=PUBLISH, ) # Lynx Coordinator Coordinator = deployer.deploy( - *config.get_params(project.Coordinator, locals()), + project.Coordinator, + *config.get_constructor_params(project.Coordinator, locals()), publish=PUBLISH, ) - LynxTACoChildApplication.setCoordinator( - Coordinator.address, - sender=deployer - ) + LynxTACoChildApplication.setCoordinator(Coordinator.address, sender=deployer) - deployments = [ - LynxRootApplication, - LynxTACoChildApplication, - LynxRitualToken, - Coordinator - ] + deployments = [LynxRootApplication, LynxTACoChildApplication, LynxRitualToken, Coordinator] registry_from_ape_deployments( - deployments=deployments, - output_filepath=DEPLOYMENT_REGISTRY_FILEPATH + deployments=deployments, output_filepath=DEPLOYMENT_REGISTRY_FILEPATH ) diff --git a/utils/deployment.py b/scripts/deployment.py similarity index 67% rename from utils/deployment.py rename to scripts/deployment.py index 10468547..272a0ad8 100644 --- a/utils/deployment.py +++ b/scripts/deployment.py @@ -25,10 +25,7 @@ def _resolve_param(value: Any, context: typing.Dict[str, Any]) -> Any: return contract_instance.address -def _resolve_parameters( - parameters: OrderedDict, - context: typing.Dict[str, Any] -) -> OrderedDict: +def _resolve_parameters(parameters: OrderedDict, context: typing.Dict[str, Any]) -> OrderedDict: resolved_params = OrderedDict() for name, value in parameters.items(): if isinstance(value, list): @@ -42,10 +39,7 @@ def _resolve_parameters( return resolved_params -def _validate_param( - param: Any, - contracts: List[str] -) -> None: +def _validate_param(param: Any, contracts: List[str]) -> None: if not is_variable(param): return variable = param.strip(VARIABLE_PREFIX) @@ -53,9 +47,7 @@ def _validate_param( raise DeploymentConfigError(f"Variable {param} is not resolvable") -def validate_deployment_config( - config: typing.OrderedDict[str, Any] -) -> None: +def validate_deployment_config(config: typing.OrderedDict[str, Any]) -> None: available_contracts = list(config.keys()) for contract, parameters in config.items(): for name, value in parameters.items(): @@ -66,12 +58,14 @@ def validate_deployment_config( _validate_param(value, available_contracts) -def _confirm_resolution( - resolved_params: OrderedDict, - contract_name: str -) -> None: +def _confirm_resolution(resolved_params: OrderedDict, contract_name: str) -> None: + if len(resolved_params) == 0: + # Nothing really to confirm + print(f"(i) No constructor parameters for {contract_name}; proceeding") + return + print(f"Resolved constructor parameters for {contract_name}") - for name, resolved_value in resolved_params: + for name, resolved_value in resolved_params.items(): print(f"\t{name}={resolved_value}") answer = input("Continue Y/N? ") if answer.lower().strip() == "n": @@ -79,31 +73,26 @@ def _confirm_resolution( exit(-1) -class ConstructorParams: - def __init__(self, constructor_values: OrderedDict): - self.params = constructor_values +class DeploymentConfig: + def __init__(self, contracts_configuration: OrderedDict): + validate_deployment_config(contracts_configuration) + self.contracts_configuration = contracts_configuration @classmethod - def from_file(cls, config_filepath: Path) -> "ConstructorParams": + def from_file(cls, config_filepath: Path) -> "DeploymentConfig": with open(config_filepath, "r") as config_file: config = OrderedDict(json.load(config_file)) return cls(config) - def get_params( - self, - container: ContractContainer, - context: typing.Dict[str, Any], - interactive: bool = True + def get_constructor_params( + self, container: ContractContainer, context: typing.Dict[str, Any], interactive: bool = True ) -> List[Any]: contract_name = container.contract_type.name - contract_parameters = self.params[contract_name] + contract_parameters = self.contracts_configuration[contract_name] resolved_params = _resolve_parameters( contract_parameters, context, ) if interactive: - _confirm_resolution( - resolved_params, - contract_name - ) + _confirm_resolution(resolved_params, contract_name) return list(resolved_params.values()) diff --git a/utils/registry.py b/scripts/registry.py similarity index 100% rename from utils/registry.py rename to scripts/registry.py diff --git a/scripts/utils.py b/scripts/utils.py index ff54f1e5..6263f053 100644 --- a/scripts/utils.py +++ b/scripts/utils.py @@ -1,3 +1,5 @@ +import os + from ape import accounts, config, networks, project from web3 import Web3 @@ -40,3 +42,12 @@ def get_account(id): return accounts.test_accounts[0] else: return None + + +def check_etherscan_plugin(): + try: + import ape_etherscan # noqa: F401 + except ImportError: + raise ImportError("Please install the ape-etherscan plugin to use this script.") + if not os.environ.get("ETHERSCAN_API_KEY"): + raise ValueError("ETHERSCAN_API_KEY is not set.") diff --git a/utils/__init__.py b/utils/__init__.py deleted file mode 100644 index e69de29b..00000000