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
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,

View File

@ -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

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),
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()

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
# 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)

View File

@ -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

View File

@ -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):

View File

@ -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()

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,
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)