Merge pull request #1170 from derekpierre/progressbar

UX: Add the ability to provide progress during NuCypher contract deployments
pull/1124/head
David Núñez 2019-07-30 18:48:16 +02:00 committed by GitHub
commit 0df7d97939
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 146 additions and 66 deletions

View File

@ -27,14 +27,12 @@ from constant_sorrow.constants import (
CONTRACT_NOT_DEPLOYED, CONTRACT_NOT_DEPLOYED,
NO_DEPLOYER_ADDRESS, NO_DEPLOYER_ADDRESS,
WORKER_NOT_RUNNING, WORKER_NOT_RUNNING,
NO_WORKER_ASSIGNED, NO_WORKER_ASSIGNED
NO_FUNDING_ACCOUNT
) )
from eth_tester.exceptions import TransactionFailed from eth_tester.exceptions import TransactionFailed
from eth_utils import is_checksum_address from eth_utils import is_checksum_address
from eth_utils import keccak from eth_utils import keccak
from twisted.logger import Logger from twisted.logger import Logger
from web3 import Web3
from nucypher.blockchain.economics import TokenEconomics from nucypher.blockchain.economics import TokenEconomics
from nucypher.blockchain.eth.agents import ( from nucypher.blockchain.eth.agents import (
@ -43,8 +41,6 @@ from nucypher.blockchain.eth.agents import (
PolicyManagerAgent, PolicyManagerAgent,
AdjudicatorAgent AdjudicatorAgent
) )
from nucypher.blockchain.eth.constants import NUCYPHER_TOKEN_CONTRACT_NAME, ADJUDICATOR_CONTRACT_NAME, \
USER_ESCROW_PROXY_CONTRACT_NAME, POLICY_MANAGER_CONTRACT_NAME, STAKING_ESCROW_CONTRACT_NAME
from nucypher.blockchain.eth.decorators import validate_checksum_address from nucypher.blockchain.eth.decorators import validate_checksum_address
from nucypher.blockchain.eth.deployers import ( from nucypher.blockchain.eth.deployers import (
NucypherTokenDeployer, NucypherTokenDeployer,
@ -230,6 +226,7 @@ class DeployerActor(NucypherTokenActor):
contract_name: str, contract_name: str,
gas_limit: int = None, gas_limit: int = None,
plaintext_secret: str = None, plaintext_secret: str = None,
progress=None
) -> Tuple[dict, ContractDeployer]: ) -> Tuple[dict, ContractDeployer]:
Deployer = self.__get_deployer(contract_name=contract_name) Deployer = self.__get_deployer(contract_name=contract_name)
@ -238,9 +235,9 @@ class DeployerActor(NucypherTokenActor):
if not plaintext_secret: if not plaintext_secret:
raise ValueError("Upgrade plaintext_secret must be passed to deploy an upgradeable contract.") raise ValueError("Upgrade plaintext_secret must be passed to deploy an upgradeable contract.")
secret_hash = keccak(bytes(plaintext_secret, encoding='utf-8')) secret_hash = keccak(bytes(plaintext_secret, encoding='utf-8'))
txhashes = deployer.deploy(secret_hash=secret_hash, gas_limit=gas_limit) txhashes = deployer.deploy(secret_hash=secret_hash, gas_limit=gas_limit, progress=progress)
else: else:
txhashes = deployer.deploy(gas_limit=gas_limit) txhashes = deployer.deploy(gas_limit=gas_limit, progress=progress)
return txhashes, deployer return txhashes, deployer
def upgrade_contract(self, contract_name: str, existing_plaintext_secret: str, new_plaintext_secret: str) -> dict: def upgrade_contract(self, contract_name: str, existing_plaintext_secret: str, new_plaintext_secret: str) -> dict:
@ -286,38 +283,41 @@ class DeployerActor(NucypherTokenActor):
deployment_receipts = dict() deployment_receipts = dict()
gas_limit = None # TODO: Gas management gas_limit = None # TODO: Gas management
# NuCypherToken # deploy contracts
if emitter: total_deployment_transactions = 0
emitter.echo(f"\nDeploying {NUCYPHER_TOKEN_CONTRACT_NAME} ...") for deployer_class in self.deployer_classes:
total_deployment_transactions += deployer_class.number_of_deployment_transactions
token_receipts, token_deployer = self.deploy_contract(contract_name=NUCYPHER_TOKEN_CONTRACT_NAME, first_iteration = True
gas_limit=gas_limit) with click.progressbar(length=total_deployment_transactions, label="Deployment progress") as bar:
bar.short_limit = 0
for deployer_class in self.deployer_classes:
if interactive and not first_iteration:
click.pause(info="\nPress any key to continue")
if emitter: if emitter:
paint_contract_deployment(contract_name=NUCYPHER_TOKEN_CONTRACT_NAME, emitter.echo(f"\nDeploying {deployer_class.contract_name} ...")
receipts=token_receipts, bar._last_line = None
contract_address=token_deployer.contract_address, bar.render_progress()
emitter=emitter)
deployment_receipts[NUCYPHER_TOKEN_CONTRACT_NAME] = token_receipts if deployer_class in self.standard_deployer_classes:
receipts, deployer = self.deploy_contract(contract_name=deployer_class.contract_name,
gas_limit=gas_limit,
progress=bar)
else:
receipts, deployer = self.deploy_contract(contract_name=deployer_class.contract_name,
plaintext_secret=secrets[deployer_class.contract_name],
gas_limit=gas_limit,
progress=bar)
for contract_deployer in self.upgradeable_deployer_classes: if emitter:
if interactive: paint_contract_deployment(contract_name=deployer_class.contract_name,
click.pause(info="Press any key to continue") receipts=receipts,
contract_address=deployer.contract_address,
emitter=emitter)
if emitter: deployment_receipts[deployer_class.contract_name] = receipts
emitter.echo(f"\nDeploying {contract_deployer.contract_name} ...") first_iteration = False
receipts, deployer = self.deploy_contract(contract_name=contract_deployer.contract_name,
plaintext_secret=secrets[contract_deployer.contract_name],
gas_limit=gas_limit)
if emitter:
paint_contract_deployment(contract_name=contract_deployer.contract_name,
receipts=receipts,
contract_address=deployer.contract_address,
emitter=emitter)
deployment_receipts[contract_deployer.contract_name] = receipts
return deployment_receipts return deployment_receipts

View File

@ -24,7 +24,7 @@ from web3.contract import Contract
from nucypher.blockchain.eth.constants import DISPATCHER_CONTRACT_NAME, STAKING_ESCROW_CONTRACT_NAME, \ from nucypher.blockchain.eth.constants import DISPATCHER_CONTRACT_NAME, STAKING_ESCROW_CONTRACT_NAME, \
POLICY_MANAGER_CONTRACT_NAME, USER_ESCROW_CONTRACT_NAME, USER_ESCROW_PROXY_CONTRACT_NAME, \ POLICY_MANAGER_CONTRACT_NAME, USER_ESCROW_CONTRACT_NAME, USER_ESCROW_PROXY_CONTRACT_NAME, \
LIBRARY_LINKER_CONTRACT_NAME, ADJUDICATOR_CONTRACT_NAME LIBRARY_LINKER_CONTRACT_NAME, ADJUDICATOR_CONTRACT_NAME, NUCYPHER_TOKEN_CONTRACT_NAME
from nucypher.blockchain.eth.decorators import validate_checksum_address from nucypher.blockchain.eth.decorators import validate_checksum_address
from nucypher.blockchain.eth.interfaces import BlockchainInterface from nucypher.blockchain.eth.interfaces import BlockchainInterface
from nucypher.blockchain.eth.registry import AllocationRegistry from nucypher.blockchain.eth.registry import AllocationRegistry
@ -124,7 +124,7 @@ class EthereumContractAgent:
class NucypherTokenAgent(EthereumContractAgent, metaclass=Agency): class NucypherTokenAgent(EthereumContractAgent, metaclass=Agency):
registry_contract_name = "NuCypherToken" registry_contract_name = NUCYPHER_TOKEN_CONTRACT_NAME
def get_balance(self, address: str = None) -> int: def get_balance(self, address: str = None) -> int:
"""Get the balance of a token address, or of this contract address""" """Get the balance of a token address, or of this contract address"""

View File

@ -14,7 +14,6 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License You should have received a copy of the GNU Affero General Public License
along with nucypher. If not, see <https://www.gnu.org/licenses/>. along with nucypher. If not, see <https://www.gnu.org/licenses/>.
""" """
import collections
from typing import Tuple, Dict from typing import Tuple, Dict
from constant_sorrow.constants import CONTRACT_NOT_DEPLOYED, NO_DEPLOYER_CONFIGURED, NO_BENEFICIARY from constant_sorrow.constants import CONTRACT_NOT_DEPLOYED, NO_DEPLOYER_CONFIGURED, NO_BENEFICIARY
@ -31,14 +30,15 @@ from nucypher.blockchain.eth.agents import (
AdjudicatorAgent) AdjudicatorAgent)
from nucypher.blockchain.eth.constants import DISPATCHER_CONTRACT_NAME from nucypher.blockchain.eth.constants import DISPATCHER_CONTRACT_NAME
from nucypher.blockchain.eth.decorators import validate_secret from nucypher.blockchain.eth.decorators import validate_secret
from nucypher.blockchain.eth.interfaces import BlockchainDeployerInterface, BlockchainInterface from nucypher.blockchain.eth.interfaces import BlockchainDeployerInterface
from nucypher.blockchain.eth.registry import AllocationRegistry, EthereumContractRegistry from nucypher.blockchain.eth.registry import AllocationRegistry
class ContractDeployer: class ContractDeployer:
agency = NotImplemented agency = NotImplemented
contract_name = NotImplemented contract_name = NotImplemented
number_of_deployment_transactions = NotImplemented
_interface_class = BlockchainDeployerInterface _interface_class = BlockchainDeployerInterface
_upgradeable = NotImplemented _upgradeable = NotImplemented
__linker_deployer = NotImplemented __linker_deployer = NotImplemented
@ -126,7 +126,7 @@ class ContractDeployer:
raise self.ContractDeploymentError(message) raise self.ContractDeploymentError(message)
return True return True
def deploy(self, secret_hash: bytes, gas_limit: int) -> dict: def deploy(self, secret_hash: bytes, gas_limit: int, progress) -> dict:
""" """
Provides for the setup, deployment, and initialization of ethereum smart contracts. Provides for the setup, deployment, and initialization of ethereum smart contracts.
Emits the configured blockchain network transactions for single contract instance publication. Emits the configured blockchain network transactions for single contract instance publication.
@ -142,6 +142,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
_upgradeable = False _upgradeable = False
def __init__(self, def __init__(self,
@ -156,7 +157,7 @@ class NucypherTokenDeployer(ContractDeployer):
economics = TokenEconomics() economics = TokenEconomics()
self.__economics = economics self.__economics = economics
def deploy(self, gas_limit: int = None) -> dict: def deploy(self, gas_limit: int = None, progress=None) -> dict:
""" """
Deploy and publish the NuCypher Token contract Deploy and publish the NuCypher Token contract
to the blockchain network specified in self.blockchain.network. to the blockchain network specified in self.blockchain.network.
@ -168,6 +169,8 @@ class NucypherTokenDeployer(ContractDeployer):
contract, deployment_receipt = self.blockchain.deploy_contract(self.contract_name, contract, deployment_receipt = self.blockchain.deploy_contract(self.contract_name,
self.__economics.erc20_total_supply, self.__economics.erc20_total_supply,
gas_limit=gas_limit) gas_limit=gas_limit)
if progress:
progress.update(1)
self._contract = contract self._contract = contract
return {'txhash': deployment_receipt} return {'txhash': deployment_receipt}
@ -180,6 +183,7 @@ class DispatcherDeployer(ContractDeployer):
""" """
contract_name = DISPATCHER_CONTRACT_NAME contract_name = DISPATCHER_CONTRACT_NAME
number_of_deployment_transactions = 1
_upgradeable = False _upgradeable = False
DISPATCHER_SECRET_LENGTH = 32 DISPATCHER_SECRET_LENGTH = 32
@ -191,9 +195,12 @@ class DispatcherDeployer(ContractDeployer):
self._contract = self.blockchain.get_proxy(target_address=self.target_contract.address, self._contract = self.blockchain.get_proxy(target_address=self.target_contract.address,
proxy_name=self.contract_name) proxy_name=self.contract_name)
def deploy(self, secret_hash: bytes, gas_limit: int = None) -> dict: def deploy(self, secret_hash: bytes, gas_limit: int = None, progress=None) -> dict:
args = (self.contract_name, self.target_contract.address, bytes(secret_hash)) args = (self.contract_name, self.target_contract.address, bytes(secret_hash))
dispatcher_contract, receipt = self.blockchain.deploy_contract(gas_limit=gas_limit, *args) dispatcher_contract, receipt = self.blockchain.deploy_contract(gas_limit=gas_limit, *args)
if progress:
progress.update(1)
self._contract = dispatcher_contract self._contract = dispatcher_contract
return {'deployment': receipt} return {'deployment': receipt}
@ -234,6 +241,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
_upgradeable = True _upgradeable = True
__proxy_deployer = DispatcherDeployer __proxy_deployer = DispatcherDeployer
@ -259,7 +267,7 @@ class StakingEscrowDeployer(ContractDeployer):
gas_limit=gas_limit) gas_limit=gas_limit)
return the_escrow_contract, deploy_receipt return the_escrow_contract, deploy_receipt
def deploy(self, secret_hash: bytes, gas_limit: int = None) -> dict: def deploy(self, secret_hash: bytes, gas_limit: int = None, progress=None) -> dict:
""" """
Deploy and publish the StakingEscrow contract Deploy and publish the StakingEscrow contract
to the blockchain network specified in self.blockchain.network. to the blockchain network specified in self.blockchain.network.
@ -285,6 +293,8 @@ class StakingEscrowDeployer(ContractDeployer):
# 1 - Deploy # # 1 - Deploy #
the_escrow_contract, deploy_receipt = self._deploy_essential(gas_limit=gas_limit) the_escrow_contract, deploy_receipt = self._deploy_essential(gas_limit=gas_limit)
if progress:
progress.update(1)
# 2 - Deploy the dispatcher used for updating this contract # # 2 - Deploy the dispatcher used for updating this contract #
dispatcher_deployer = DispatcherDeployer(blockchain=self.blockchain, dispatcher_deployer = DispatcherDeployer(blockchain=self.blockchain,
@ -292,6 +302,8 @@ class StakingEscrowDeployer(ContractDeployer):
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_deploy_receipt = dispatcher_deployer.deploy(secret_hash=secret_hash, gas_limit=gas_limit)
if progress:
progress.update(1)
# Cache the dispatcher contract # Cache the dispatcher contract
dispatcher_contract = dispatcher_deployer.contract dispatcher_contract = dispatcher_deployer.contract
@ -311,6 +323,8 @@ class StakingEscrowDeployer(ContractDeployer):
reward_receipt = self.blockchain.send_transaction(contract_function=reward_function, reward_receipt = self.blockchain.send_transaction(contract_function=reward_function,
sender_address=self.deployer_address, sender_address=self.deployer_address,
payload=origin_args) payload=origin_args)
if progress:
progress.update(1)
# Make a call. # Make a call.
_escrow_balance = self.token_agent.get_balance(address=the_escrow_contract.address) _escrow_balance = self.token_agent.get_balance(address=the_escrow_contract.address)
@ -321,6 +335,8 @@ class StakingEscrowDeployer(ContractDeployer):
init_receipt = self.blockchain.send_transaction(contract_function=init_function, init_receipt = self.blockchain.send_transaction(contract_function=init_function,
sender_address=self.deployer_address, sender_address=self.deployer_address,
payload=origin_args) payload=origin_args)
if progress:
progress.update(1)
# Gather the transaction hashes # Gather the transaction hashes
deployment_receipts = {'deploy': deploy_receipt, deployment_receipts = {'deploy': deploy_receipt,
@ -394,6 +410,7 @@ 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
@ -412,17 +429,21 @@ class PolicyManagerDeployer(ContractDeployer):
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) -> Dict[str, str]: def deploy(self, secret_hash: bytes, gas_limit: int = None, progress=None) -> Dict[str, str]:
self.check_deployment_readiness() self.check_deployment_readiness()
# Creator deploys the policy manager # Creator deploys the policy manager
policy_manager_contract, deploy_receipt = self._deploy_essential(gas_limit=gas_limit) policy_manager_contract, deploy_receipt = self._deploy_essential(gas_limit=gas_limit)
if progress:
progress.update(1)
proxy_deployer = self.__proxy_deployer(blockchain=self.blockchain, proxy_deployer = self.__proxy_deployer(blockchain=self.blockchain,
target_contract=policy_manager_contract, target_contract=policy_manager_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_receipt = proxy_deployer.deploy(secret_hash=secret_hash, gas_limit=gas_limit)
if progress:
progress.update(1)
# Cache the dispatcher contract # Cache the dispatcher contract
proxy_contract = proxy_deployer.contract proxy_contract = proxy_deployer.contract
@ -440,6 +461,8 @@ class PolicyManagerDeployer(ContractDeployer):
set_policy_manager_receipt = self.blockchain.send_transaction(contract_function=set_policy_manager_function, set_policy_manager_receipt = self.blockchain.send_transaction(contract_function=set_policy_manager_function,
sender_address=self.deployer_address, sender_address=self.deployer_address,
payload=tx_args) payload=tx_args)
if progress:
progress.update(1)
# Gather the transaction hashes # Gather the transaction hashes
deployment_receipts = {'deployment': deploy_receipt, deployment_receipts = {'deployment': deploy_receipt,
@ -497,6 +520,7 @@ class PolicyManagerDeployer(ContractDeployer):
class LibraryLinkerDeployer(ContractDeployer): class LibraryLinkerDeployer(ContractDeployer):
contract_name = 'UserEscrowLibraryLinker' contract_name = 'UserEscrowLibraryLinker'
number_of_deployment_transactions = 1
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
@ -505,9 +529,12 @@ class LibraryLinkerDeployer(ContractDeployer):
self._contract = self.blockchain.get_proxy(target_address=self.target_contract.address, self._contract = self.blockchain.get_proxy(target_address=self.target_contract.address,
proxy_name=self.contract_name) proxy_name=self.contract_name)
def deploy(self, secret_hash: bytes, gas_limit: int = 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, linker_deployment_txhash = self.blockchain.deploy_contract(gas_limit=gas_limit, *linker_args)
if progress:
progress.update(1)
self._contract = linker_contract self._contract = linker_contract
return {'txhash': linker_deployment_txhash} return {'txhash': linker_deployment_txhash}
@ -531,6 +558,7 @@ class LibraryLinkerDeployer(ContractDeployer):
class UserEscrowProxyDeployer(ContractDeployer): class UserEscrowProxyDeployer(ContractDeployer):
contract_name = 'UserEscrowProxy' contract_name = 'UserEscrowProxy'
number_of_deployment_transactions = 2
__linker_deployer = LibraryLinkerDeployer __linker_deployer = LibraryLinkerDeployer
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -548,7 +576,7 @@ class UserEscrowProxyDeployer(ContractDeployer):
gas_limit=gas_limit) gas_limit=gas_limit)
return contract, deployment_receipt return contract, deployment_receipt
def deploy(self, secret_hash: bytes, gas_limit: int = None) -> dict: def deploy(self, secret_hash: bytes, gas_limit: int = None, progress=None) -> dict:
""" """
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.
@ -558,6 +586,9 @@ class UserEscrowProxyDeployer(ContractDeployer):
# UserEscrowProxy # 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:
progress.update(1)
receipts['deployment'] = deployment_receipt receipts['deployment'] = deployment_receipt
# UserEscrowLibraryLinker # UserEscrowLibraryLinker
@ -566,6 +597,8 @@ class UserEscrowProxyDeployer(ContractDeployer):
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_receipt = linker_deployer.deploy(secret_hash=secret_hash, gas_limit=gas_limit)
if progress:
progress.update(1)
receipts['linker_deployment'] = linker_deployment_receipt['txhash'] receipts['linker_deployment'] = linker_deployment_receipt['txhash']
self._contract = user_escrow_proxy_contract self._contract = user_escrow_proxy_contract
@ -612,6 +645,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
_upgradeable = True _upgradeable = True
__linker_deployer = LibraryLinkerDeployer __linker_deployer = LibraryLinkerDeployer
__allocation_registry = AllocationRegistry __allocation_registry = AllocationRegistry
@ -693,12 +727,15 @@ class UserEscrowDeployer(ContractDeployer):
self.enroll_principal_contract() self.enroll_principal_contract()
return dict(deposit_txhash=deposit_txhash, assign_txhash=assign_txhash) return dict(deposit_txhash=deposit_txhash, assign_txhash=assign_txhash)
def deploy(self, gas_limit: int = None) -> dict: def deploy(self, gas_limit: int = None, progress=None) -> dict:
"""Deploy a new instance of UserEscrow to the blockchain.""" """Deploy a new instance of UserEscrow to the blockchain."""
self.check_deployment_readiness() self.check_deployment_readiness()
linker_contract = self.blockchain.get_contract_by_name(name=self.__linker_deployer.contract_name) linker_contract = self.blockchain.get_contract_by_name(name=self.__linker_deployer.contract_name)
args = (self.contract_name, linker_contract.address, self.token_agent.contract_address) args = (self.contract_name, linker_contract.address, self.token_agent.contract_address)
user_escrow_contract, deploy_receipt = self.blockchain.deploy_contract(*args, gas_limit=gas_limit, enroll=False) user_escrow_contract, deploy_receipt = self.blockchain.deploy_contract(*args, gas_limit=gas_limit, enroll=False)
if progress:
progress.update(1)
self._contract = user_escrow_contract self._contract = user_escrow_contract
return deploy_receipt return deploy_receipt
@ -707,6 +744,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
_upgradeable = True _upgradeable = True
__proxy_deployer = DispatcherDeployer __proxy_deployer = DispatcherDeployer
@ -727,16 +765,20 @@ class AdjudicatorDeployer(ContractDeployer):
gas_limit=gas_limit) gas_limit=gas_limit)
return adjudicator_contract, deploy_receipt return adjudicator_contract, deploy_receipt
def deploy(self, secret_hash: bytes, gas_limit: int = None) -> Dict[str, str]: def deploy(self, secret_hash: bytes, gas_limit: int = None, progress=None) -> Dict[str, str]:
self.check_deployment_readiness() self.check_deployment_readiness()
adjudicator_contract, deploy_receipt = self._deploy_essential(gas_limit=gas_limit) adjudicator_contract, deploy_receipt = self._deploy_essential(gas_limit=gas_limit)
if progress:
progress.update(1)
proxy_deployer = self.__proxy_deployer(blockchain=self.blockchain, proxy_deployer = self.__proxy_deployer(blockchain=self.blockchain,
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_receipt = proxy_deployer.deploy(secret_hash=secret_hash, gas_limit=gas_limit)
if progress:
progress.update(1)
# Cache the dispatcher contract # Cache the dispatcher contract
proxy_contract = proxy_deployer.contract proxy_contract = proxy_deployer.contract
@ -756,6 +798,8 @@ class AdjudicatorDeployer(ContractDeployer):
set_adjudicator_receipt = self.blockchain.send_transaction(contract_function=set_adjudicator_function, set_adjudicator_receipt = self.blockchain.send_transaction(contract_function=set_adjudicator_function,
sender_address=self.deployer_address, sender_address=self.deployer_address,
payload=tx_args) payload=tx_args)
if progress:
progress.update(1)
# Gather the transaction hashes # Gather the transaction hashes
deployment_receipts = {'deployment': deploy_receipt, deployment_receipts = {'deployment': deploy_receipt,

View File

@ -227,7 +227,9 @@ def deploy(action,
paint_deployment_delay(emitter=emitter) paint_deployment_delay(emitter=emitter)
# Execute Deployment # Execute Deployment
deployment_receipts = DEPLOYER.deploy_network_contracts(secrets=secrets, emitter=emitter) deployment_receipts = DEPLOYER.deploy_network_contracts(secrets=secrets,
emitter=emitter,
interactive=not force)
# Paint outfile paths # Paint outfile paths
registry_outfile = DEPLOYER.blockchain.registry.filepath registry_outfile = DEPLOYER.blockchain.registry.filepath

View File

@ -306,7 +306,7 @@ def paint_contract_deployment(emitter, contract_name: str, contract_address: str
# TODO: switch to using an explicit emitter # TODO: switch to using an explicit emitter
# Paint heading # Paint heading
heading = '\n{} ({})'.format(contract_name, contract_address) heading = f'\r{" "*80}\n{contract_name} ({contract_address})'
emitter.echo(heading, bold=True) emitter.echo(heading, bold=True)
emitter.echo('*' * (42 + 3 + len(contract_name))) emitter.echo('*' * (42 + 3 + len(contract_name)))

View File

@ -35,3 +35,16 @@ def staking_escrow_deployer(session_testerchain, token_deployer):
staking_escrow_deployer = StakingEscrowDeployer(blockchain=session_testerchain, staking_escrow_deployer = StakingEscrowDeployer(blockchain=session_testerchain,
deployer_address=session_testerchain.etherbase_account) deployer_address=session_testerchain.etherbase_account)
return staking_escrow_deployer return staking_escrow_deployer
@pytest.fixture(scope="function")
def deployment_progress():
class DeploymentProgress:
num_steps = 0
def update(self, steps: int):
self.num_steps += steps
progress = DeploymentProgress()
return progress

View File

@ -29,7 +29,7 @@ from nucypher.blockchain.eth.deployers import (
@pytest.mark.slow() @pytest.mark.slow()
def test_adjudicator_deployer(session_testerchain, slashing_economics): def test_adjudicator_deployer(session_testerchain, slashing_economics, deployment_progress):
testerchain = session_testerchain testerchain = session_testerchain
origin = testerchain.etherbase_account origin = testerchain.etherbase_account
@ -43,9 +43,12 @@ def test_adjudicator_deployer(session_testerchain, slashing_economics):
staking_agent = staking_escrow_deployer.make_agent() # 2 Staker Escrow staking_agent = staking_escrow_deployer.make_agent() # 2 Staker Escrow
deployer = AdjudicatorDeployer(deployer_address=origin, blockchain=testerchain) deployer = AdjudicatorDeployer(deployer_address=origin, blockchain=testerchain)
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)
assert len(deployment_receipts) == 3 assert len(deployment_receipts) == 3
# deployment steps must match expected number of steps
assert deployment_progress.num_steps == deployer.number_of_deployment_transactions
for title, receipt in deployment_receipts.items(): for title, receipt in deployment_receipts.items():
assert receipt['status'] == 1 assert receipt['status'] == 1

View File

@ -30,7 +30,7 @@ from nucypher.blockchain.eth.deployers import (NucypherTokenDeployer,
@pytest.mark.slow() @pytest.mark.slow()
def test_deploy_ethereum_contracts(session_testerchain): def test_deploy_ethereum_contracts(session_testerchain, deployment_progress):
testerchain = session_testerchain testerchain = session_testerchain
origin, *everybody_else = testerchain.client.accounts origin, *everybody_else = testerchain.client.accounts
@ -45,7 +45,7 @@ def test_deploy_ethereum_contracts(session_testerchain):
assert token_deployer.contract_address is constants.CONTRACT_NOT_DEPLOYED assert token_deployer.contract_address is constants.CONTRACT_NOT_DEPLOYED
assert not token_deployer.is_deployed assert not token_deployer.is_deployed
token_deployer.deploy() token_deployer.deploy(progress=deployment_progress)
assert token_deployer.is_deployed assert token_deployer.is_deployed
assert len(token_deployer.contract_address) == 42 assert len(token_deployer.contract_address) == 42
@ -70,7 +70,7 @@ def test_deploy_ethereum_contracts(session_testerchain):
assert staking_escrow_deployer.contract_address is constants.CONTRACT_NOT_DEPLOYED assert staking_escrow_deployer.contract_address is constants.CONTRACT_NOT_DEPLOYED
assert not staking_escrow_deployer.is_deployed assert not staking_escrow_deployer.is_deployed
staking_escrow_deployer.deploy(secret_hash=keccak(stakers_escrow_secret)) staking_escrow_deployer.deploy(secret_hash=keccak(stakers_escrow_secret), progress=deployment_progress)
assert staking_escrow_deployer.is_deployed assert staking_escrow_deployer.is_deployed
assert len(staking_escrow_deployer.contract_address) == 42 assert len(staking_escrow_deployer.contract_address) == 42
@ -97,7 +97,7 @@ def test_deploy_ethereum_contracts(session_testerchain):
assert policy_manager_deployer.contract_address is constants.CONTRACT_NOT_DEPLOYED assert policy_manager_deployer.contract_address is constants.CONTRACT_NOT_DEPLOYED
assert not policy_manager_deployer.is_deployed assert not policy_manager_deployer.is_deployed
policy_manager_deployer.deploy(secret_hash=keccak(policy_manager_secret)) policy_manager_deployer.deploy(secret_hash=keccak(policy_manager_secret), progress=deployment_progress)
assert policy_manager_deployer.is_deployed assert policy_manager_deployer.is_deployed
assert len(policy_manager_deployer.contract_address) == 42 assert len(policy_manager_deployer.contract_address) == 42
@ -124,7 +124,7 @@ def test_deploy_ethereum_contracts(session_testerchain):
assert adjudicator_deployer.contract_address is constants.CONTRACT_NOT_DEPLOYED assert adjudicator_deployer.contract_address is constants.CONTRACT_NOT_DEPLOYED
assert not adjudicator_deployer.is_deployed assert not adjudicator_deployer.is_deployed
adjudicator_deployer.deploy(secret_hash=keccak(adjudicator_secret)) adjudicator_deployer.deploy(secret_hash=keccak(adjudicator_secret), progress=deployment_progress)
assert adjudicator_deployer.is_deployed assert adjudicator_deployer.is_deployed
assert len(adjudicator_deployer.contract_address) == 42 assert len(adjudicator_deployer.contract_address) == 42
@ -135,3 +135,9 @@ def test_deploy_ethereum_contracts(session_testerchain):
another_adjudicator_agent = AdjudicatorAgent() another_adjudicator_agent = AdjudicatorAgent()
assert len(another_adjudicator_agent.contract_address) == 42 assert len(another_adjudicator_agent.contract_address) == 42
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
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)

View File

@ -37,10 +37,12 @@ def policy_manager_deployer(staking_escrow_deployer, session_testerchain):
return policy_manager_deployer return policy_manager_deployer
def test_policy_manager_deployment(policy_manager_deployer, staking_escrow_deployer): def test_policy_manager_deployment(policy_manager_deployer, staking_escrow_deployer, deployment_progress):
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)
assert len(deployment_receipts) == 3 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(): for title, receipt in deployment_receipts.items():
assert receipt['status'] == 1 assert receipt['status'] == 1

View File

@ -24,11 +24,13 @@ from nucypher.blockchain.eth.deployers import (StakingEscrowDeployer,
from nucypher.utilities.sandbox.blockchain import STAKING_ESCROW_DEPLOYMENT_SECRET from nucypher.utilities.sandbox.blockchain import STAKING_ESCROW_DEPLOYMENT_SECRET
def test_staking_escrow_deployment(staking_escrow_deployer): 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) deployment_receipts = staking_escrow_deployer.deploy(secret_hash=secret_hash, progress=deployment_progress)
assert len(deployment_receipts) == 4 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
for title, receipt in deployment_receipts.items(): for title, receipt in deployment_receipts.items():
assert receipt['status'] == 1 assert receipt['status'] == 1

View File

@ -21,7 +21,7 @@ from nucypher.blockchain.eth.deployers import NucypherTokenDeployer
from nucypher.blockchain.eth.interfaces import EthereumContractRegistry from nucypher.blockchain.eth.interfaces import EthereumContractRegistry
def test_token_deployer_and_agent(session_testerchain): def test_token_deployer_and_agent(session_testerchain, deployment_progress):
testerchain = session_testerchain testerchain = session_testerchain
origin = testerchain.etherbase_account origin = testerchain.etherbase_account
@ -32,11 +32,14 @@ def test_token_deployer_and_agent(session_testerchain):
# The big day... # The big day...
deployer = NucypherTokenDeployer(blockchain=testerchain, deployer_address=origin) deployer = NucypherTokenDeployer(blockchain=testerchain, deployer_address=origin)
deployment_receipts = deployer.deploy() deployment_receipts = deployer.deploy(progress=deployment_progress)
for title, receipt in deployment_receipts.items(): for title, receipt in deployment_receipts.items():
assert receipt['status'] == 1 assert receipt['status'] == 1
# deployment steps must match expected number of steps
assert deployment_progress.num_steps == deployer.number_of_deployment_transactions
# Create a token instance # Create a token instance
token_agent = deployer.make_agent() token_agent = deployer.make_agent()
token_contract = token_agent.contract token_contract = token_agent.contract

View File

@ -40,13 +40,18 @@ def user_escrow_proxy_deployer(session_testerchain, session_agency):
@pytest.mark.slow() @pytest.mark.slow()
def test_user_escrow_deployer(session_testerchain, session_agency, user_escrow_proxy_deployer): def test_user_escrow_deployer(session_testerchain, session_agency, user_escrow_proxy_deployer, deployment_progress):
testerchain = session_testerchain testerchain = session_testerchain
deployer_account = testerchain.etherbase_account deployer_account = testerchain.etherbase_account
secret_hash = keccak_digest(USER_ESCROW_PROXY_DEPLOYMENT_SECRET.encode()) secret_hash = keccak_digest(USER_ESCROW_PROXY_DEPLOYMENT_SECRET.encode())
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)
assert len(user_escrow_proxy_receipts) == 2 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
for title, receipt in user_escrow_proxy_receipts.items(): for title, receipt in user_escrow_proxy_receipts.items():
assert receipt['status'] == 1 assert receipt['status'] == 1