diff --git a/nucypher/blockchain/eth/actors.py b/nucypher/blockchain/eth/actors.py index 9c3abf4b5..07df2d52e 100644 --- a/nucypher/blockchain/eth/actors.py +++ b/nucypher/blockchain/eth/actors.py @@ -286,7 +286,7 @@ class DeployerActor(NucypherTokenActor): # deploy contracts total_deployment_transactions = 0 for deployer_class in self.deployer_classes: - total_deployment_transactions += deployer_class.number_of_deployment_transactions + total_deployment_transactions += len(deployer_class.deployment_steps) first_iteration = True with click.progressbar(length=total_deployment_transactions, diff --git a/nucypher/blockchain/eth/deployers.py b/nucypher/blockchain/eth/deployers.py index 841313b41..5c98a2708 100644 --- a/nucypher/blockchain/eth/deployers.py +++ b/nucypher/blockchain/eth/deployers.py @@ -38,7 +38,9 @@ class ContractDeployer: agency = NotImplemented contract_name = NotImplemented - number_of_deployment_transactions = NotImplemented + deployment_steps = NotImplemented + upgrade_steps = NotImplemented + rollback_steps = NotImplemented _interface_class = BlockchainDeployerInterface _upgradeable = NotImplemented __linker_deployer = NotImplemented @@ -142,7 +144,7 @@ class NucypherTokenDeployer(ContractDeployer): agency = NucypherTokenAgent contract_name = agency.registry_contract_name - number_of_deployment_transactions = 1 + deployment_steps = ('contract_deployment', ) _upgradeable = False def __init__(self, @@ -173,7 +175,7 @@ class NucypherTokenDeployer(ContractDeployer): progress.update(1) self._contract = contract - return {'txhash': deployment_receipt} + return {self.deployment_steps[0]: deployment_receipt} class DispatcherDeployer(ContractDeployer): @@ -183,7 +185,7 @@ class DispatcherDeployer(ContractDeployer): """ contract_name = DISPATCHER_CONTRACT_NAME - number_of_deployment_transactions = 1 + deployment_steps = ('contract_deployment', ) _upgradeable = False DISPATCHER_SECRET_LENGTH = 32 @@ -202,7 +204,7 @@ class DispatcherDeployer(ContractDeployer): progress.update(1) self._contract = dispatcher_contract - return {'deployment': receipt} + return {self.deployment_steps[0]: receipt} @validate_secret def retarget(self, new_target: str, existing_secret_plaintext: bytes, new_secret_hash: bytes, gas_limit: int = None) -> dict: @@ -241,7 +243,7 @@ class StakingEscrowDeployer(ContractDeployer): agency = StakingEscrowAgent contract_name = agency.registry_contract_name - number_of_deployment_transactions = 4 + deployment_steps = ('contract_deployment', 'dispatcher_deployment', 'reward_transfer', 'initialize') _upgradeable = True __proxy_deployer = DispatcherDeployer @@ -301,7 +303,8 @@ class StakingEscrowDeployer(ContractDeployer): target_contract=the_escrow_contract, deployer_address=self.deployer_address) - dispatcher_deploy_receipt = dispatcher_deployer.deploy(secret_hash=secret_hash, gas_limit=gas_limit) + dispatcher_receipts = dispatcher_deployer.deploy(secret_hash=secret_hash, gas_limit=gas_limit) + dispatcher_deploy_receipt = dispatcher_receipts[dispatcher_deployer.deployment_steps[0]] if progress: progress.update(1) @@ -338,13 +341,11 @@ class StakingEscrowDeployer(ContractDeployer): if progress: progress.update(1) - # Gather the transaction hashes - deployment_receipts = {'deploy': deploy_receipt, - 'dispatcher_deploy': dispatcher_deploy_receipt['deployment'], - 'reward_transfer': reward_receipt, - 'initialize': init_receipt} + # Gather the transaction receipts + ordered_receipts = (deploy_receipt, dispatcher_deploy_receipt, reward_receipt, init_receipt) + deployment_receipts = dict(zip(self.deployment_steps, ordered_receipts)) - # Set the contract and transaction hashes # + # Set the contract and transaction receipts # self._contract = the_escrow_contract self.deployment_receipts = deployment_receipts return deployment_receipts @@ -410,10 +411,12 @@ class PolicyManagerDeployer(ContractDeployer): agency = PolicyManagerAgent contract_name = agency.registry_contract_name - number_of_deployment_transactions = 3 + _upgradeable = True __proxy_deployer = DispatcherDeployer + deployment_steps = ('deployment', 'dispatcher_deployment', 'set_policy_manager') + def make_agent(self) -> EthereumContractAgent: agent = self.agency(blockchain=self.blockchain, contract=self._contract) return agent @@ -425,11 +428,11 @@ class PolicyManagerDeployer(ContractDeployer): def _deploy_essential(self, gas_limit: int = None): policy_manager_contract, deploy_receipt = self.blockchain.deploy_contract(self.contract_name, - self.staking_agent.contract_address, - gas_limit=gas_limit) + self.staking_agent.contract_address, + gas_limit=gas_limit) return policy_manager_contract, deploy_receipt - def deploy(self, secret_hash: bytes, gas_limit: int = None, progress=None) -> Dict[str, str]: + def deploy(self, secret_hash: bytes, gas_limit: int = None, progress=None) -> Dict[str, dict]: self.check_deployment_readiness() # Creator deploys the policy manager @@ -442,6 +445,7 @@ class PolicyManagerDeployer(ContractDeployer): deployer_address=self.deployer_address) proxy_deploy_receipt = proxy_deployer.deploy(secret_hash=secret_hash, gas_limit=gas_limit) + proxy_deploy_receipt = proxy_deploy_receipt[proxy_deployer.deployment_steps[0]] if progress: progress.update(1) @@ -464,10 +468,9 @@ class PolicyManagerDeployer(ContractDeployer): if progress: progress.update(1) - # Gather the transaction hashes - deployment_receipts = {'deployment': deploy_receipt, - 'dispatcher_deployment': proxy_deploy_receipt['deployment'], - 'set_policy_manager': set_policy_manager_receipt} + # Gather the transaction receipts + ordered_receipts = (deploy_receipt, proxy_deploy_receipt, set_policy_manager_receipt) + deployment_receipts = dict(zip(self.deployment_steps, ordered_receipts)) self.deployment_receipts = deployment_receipts self._contract = wrapped_contract @@ -486,9 +489,10 @@ class PolicyManagerDeployer(ContractDeployer): deployer_address=self.deployer_address, bare=True) # acquire agency for the dispatcher itself. - # Creator deploys the policy manager - policy_manager_contract, deploy_txhash = self._deploy_essential(gas_limit=gas_limit) + # Creator deploys new version of PolicyManager + policy_manager_contract, deploy_receipt = self._deploy_essential(gas_limit=gas_limit) + # The proxy ("Dispatcher") updates its target. upgrade_receipt = proxy_deployer.retarget(new_target=policy_manager_contract.address, existing_secret_plaintext=existing_secret_plaintext, new_secret_hash=new_secret_hash, @@ -498,7 +502,9 @@ class PolicyManagerDeployer(ContractDeployer): self._contract = self.blockchain._wrap_contract(proxy_deployer.contract, target_contract=policy_manager_contract) - upgrade_transaction = {'deploy': deploy_txhash, 'retarget': upgrade_receipt} + # TODO: Contract ABI is not updated in Agents when upgrade/rollback #1184 + + upgrade_transaction = {'deploy': deploy_receipt, 'retarget': upgrade_receipt} return upgrade_transaction def rollback(self, existing_secret_plaintext: bytes, new_secret_hash: bytes, gas_limit: int = None): @@ -520,7 +526,7 @@ class PolicyManagerDeployer(ContractDeployer): class LibraryLinkerDeployer(ContractDeployer): contract_name = 'UserEscrowLibraryLinker' - number_of_deployment_transactions = 1 + deployment_steps = ('contract_deployment', ) def __init__(self, target_contract: Contract, bare: bool = False, *args, **kwargs): self.target_contract = target_contract @@ -531,12 +537,12 @@ class LibraryLinkerDeployer(ContractDeployer): def deploy(self, secret_hash: bytes, gas_limit: int = None, progress=None) -> dict: linker_args = (self.contract_name, self.target_contract.address, secret_hash) - linker_contract, linker_deployment_txhash = self.blockchain.deploy_contract(gas_limit=gas_limit, *linker_args) + linker_contract, receipt = self.blockchain.deploy_contract(gas_limit=gas_limit, *linker_args) if progress: progress.update(1) self._contract = linker_contract - return {'txhash': linker_deployment_txhash} + return {self.deployment_steps[0]: receipt} @validate_secret def retarget(self, new_target: str, existing_secret_plaintext: bytes, new_secret_hash: bytes, gas_limit: int = None): @@ -558,7 +564,7 @@ class LibraryLinkerDeployer(ContractDeployer): class UserEscrowProxyDeployer(ContractDeployer): contract_name = 'UserEscrowProxy' - number_of_deployment_transactions = 2 + deployment_steps = ('contract_deployment', 'linker_deployment') __linker_deployer = LibraryLinkerDeployer def __init__(self, *args, **kwargs): @@ -581,28 +587,27 @@ class UserEscrowProxyDeployer(ContractDeployer): Deploys a new UserEscrowProxy contract, and a new UserEscrowLibraryLinker, targeting the first. This is meant to be called only once per general deployment. """ - - receipts = dict() - - # UserEscrowProxy + # 1 - UserEscrowProxy user_escrow_proxy_contract, deployment_receipt = self._deploy_essential(gas_limit=gas_limit) if progress: progress.update(1) - receipts['deployment'] = deployment_receipt - - # UserEscrowLibraryLinker + # 2 - UserEscrowLibraryLinker linker_deployer = self.__linker_deployer(blockchain=self.blockchain, deployer_address=self.deployer_address, target_contract=user_escrow_proxy_contract) - linker_deployment_receipt = linker_deployer.deploy(secret_hash=secret_hash, gas_limit=gas_limit) + linker_deployment_receipts = linker_deployer.deploy(secret_hash=secret_hash, gas_limit=gas_limit) + linker_deployment_receipt = linker_deployment_receipts[linker_deployer.deployment_steps[0]] if progress: progress.update(1) - receipts['linker_deployment'] = linker_deployment_receipt['txhash'] + # Gather the transaction receipts + ordered_receipts = (deployment_receipt, linker_deployment_receipt) + deployment_receipts = dict(zip(self.deployment_steps, ordered_receipts)) + self._contract = user_escrow_proxy_contract - return receipts + return deployment_receipts @classmethod def get_latest_version(cls, blockchain) -> Contract: @@ -636,6 +641,8 @@ class UserEscrowProxyDeployer(ContractDeployer): new_secret_hash=new_secret_hash, gas_limit=gas_limit) + # TODO: Contract ABI is not updated in Agents when upgrade/rollback #1184 + deployment_receipts['linker_retarget'] = linker_receipt self._contract = user_escrow_proxy_contract return deployment_receipts @@ -645,7 +652,7 @@ class UserEscrowDeployer(ContractDeployer): agency = UserEscrowAgent contract_name = agency.registry_contract_name - number_of_deployment_transactions = 1 + deployment_steps = ('contract_deployment', ) _upgradeable = True __linker_deployer = LibraryLinkerDeployer __allocation_registry = AllocationRegistry @@ -737,6 +744,7 @@ class UserEscrowDeployer(ContractDeployer): progress.update(1) self._contract = user_escrow_contract + # TODO: Homogenize with rest of deployer receipts return deploy_receipt @@ -744,7 +752,7 @@ class AdjudicatorDeployer(ContractDeployer): agency = AdjudicatorAgent contract_name = agency.registry_contract_name - number_of_deployment_transactions = 3 + deployment_steps = ('contract_deployment', 'dispatcher_deployment', 'set_adjudicator') _upgradeable = True __proxy_deployer = DispatcherDeployer @@ -776,7 +784,8 @@ class AdjudicatorDeployer(ContractDeployer): target_contract=adjudicator_contract, deployer_address=self.deployer_address) - proxy_deploy_receipt = proxy_deployer.deploy(secret_hash=secret_hash, gas_limit=gas_limit) + proxy_deploy_receipts = proxy_deployer.deploy(secret_hash=secret_hash, gas_limit=gas_limit) + proxy_deploy_receipt = proxy_deploy_receipts[proxy_deployer.deployment_steps[0]] if progress: progress.update(1) @@ -801,10 +810,9 @@ class AdjudicatorDeployer(ContractDeployer): if progress: progress.update(1) - # Gather the transaction hashes - deployment_receipts = {'deployment': deploy_receipt, - 'dispatcher_deployment': proxy_deploy_receipt['deployment'], - 'set_adjudicator': set_adjudicator_receipt} + # Gather the transaction receipts + ordered_receipts = (deploy_receipt, proxy_deploy_receipt, set_adjudicator_receipt) + deployment_receipts = dict(zip(self.deployment_steps, ordered_receipts)) self.deployment_receipts = deployment_receipts self._contract = adjudicator_contract @@ -838,6 +846,8 @@ class AdjudicatorDeployer(ContractDeployer): # Switch the contract for the wrapped one self._contract = wrapped_adjudicator_contract + # TODO: Contract ABI is not updated in Agents when upgrade/rollback #1184 + upgrade_transaction = {'deploy': deploy_receipt, 'retarget': upgrade_receipt['transactionHash']} return upgrade_transaction diff --git a/tests/blockchain/eth/entities/deployers/test_adjudicator_deployer.py b/tests/blockchain/eth/entities/deployers/test_adjudicator_deployer.py index fd6cf28f6..25824199f 100644 --- a/tests/blockchain/eth/entities/deployers/test_adjudicator_deployer.py +++ b/tests/blockchain/eth/entities/deployers/test_adjudicator_deployer.py @@ -46,12 +46,11 @@ def test_adjudicator_deployer(session_testerchain, slashing_economics, deploymen deployment_receipts = deployer.deploy(secret_hash=os.urandom(DispatcherDeployer.DISPATCHER_SECRET_LENGTH), progress=deployment_progress) - assert len(deployment_receipts) == 3 # deployment steps must match expected number of steps - assert deployment_progress.num_steps == deployer.number_of_deployment_transactions + assert deployment_progress.num_steps == len(deployer.deployment_steps) == len(deployment_receipts) == 3 - for title, receipt in deployment_receipts.items(): - assert receipt['status'] == 1 + for step in deployer.deployment_steps: + assert deployment_receipts[step]['status'] == 1 # Create an AdjudicatorAgent instance adjudicator_agent = deployer.make_agent() diff --git a/tests/blockchain/eth/entities/deployers/test_interdeployer_integration.py b/tests/blockchain/eth/entities/deployers/test_interdeployer_integration.py index fa8c7145c..d08f5a936 100644 --- a/tests/blockchain/eth/entities/deployers/test_interdeployer_integration.py +++ b/tests/blockchain/eth/entities/deployers/test_interdeployer_integration.py @@ -137,7 +137,6 @@ def test_deploy_ethereum_contracts(session_testerchain, deployment_progress): assert another_adjudicator_agent.contract_address == adjudicator_deployer.contract_address == adjudicator_agent.contract_address # overall deployment steps must match aggregated individual expected number of steps - assert deployment_progress.num_steps == (token_deployer.number_of_deployment_transactions + - staking_escrow_deployer.number_of_deployment_transactions + - policy_manager_deployer.number_of_deployment_transactions + - adjudicator_deployer.number_of_deployment_transactions) + all_deployment_transactions = token_deployer.deployment_steps + staking_escrow_deployer.deployment_steps + \ + policy_manager_deployer.deployment_steps + adjudicator_deployer.deployment_steps + assert deployment_progress.num_steps == len(all_deployment_transactions) diff --git a/tests/blockchain/eth/entities/deployers/test_policy_manager_deployer.py b/tests/blockchain/eth/entities/deployers/test_policy_manager_deployer.py index d1f6dec37..f0ec0269d 100644 --- a/tests/blockchain/eth/entities/deployers/test_policy_manager_deployer.py +++ b/tests/blockchain/eth/entities/deployers/test_policy_manager_deployer.py @@ -20,6 +20,7 @@ import pytest from eth_utils import keccak from nucypher.blockchain.eth.agents import PolicyManagerAgent, StakingEscrowAgent +from nucypher.blockchain.eth.constants import POLICY_MANAGER_CONTRACT_NAME from nucypher.blockchain.eth.deployers import ( PolicyManagerDeployer, DispatcherDeployer @@ -38,14 +39,18 @@ def policy_manager_deployer(staking_escrow_deployer, session_testerchain): def test_policy_manager_deployment(policy_manager_deployer, staking_escrow_deployer, deployment_progress): + + assert policy_manager_deployer.contract_name == POLICY_MANAGER_CONTRACT_NAME + deployment_receipts = policy_manager_deployer.deploy(secret_hash=keccak(text=POLICY_MANAGER_DEPLOYMENT_SECRET), progress=deployment_progress) - assert len(deployment_receipts) == 3 - # deployment steps must match expected number of steps - assert deployment_progress.num_steps == policy_manager_deployer.number_of_deployment_transactions - for title, receipt in deployment_receipts.items(): - assert receipt['status'] == 1 + # deployment steps must match expected number of steps + steps = policy_manager_deployer.deployment_steps + assert deployment_progress.num_steps == len(steps) == len(deployment_receipts) == 3 + + for step_title in steps: + assert deployment_receipts[step_title]['status'] == 1 staking_escrow_address = policy_manager_deployer.contract.functions.escrow().call() assert staking_escrow_deployer.contract_address == staking_escrow_address diff --git a/tests/blockchain/eth/entities/deployers/test_staking_escrow_deployer.py b/tests/blockchain/eth/entities/deployers/test_staking_escrow_deployer.py index 6890aac1e..7688b5049 100644 --- a/tests/blockchain/eth/entities/deployers/test_staking_escrow_deployer.py +++ b/tests/blockchain/eth/entities/deployers/test_staking_escrow_deployer.py @@ -28,12 +28,11 @@ def test_staking_escrow_deployment(staking_escrow_deployer, deployment_progress) secret_hash = keccak(text=STAKING_ESCROW_DEPLOYMENT_SECRET) deployment_receipts = staking_escrow_deployer.deploy(secret_hash=secret_hash, progress=deployment_progress) - assert len(deployment_receipts) == 4 # deployment steps must match expected number of steps - assert deployment_progress.num_steps == staking_escrow_deployer.number_of_deployment_transactions + assert deployment_progress.num_steps == len(staking_escrow_deployer.deployment_steps) == len(deployment_receipts) == 4 - for title, receipt in deployment_receipts.items(): - assert receipt['status'] == 1 + for step in staking_escrow_deployer.deployment_steps: + assert deployment_receipts[step]['status'] == 1 def test_make_agent(staking_escrow_deployer): diff --git a/tests/blockchain/eth/entities/deployers/test_token_deployer.py b/tests/blockchain/eth/entities/deployers/test_token_deployer.py index 5f5285688..438a92308 100644 --- a/tests/blockchain/eth/entities/deployers/test_token_deployer.py +++ b/tests/blockchain/eth/entities/deployers/test_token_deployer.py @@ -38,7 +38,7 @@ def test_token_deployer_and_agent(session_testerchain, deployment_progress): assert receipt['status'] == 1 # deployment steps must match expected number of steps - assert deployment_progress.num_steps == deployer.number_of_deployment_transactions + assert deployment_progress.num_steps == len(deployer.deployment_steps) == 1 # Create a token instance token_agent = deployer.make_agent() diff --git a/tests/blockchain/eth/entities/deployers/test_user_escrow_deployer.py b/tests/blockchain/eth/entities/deployers/test_user_escrow_deployer.py index e2d3d19f4..0bc492437 100644 --- a/tests/blockchain/eth/entities/deployers/test_user_escrow_deployer.py +++ b/tests/blockchain/eth/entities/deployers/test_user_escrow_deployer.py @@ -48,12 +48,12 @@ def test_user_escrow_deployer(session_testerchain, session_agency, user_escrow_p user_escrow_proxy_receipts = user_escrow_proxy_deployer.deploy(secret_hash=secret_hash, progress=deployment_progress) - assert len(user_escrow_proxy_receipts) == 2 # deployment steps must match expected number of steps - assert deployment_progress.num_steps == user_escrow_proxy_deployer.number_of_deployment_transactions + assert deployment_progress.num_steps == len(user_escrow_proxy_deployer.deployment_steps) == 2 + assert len(user_escrow_proxy_receipts) == 2 - for title, receipt in user_escrow_proxy_receipts.items(): - assert receipt['status'] == 1 + for step in user_escrow_proxy_deployer.deployment_steps: + assert user_escrow_proxy_receipts[step]['status'] == 1 deployer = UserEscrowDeployer(deployer_address=deployer_account, blockchain=testerchain)