Deployers now hold explicit list of deployment steps

pull/1175/head
David Núñez 2019-08-03 01:06:32 +02:00
parent d82afa6d25
commit 586f7edb89
8 changed files with 80 additions and 68 deletions

View File

@ -286,7 +286,7 @@ class DeployerActor(NucypherTokenActor):
# deploy contracts # deploy contracts
total_deployment_transactions = 0 total_deployment_transactions = 0
for deployer_class in self.deployer_classes: 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 first_iteration = True
with click.progressbar(length=total_deployment_transactions, with click.progressbar(length=total_deployment_transactions,

View File

@ -38,7 +38,9 @@ class ContractDeployer:
agency = NotImplemented agency = NotImplemented
contract_name = NotImplemented contract_name = NotImplemented
number_of_deployment_transactions = NotImplemented deployment_steps = NotImplemented
upgrade_steps = NotImplemented
rollback_steps = NotImplemented
_interface_class = BlockchainDeployerInterface _interface_class = BlockchainDeployerInterface
_upgradeable = NotImplemented _upgradeable = NotImplemented
__linker_deployer = NotImplemented __linker_deployer = NotImplemented
@ -142,7 +144,7 @@ class NucypherTokenDeployer(ContractDeployer):
agency = NucypherTokenAgent agency = NucypherTokenAgent
contract_name = agency.registry_contract_name contract_name = agency.registry_contract_name
number_of_deployment_transactions = 1 deployment_steps = ('contract_deployment', )
_upgradeable = False _upgradeable = False
def __init__(self, def __init__(self,
@ -173,7 +175,7 @@ class NucypherTokenDeployer(ContractDeployer):
progress.update(1) progress.update(1)
self._contract = contract self._contract = contract
return {'txhash': deployment_receipt} return {self.deployment_steps[0]: deployment_receipt}
class DispatcherDeployer(ContractDeployer): class DispatcherDeployer(ContractDeployer):
@ -183,7 +185,7 @@ class DispatcherDeployer(ContractDeployer):
""" """
contract_name = DISPATCHER_CONTRACT_NAME contract_name = DISPATCHER_CONTRACT_NAME
number_of_deployment_transactions = 1 deployment_steps = ('contract_deployment', )
_upgradeable = False _upgradeable = False
DISPATCHER_SECRET_LENGTH = 32 DISPATCHER_SECRET_LENGTH = 32
@ -202,7 +204,7 @@ class DispatcherDeployer(ContractDeployer):
progress.update(1) progress.update(1)
self._contract = dispatcher_contract self._contract = dispatcher_contract
return {'deployment': receipt} return {self.deployment_steps[0]: receipt}
@validate_secret @validate_secret
def retarget(self, new_target: str, existing_secret_plaintext: bytes, new_secret_hash: bytes, gas_limit: int = None) -> dict: 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 agency = StakingEscrowAgent
contract_name = agency.registry_contract_name contract_name = agency.registry_contract_name
number_of_deployment_transactions = 4 deployment_steps = ('contract_deployment', 'dispatcher_deployment', 'reward_transfer', 'initialize')
_upgradeable = True _upgradeable = True
__proxy_deployer = DispatcherDeployer __proxy_deployer = DispatcherDeployer
@ -301,7 +303,8 @@ class StakingEscrowDeployer(ContractDeployer):
target_contract=the_escrow_contract, target_contract=the_escrow_contract,
deployer_address=self.deployer_address) 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: if progress:
progress.update(1) progress.update(1)
@ -338,13 +341,11 @@ class StakingEscrowDeployer(ContractDeployer):
if progress: if progress:
progress.update(1) progress.update(1)
# Gather the transaction hashes # Gather the transaction receipts
deployment_receipts = {'deploy': deploy_receipt, ordered_receipts = (deploy_receipt, dispatcher_deploy_receipt, reward_receipt, init_receipt)
'dispatcher_deploy': dispatcher_deploy_receipt['deployment'], deployment_receipts = dict(zip(self.deployment_steps, ordered_receipts))
'reward_transfer': reward_receipt,
'initialize': init_receipt}
# Set the contract and transaction hashes # # Set the contract and transaction receipts #
self._contract = the_escrow_contract self._contract = the_escrow_contract
self.deployment_receipts = deployment_receipts self.deployment_receipts = deployment_receipts
return deployment_receipts return deployment_receipts
@ -410,10 +411,12 @@ class PolicyManagerDeployer(ContractDeployer):
agency = PolicyManagerAgent agency = PolicyManagerAgent
contract_name = agency.registry_contract_name contract_name = agency.registry_contract_name
number_of_deployment_transactions = 3
_upgradeable = True _upgradeable = True
__proxy_deployer = DispatcherDeployer __proxy_deployer = DispatcherDeployer
deployment_steps = ('deployment', 'dispatcher_deployment', 'set_policy_manager')
def make_agent(self) -> EthereumContractAgent: def make_agent(self) -> EthereumContractAgent:
agent = self.agency(blockchain=self.blockchain, contract=self._contract) agent = self.agency(blockchain=self.blockchain, contract=self._contract)
return agent return agent
@ -425,11 +428,11 @@ class PolicyManagerDeployer(ContractDeployer):
def _deploy_essential(self, gas_limit: int = None): def _deploy_essential(self, gas_limit: int = None):
policy_manager_contract, deploy_receipt = self.blockchain.deploy_contract(self.contract_name, policy_manager_contract, deploy_receipt = self.blockchain.deploy_contract(self.contract_name,
self.staking_agent.contract_address, self.staking_agent.contract_address,
gas_limit=gas_limit) gas_limit=gas_limit)
return policy_manager_contract, deploy_receipt 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() self.check_deployment_readiness()
# Creator deploys the policy manager # Creator deploys the policy manager
@ -442,6 +445,7 @@ class PolicyManagerDeployer(ContractDeployer):
deployer_address=self.deployer_address) deployer_address=self.deployer_address)
proxy_deploy_receipt = proxy_deployer.deploy(secret_hash=secret_hash, gas_limit=gas_limit) 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: if progress:
progress.update(1) progress.update(1)
@ -464,10 +468,9 @@ class PolicyManagerDeployer(ContractDeployer):
if progress: if progress:
progress.update(1) progress.update(1)
# Gather the transaction hashes # Gather the transaction receipts
deployment_receipts = {'deployment': deploy_receipt, ordered_receipts = (deploy_receipt, proxy_deploy_receipt, set_policy_manager_receipt)
'dispatcher_deployment': proxy_deploy_receipt['deployment'], deployment_receipts = dict(zip(self.deployment_steps, ordered_receipts))
'set_policy_manager': set_policy_manager_receipt}
self.deployment_receipts = deployment_receipts self.deployment_receipts = deployment_receipts
self._contract = wrapped_contract self._contract = wrapped_contract
@ -486,9 +489,10 @@ class PolicyManagerDeployer(ContractDeployer):
deployer_address=self.deployer_address, deployer_address=self.deployer_address,
bare=True) # acquire agency for the dispatcher itself. bare=True) # acquire agency for the dispatcher itself.
# Creator deploys the policy manager # Creator deploys new version of PolicyManager
policy_manager_contract, deploy_txhash = self._deploy_essential(gas_limit=gas_limit) 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, upgrade_receipt = proxy_deployer.retarget(new_target=policy_manager_contract.address,
existing_secret_plaintext=existing_secret_plaintext, existing_secret_plaintext=existing_secret_plaintext,
new_secret_hash=new_secret_hash, new_secret_hash=new_secret_hash,
@ -498,7 +502,9 @@ class PolicyManagerDeployer(ContractDeployer):
self._contract = self.blockchain._wrap_contract(proxy_deployer.contract, self._contract = self.blockchain._wrap_contract(proxy_deployer.contract,
target_contract=policy_manager_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 return upgrade_transaction
def rollback(self, existing_secret_plaintext: bytes, new_secret_hash: bytes, gas_limit: int = None): 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): class LibraryLinkerDeployer(ContractDeployer):
contract_name = 'UserEscrowLibraryLinker' contract_name = 'UserEscrowLibraryLinker'
number_of_deployment_transactions = 1 deployment_steps = ('contract_deployment', )
def __init__(self, target_contract: Contract, bare: bool = False, *args, **kwargs): def __init__(self, target_contract: Contract, bare: bool = False, *args, **kwargs):
self.target_contract = target_contract 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: 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_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: if progress:
progress.update(1) progress.update(1)
self._contract = linker_contract self._contract = linker_contract
return {'txhash': linker_deployment_txhash} return {self.deployment_steps[0]: receipt}
@validate_secret @validate_secret
def retarget(self, new_target: str, existing_secret_plaintext: bytes, new_secret_hash: bytes, gas_limit: int = None): 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): class UserEscrowProxyDeployer(ContractDeployer):
contract_name = 'UserEscrowProxy' contract_name = 'UserEscrowProxy'
number_of_deployment_transactions = 2 deployment_steps = ('contract_deployment', 'linker_deployment')
__linker_deployer = LibraryLinkerDeployer __linker_deployer = LibraryLinkerDeployer
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -581,28 +587,27 @@ class UserEscrowProxyDeployer(ContractDeployer):
Deploys a new UserEscrowProxy contract, and a new UserEscrowLibraryLinker, targeting the first. Deploys a new UserEscrowProxy contract, and a new UserEscrowLibraryLinker, targeting the first.
This is meant to be called only once per general deployment. This is meant to be called only once per general deployment.
""" """
# 1 - UserEscrowProxy
receipts = dict()
# UserEscrowProxy
user_escrow_proxy_contract, deployment_receipt = self._deploy_essential(gas_limit=gas_limit) user_escrow_proxy_contract, deployment_receipt = self._deploy_essential(gas_limit=gas_limit)
if progress: if progress:
progress.update(1) progress.update(1)
receipts['deployment'] = deployment_receipt # 2 - UserEscrowLibraryLinker
# UserEscrowLibraryLinker
linker_deployer = self.__linker_deployer(blockchain=self.blockchain, linker_deployer = self.__linker_deployer(blockchain=self.blockchain,
deployer_address=self.deployer_address, deployer_address=self.deployer_address,
target_contract=user_escrow_proxy_contract) 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: if progress:
progress.update(1) 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 self._contract = user_escrow_proxy_contract
return receipts return deployment_receipts
@classmethod @classmethod
def get_latest_version(cls, blockchain) -> Contract: def get_latest_version(cls, blockchain) -> Contract:
@ -636,6 +641,8 @@ class UserEscrowProxyDeployer(ContractDeployer):
new_secret_hash=new_secret_hash, new_secret_hash=new_secret_hash,
gas_limit=gas_limit) gas_limit=gas_limit)
# TODO: Contract ABI is not updated in Agents when upgrade/rollback #1184
deployment_receipts['linker_retarget'] = linker_receipt deployment_receipts['linker_retarget'] = linker_receipt
self._contract = user_escrow_proxy_contract self._contract = user_escrow_proxy_contract
return deployment_receipts return deployment_receipts
@ -645,7 +652,7 @@ class UserEscrowDeployer(ContractDeployer):
agency = UserEscrowAgent agency = UserEscrowAgent
contract_name = agency.registry_contract_name contract_name = agency.registry_contract_name
number_of_deployment_transactions = 1 deployment_steps = ('contract_deployment', )
_upgradeable = True _upgradeable = True
__linker_deployer = LibraryLinkerDeployer __linker_deployer = LibraryLinkerDeployer
__allocation_registry = AllocationRegistry __allocation_registry = AllocationRegistry
@ -737,6 +744,7 @@ class UserEscrowDeployer(ContractDeployer):
progress.update(1) progress.update(1)
self._contract = user_escrow_contract self._contract = user_escrow_contract
# TODO: Homogenize with rest of deployer receipts
return deploy_receipt return deploy_receipt
@ -744,7 +752,7 @@ class AdjudicatorDeployer(ContractDeployer):
agency = AdjudicatorAgent agency = AdjudicatorAgent
contract_name = agency.registry_contract_name contract_name = agency.registry_contract_name
number_of_deployment_transactions = 3 deployment_steps = ('contract_deployment', 'dispatcher_deployment', 'set_adjudicator')
_upgradeable = True _upgradeable = True
__proxy_deployer = DispatcherDeployer __proxy_deployer = DispatcherDeployer
@ -776,7 +784,8 @@ class AdjudicatorDeployer(ContractDeployer):
target_contract=adjudicator_contract, target_contract=adjudicator_contract,
deployer_address=self.deployer_address) 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: if progress:
progress.update(1) progress.update(1)
@ -801,10 +810,9 @@ class AdjudicatorDeployer(ContractDeployer):
if progress: if progress:
progress.update(1) progress.update(1)
# Gather the transaction hashes # Gather the transaction receipts
deployment_receipts = {'deployment': deploy_receipt, ordered_receipts = (deploy_receipt, proxy_deploy_receipt, set_adjudicator_receipt)
'dispatcher_deployment': proxy_deploy_receipt['deployment'], deployment_receipts = dict(zip(self.deployment_steps, ordered_receipts))
'set_adjudicator': set_adjudicator_receipt}
self.deployment_receipts = deployment_receipts self.deployment_receipts = deployment_receipts
self._contract = adjudicator_contract self._contract = adjudicator_contract
@ -838,6 +846,8 @@ class AdjudicatorDeployer(ContractDeployer):
# Switch the contract for the wrapped one # Switch the contract for the wrapped one
self._contract = wrapped_adjudicator_contract 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']} upgrade_transaction = {'deploy': deploy_receipt, 'retarget': upgrade_receipt['transactionHash']}
return upgrade_transaction return upgrade_transaction

View File

@ -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), deployment_receipts = deployer.deploy(secret_hash=os.urandom(DispatcherDeployer.DISPATCHER_SECRET_LENGTH),
progress=deployment_progress) progress=deployment_progress)
assert len(deployment_receipts) == 3
# deployment steps must match expected number of steps # 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(): for step in deployer.deployment_steps:
assert receipt['status'] == 1 assert deployment_receipts[step]['status'] == 1
# Create an AdjudicatorAgent instance # Create an AdjudicatorAgent instance
adjudicator_agent = deployer.make_agent() adjudicator_agent = deployer.make_agent()

View File

@ -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 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 # overall deployment steps must match aggregated individual expected number of steps
assert deployment_progress.num_steps == (token_deployer.number_of_deployment_transactions + all_deployment_transactions = token_deployer.deployment_steps + staking_escrow_deployer.deployment_steps + \
staking_escrow_deployer.number_of_deployment_transactions + policy_manager_deployer.deployment_steps + adjudicator_deployer.deployment_steps
policy_manager_deployer.number_of_deployment_transactions + assert deployment_progress.num_steps == len(all_deployment_transactions)
adjudicator_deployer.number_of_deployment_transactions)

View File

@ -20,6 +20,7 @@ import pytest
from eth_utils import keccak from eth_utils import keccak
from nucypher.blockchain.eth.agents import PolicyManagerAgent, StakingEscrowAgent from nucypher.blockchain.eth.agents import PolicyManagerAgent, StakingEscrowAgent
from nucypher.blockchain.eth.constants import POLICY_MANAGER_CONTRACT_NAME
from nucypher.blockchain.eth.deployers import ( from nucypher.blockchain.eth.deployers import (
PolicyManagerDeployer, PolicyManagerDeployer,
DispatcherDeployer 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): 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), deployment_receipts = policy_manager_deployer.deploy(secret_hash=keccak(text=POLICY_MANAGER_DEPLOYMENT_SECRET),
progress=deployment_progress) 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(): # deployment steps must match expected number of steps
assert receipt['status'] == 1 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() staking_escrow_address = policy_manager_deployer.contract.functions.escrow().call()
assert staking_escrow_deployer.contract_address == staking_escrow_address assert staking_escrow_deployer.contract_address == staking_escrow_address

View File

@ -28,12 +28,11 @@ def test_staking_escrow_deployment(staking_escrow_deployer, deployment_progress)
secret_hash = keccak(text=STAKING_ESCROW_DEPLOYMENT_SECRET) secret_hash = keccak(text=STAKING_ESCROW_DEPLOYMENT_SECRET)
deployment_receipts = staking_escrow_deployer.deploy(secret_hash=secret_hash, progress=deployment_progress) 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 # 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(): for step in staking_escrow_deployer.deployment_steps:
assert receipt['status'] == 1 assert deployment_receipts[step]['status'] == 1
def test_make_agent(staking_escrow_deployer): def test_make_agent(staking_escrow_deployer):

View File

@ -38,7 +38,7 @@ def test_token_deployer_and_agent(session_testerchain, deployment_progress):
assert receipt['status'] == 1 assert receipt['status'] == 1
# deployment steps must match expected number of steps # 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 # Create a token instance
token_agent = deployer.make_agent() token_agent = deployer.make_agent()

View File

@ -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, user_escrow_proxy_receipts = user_escrow_proxy_deployer.deploy(secret_hash=secret_hash,
progress=deployment_progress) progress=deployment_progress)
assert len(user_escrow_proxy_receipts) == 2
# deployment steps must match expected number of steps # 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(): for step in user_escrow_proxy_deployer.deployment_steps:
assert receipt['status'] == 1 assert user_escrow_proxy_receipts[step]['status'] == 1
deployer = UserEscrowDeployer(deployer_address=deployer_account, deployer = UserEscrowDeployer(deployer_address=deployer_account,
blockchain=testerchain) blockchain=testerchain)