Esempio n. 1
0
def test_rapid_deployment():
    compiler = SolidityCompiler()
    registry = InMemoryEthereumContractRegistry()
    allocation_registry = InMemoryAllocationRegistry()
    interface = BlockchainDeployerInterface(compiler=compiler,
                                            registry=registry,
                                            provider_uri='tester://pyevm')
    blockchain = TesterBlockchain(interface=interface,
                                  airdrop=False,
                                  test_accounts=4)
    blockchain.ether_airdrop(amount=1000000000)
    origin, *everyone = blockchain.interface.w3.eth.accounts

    deployer = Deployer(blockchain=blockchain, deployer_address=origin)

    deployer_address, *all_yall = deployer.blockchain.interface.w3.eth.accounts

    # The Big Three (+ Dispatchers)
    deployer.deploy_network_contracts(miner_secret=os.urandom(32),
                                      policy_secret=os.urandom(32))

    # User Escrow Proxy
    deployer.deploy_escrow_proxy(secret=os.urandom(32))

    # Deploy User Escrow
    total_allocations = 100

    # Start with some hard-coded cases...
    allocation_data = [{
        'address': all_yall[1],
        'amount': MAX_ALLOWED_LOCKED,
        'duration': ONE_YEAR_IN_SECONDS
    }, {
        'address': all_yall[2],
        'amount': MIN_ALLOWED_LOCKED,
        'duration': ONE_YEAR_IN_SECONDS * 2
    }, {
        'address': all_yall[3],
        'amount': MIN_ALLOWED_LOCKED * 100,
        'duration': ONE_YEAR_IN_SECONDS * 3
    }]

    # Pile on the rest
    for _ in range(total_allocations - len(allocation_data)):
        random_password = ''.join(
            random.SystemRandom().choice(string.ascii_uppercase +
                                         string.digits) for _ in range(16))
        acct = w3.eth.account.create(random_password)
        beneficiary_address = acct.address
        amount = random.randint(MIN_ALLOWED_LOCKED, MAX_ALLOWED_LOCKED)
        duration = random.randint(MIN_LOCKED_PERIODS, MAX_MINTING_PERIODS * 3)
        random_allocation = {
            'address': beneficiary_address,
            'amount': amount,
            'duration': duration
        }
        allocation_data.append(random_allocation)

    deployer.deploy_beneficiary_contracts(
        allocations=allocation_data, allocation_registry=allocation_registry)
Esempio n. 2
0
def test_geth_deployment_integration(instant_geth_dev_node):

    # TODO: Move to decorator
    if 'CIRCLECI' in os.environ:
        pytest.skip("Do not run Geth nodes in CI")

    memory_registry = InMemoryEthereumContractRegistry()
    blockchain = BlockchainDeployerInterface(
        provider_process=instant_geth_dev_node, registry=memory_registry)

    # Make Deployer
    etherbase = to_checksum_address(instant_geth_dev_node.accounts[0].decode(
    ))  # TODO: Make property on nucypher geth node instances?
    deployer = DeployerActor(
        blockchain=blockchain,
        deployer_address=etherbase,
        client_password=None)  # dev accounts have no password.

    assert int(deployer.blockchain.client.chain_id) == 1337

    # Deploy
    secrets = dict()
    for deployer_class in deployer.upgradeable_deployer_classes:
        secrets[deployer_class.contract_name] = INSECURE_DEVELOPMENT_PASSWORD

    deployer.deploy_network_contracts(secrets=secrets, interactive=False)
Esempio n. 3
0
def testerchain(solidity_compiler):
    """
    https: // github.com / ethereum / eth - tester     # available-backends
    """
    memory_registry = InMemoryEthereumContractRegistry()

    # Use the the custom provider and registrar to init an interface

    deployer_interface = BlockchainDeployerInterface(
        compiler=solidity_compiler,  # freshly recompile if not None
        registry=memory_registry,
        provider_uri='tester://pyevm')

    # Create the blockchain
    testerchain = TesterBlockchain(
        interface=deployer_interface,
        test_accounts=NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK,
        airdrop=False)

    origin, *everyone = testerchain.interface.w3.eth.accounts
    deployer_interface.deployer_address = origin  # Set the deployer address from a freshly created test account
    testerchain.ether_airdrop(amount=1000000000)  # TODO: Use test constant

    yield testerchain
    testerchain.sever_connection()
Esempio n. 4
0
def testerchain(solidity_compiler):
    """
    https: // github.com / ethereum / eth - tester     # available-backends
    """
    memory_registry = InMemoryEthereumContractRegistry()

    # Use the the custom provider and registrar to init an interface

    deployer_interface = BlockchainDeployerInterface(
        compiler=solidity_compiler,  # freshly recompile if not None
        registry=memory_registry,
        provider_uri=TEST_PROVIDER_URI)

    # Create the blockchain
    testerchain = TesterBlockchain(interface=deployer_interface,
                                   eth_airdrop=True,
                                   free_transactions=True,
                                   poa=True)

    # Set the deployer address from a freshly created test account
    deployer_interface.deployer_address = testerchain.etherbase_account

    yield testerchain
    deployer_interface.disconnect()
    testerchain.sever_connection()
Esempio n. 5
0
    def connect(cls, *args, **kwargs) -> 'TesterBlockchain':
        interface = BlockchainDeployerInterface(provider_uri=cls._PROVIDER_URI,
                                                compiler=SolidityCompiler(test_contract_dir=CONTRACT_ROOT),
                                                registry=InMemoryEthereumContractRegistry())

        testerchain = TesterBlockchain(interface=interface, *args, **kwargs)
        return testerchain
Esempio n. 6
0
def test_upgradeability(temp_dir_path):
    # Prepare remote source for compilation
    download_github_dir(GITHUB_SOURCE_LINK, temp_dir_path)
    solidity_compiler = SolidityCompiler(source_dirs=[SourceDirs(SolidityCompiler.default_contract_dir()),
                                                      SourceDirs(temp_dir_path)])

    # Prepare the blockchain
    provider_uri = 'tester://pyevm/2'
    try:
        blockchain_interface = BlockchainDeployerInterface(provider_uri=provider_uri,
                                                           compiler=solidity_compiler,
                                                           gas_strategy=free_gas_price_strategy)
        blockchain_interface.connect()
        origin = blockchain_interface.client.accounts[0]
        BlockchainInterfaceFactory.register_interface(interface=blockchain_interface)
        blockchain_interface.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD, account=origin)
        blockchain_interface.transacting_power.activate()

        # Check contracts with multiple versions
        raw_contracts = blockchain_interface._raw_contract_cache
        contract_name = AdjudicatorDeployer.contract_name
        test_adjudicator = len(raw_contracts[contract_name]) > 1
        contract_name = StakingEscrowDeployer.contract_name
        test_staking_escrow = len(raw_contracts[contract_name]) > 1
        contract_name = PolicyManagerDeployer.contract_name
        test_policy_manager = len(raw_contracts[contract_name]) > 1

        if not test_adjudicator and not test_staking_escrow and not test_policy_manager:
            return

        # Prepare master version of contracts and upgrade to the latest
        registry = InMemoryContractRegistry()

        token_deployer = NucypherTokenDeployer(registry=registry, deployer_address=origin)
        token_deployer.deploy()

        staking_escrow_deployer = StakingEscrowDeployer(registry=registry, deployer_address=origin)
        deploy_earliest_contract(blockchain_interface, staking_escrow_deployer)
        if test_staking_escrow:
            staking_escrow_deployer.upgrade(contract_version="latest", confirmations=0)

        if test_policy_manager:
            policy_manager_deployer = PolicyManagerDeployer(registry=registry, deployer_address=origin)
            deploy_earliest_contract(blockchain_interface, policy_manager_deployer)
            policy_manager_deployer.upgrade(contract_version="latest", confirmations=0)

        if test_adjudicator:
            adjudicator_deployer = AdjudicatorDeployer(registry=registry, deployer_address=origin)
            deploy_earliest_contract(blockchain_interface, adjudicator_deployer)
            adjudicator_deployer.upgrade(contract_version="latest", confirmations=0)

    finally:
        # Unregister interface
        with contextlib.suppress(KeyError):
            del BlockchainInterfaceFactory._interfaces[provider_uri]
Esempio n. 7
0
def _initialize_blockchain(poa, provider_uri, emitter):
    if not BlockchainInterfaceFactory.is_interface_initialized(provider_uri=provider_uri):
        # Note: For test compatibility.
        deployer_interface = BlockchainDeployerInterface(provider_uri=provider_uri, poa=poa)
        BlockchainInterfaceFactory.register_interface(interface=deployer_interface, sync=False,
                                                      emitter=emitter)
    else:
        deployer_interface = BlockchainInterfaceFactory.get_interface(provider_uri=provider_uri)

    deployer_interface.connect()
    return deployer_interface
Esempio n. 8
0
def another_testerchain(solidity_compiler):
    memory_registry = InMemoryEthereumContractRegistry()
    deployer_interface = BlockchainDeployerInterface(
        compiler=solidity_compiler,
        registry=memory_registry,
        provider_uri=TEST_PROVIDER_URI)
    testerchain = TesterBlockchain(interface=deployer_interface,
                                   test_accounts=2 *
                                   NUMBER_OF_ETH_TEST_ACCOUNTS,
                                   eth_airdrop=True)
    deployer_interface.deployer_address = testerchain.etherbase_account
    yield testerchain
    testerchain.sever_connection()
def test_rapid_deployment(token_economics):
    compiler = SolidityCompiler()
    registry = InMemoryEthereumContractRegistry()
    allocation_registry = InMemoryAllocationRegistry()
    interface = BlockchainDeployerInterface(compiler=compiler,
                                            registry=registry,
                                            provider_uri='tester://pyevm')

    blockchain = TesterBlockchain(interface=interface, airdrop=False, test_accounts=4)
    deployer_address = blockchain.etherbase_account

    deployer = Deployer(blockchain=blockchain, deployer_address=deployer_address)

    # The Big Three (+ Dispatchers)
    deployer.deploy_network_contracts(miner_secret=MINERS_ESCROW_DEPLOYMENT_SECRET,
                                      policy_secret=POLICY_MANAGER_DEPLOYMENT_SECRET,
                                      adjudicator_secret=MINING_ADJUDICATOR_DEPLOYMENT_SECRET)

    # Deploy User Escrow, too (+ Linker)
    deployer.deploy_escrow_proxy(secret=USER_ESCROW_PROXY_DEPLOYMENT_SECRET)

    total_allocations = NUMBER_OF_ALLOCATIONS_IN_TESTS

    all_yall = blockchain.unassigned_accounts
    # Start with some hard-coded cases...
    allocation_data = [{'address': all_yall[1],
                        'amount': token_economics.maximum_allowed_locked,
                        'duration': ONE_YEAR_IN_SECONDS},

                       {'address': all_yall[2],
                        'amount': token_economics.minimum_allowed_locked,
                        'duration': ONE_YEAR_IN_SECONDS*2},

                       {'address': all_yall[3],
                        'amount': token_economics.minimum_allowed_locked*100,
                        'duration': ONE_YEAR_IN_SECONDS*3}
                       ]

    # Pile on the rest
    for _ in range(total_allocations - len(allocation_data)):
        random_password = ''.join(random.SystemRandom().choice(string.ascii_uppercase+string.digits) for _ in range(16))
        acct = w3.eth.account.create(random_password)
        beneficiary_address = acct.address
        amount = random.randint(token_economics.minimum_allowed_locked, token_economics.maximum_allowed_locked)
        duration = random.randint(token_economics.minimum_locked_periods*ONE_YEAR_IN_SECONDS,
                                  (token_economics.maximum_locked_periods*ONE_YEAR_IN_SECONDS)*3)
        random_allocation = {'address': beneficiary_address, 'amount': amount, 'duration': duration}
        allocation_data.append(random_allocation)

    deployer.deploy_beneficiary_contracts(allocations=allocation_data, allocation_registry=allocation_registry)
Esempio n. 10
0
def _initialize_blockchain(poa, provider_uri, emitter, ignore_solidity_check, gas_strategy=None):
    if not BlockchainInterfaceFactory.is_interface_initialized(provider_uri=provider_uri):
        # Note: For test compatibility.
        deployer_interface = BlockchainDeployerInterface(provider_uri=provider_uri,
                                                         poa=poa,
                                                         ignore_solidity_check=ignore_solidity_check,
                                                         gas_strategy=gas_strategy)

        BlockchainInterfaceFactory.register_interface(interface=deployer_interface,
                                                      sync=False,
                                                      emitter=emitter)
    else:
        deployer_interface = BlockchainInterfaceFactory.get_interface(provider_uri=provider_uri)

    deployer_interface.connect()
    return deployer_interface
Esempio n. 11
0
def deployed_blockchain():

    #
    # Interface
    #
    compiler = SolidityCompiler()
    registry = InMemoryEthereumContractRegistry()
    allocation_registry = InMemoryAllocationRegistry()
    interface = BlockchainDeployerInterface(compiler=compiler,
                                            registry=registry,
                                            provider_uri=TEST_PROVIDER_URI)

    #
    # Blockchain
    #
    blockchain = TesterBlockchain(interface=interface,
                                  airdrop=False,
                                  test_accounts=5,
                                  poa=True)
    blockchain.ether_airdrop(amount=TESTING_ETH_AIRDROP_AMOUNT)
    origin, *everyone = blockchain.interface.w3.eth.accounts

    #
    # Delpoyer
    #
    deployer = Deployer(blockchain=blockchain, deployer_address=origin)

    deployer_address, *all_yall = deployer.blockchain.interface.w3.eth.accounts

    # The Big Three (+ Dispatchers)
    deployer.deploy_network_contracts(miner_secret=os.urandom(32),
                                      policy_secret=os.urandom(32))

    # User Escrow Proxy
    deployer.deploy_escrow_proxy(secret=os.urandom(32))

    # Start with some hard-coded cases...
    allocation_data = [{
        'address': all_yall[1],
        'amount': MAX_ALLOWED_LOCKED,
        'duration': ONE_YEAR_IN_SECONDS
    }]

    deployer.deploy_beneficiary_contracts(
        allocations=allocation_data, allocation_registry=allocation_registry)

    yield blockchain, deployer_address, registry
Esempio n. 12
0
def initialize_deployer_interface(emitter: StdoutEmitter,
                                  poa: bool,
                                  provider_uri,
                                  ignore_solidity_check: bool,
                                  gas_strategy: str = None,
                                  max_gas_price: int = None
                                  ) -> BlockchainDeployerInterface:
    if not BlockchainInterfaceFactory.is_interface_initialized(provider_uri=provider_uri):
        deployer_interface = BlockchainDeployerInterface(provider_uri=provider_uri,
                                                         poa=poa,
                                                         gas_strategy=gas_strategy,
                                                         max_gas_price=max_gas_price)
        BlockchainInterfaceFactory.register_interface(interface=deployer_interface, emitter=emitter)
    else:
        deployer_interface = BlockchainInterfaceFactory.get_interface(provider_uri=provider_uri)
    deployer_interface.connect(ignore_solidity_check=ignore_solidity_check)
    return deployer_interface
Esempio n. 13
0
def test_geth_deployment_integration(instant_geth_dev_node, test_registry):
    blockchain = BlockchainDeployerInterface(
        provider_process=instant_geth_dev_node, poa=True)  # always poa here.
    BlockchainInterfaceFactory.register_interface(interface=blockchain)

    # Make Deployer
    etherbase = to_checksum_address(instant_geth_dev_node.accounts[0].decode(
    ))  # TODO: Make property on nucypher geth node instances?
    administrator = ContractAdministrator(
        registry=test_registry,
        deployer_address=etherbase,
        client_password=None)  # dev accounts have no password.

    assert int(blockchain.client.chain_id) == 1337

    # Deploy
    administrator.deploy_network_contracts(interactive=False)  # just do it
Esempio n. 14
0
def make_testerchain(provider_uri, solidity_compiler):

    # Destroy existing blockchain
    BlockchainInterface.disconnect()
    TesterBlockchain.sever_connection()

    registry = EthereumContractRegistry(registry_filepath=MOCK_REGISTRY_FILEPATH)
    deployer_interface = BlockchainDeployerInterface(compiler=solidity_compiler,
                                                     registry=registry,
                                                     provider_uri=provider_uri)

    # Create new blockchain
    testerchain = TesterBlockchain(interface=deployer_interface,
                                   eth_airdrop=True,
                                   free_transactions=False,
                                   poa=True)

    # Set the deployer address from a freshly created test account
    deployer_interface.deployer_address = testerchain.etherbase_account
    return testerchain
Esempio n. 15
0
def deployed_blockchain(token_economics):

    # Interface
    compiler = SolidityCompiler()
    registry = InMemoryEthereumContractRegistry()
    allocation_registry = InMemoryAllocationRegistry()
    interface = BlockchainDeployerInterface(compiler=compiler,
                                            registry=registry,
                                            provider_uri=TEST_PROVIDER_URI)

    # Blockchain
    blockchain = TesterBlockchain(interface=interface,
                                  airdrop=True,
                                  test_accounts=5,
                                  poa=True)
    deployer_address = blockchain.etherbase_account

    # Deployer
    deployer = Deployer(blockchain=blockchain,
                        deployer_address=deployer_address)

    # The Big Three (+ Dispatchers)
    deployer.deploy_network_contracts(miner_secret=os.urandom(32),
                                      policy_secret=os.urandom(32),
                                      adjudicator_secret=os.urandom(32))

    # User Escrow Proxy
    deployer.deploy_escrow_proxy(secret=os.urandom(32))

    # Start with some hard-coded cases...
    all_yall = blockchain.unassigned_accounts
    allocation_data = [{
        'address': all_yall[1],
        'amount': token_economics.maximum_allowed_locked,
        'duration': ONE_YEAR_IN_SECONDS
    }]

    deployer.deploy_beneficiary_contracts(
        allocations=allocation_data, allocation_registry=allocation_registry)

    yield blockchain, deployer_address, registry
Esempio n. 16
0
def testerchain(solidity_compiler):
    """
    https: // github.com / ethereum / eth - tester     # available-backends
    """

    temp_registrar = TemporaryEthereumContractRegistry()

    # Use the the custom provider and registrar to init an interface

    deployer_interface = BlockchainDeployerInterface(
        compiler=solidity_compiler,  # freshly recompile if not None
        registry=temp_registrar,
        provider_uri='pyevm://tester')

    # Create the blockchain
    testerchain = TesterBlockchain(interface=deployer_interface,
                                   test_accounts=10)
    origin, *everyone = testerchain.interface.w3.eth.accounts
    deployer_interface.deployer_address = origin  # Set the deployer address from a freshly created test account

    yield testerchain

    testerchain.sever_connection()
Esempio n. 17
0
def deploy(action, poa, etherscan, provider_uri, gas, deployer_address,
           contract_name, allocation_infile, allocation_outfile,
           registry_infile, registry_outfile, amount, recipient_address,
           config_root, hw_wallet, force, dev):
    """
    Manage contract and registry deployment.

    \b
    Actions
    -----------------------------------------------------------------------------
    contracts              Compile and deploy contracts.
    allocations            Deploy pre-allocation contracts.
    upgrade                Upgrade NuCypher existing proxy contract deployments.
    rollback               Rollback a proxy contract's target.
    status                 Echo owner information and bare contract metadata.
    transfer-tokens        Transfer tokens to another address.
    transfer-ownership     Transfer ownership of contracts to another address.
    """

    emitter = StdoutEmitter()

    #
    # Validate
    #

    # Ensure config root exists, because we need a default place to put output files.
    config_root = config_root or DEFAULT_CONFIG_ROOT
    if not os.path.exists(config_root):
        os.makedirs(config_root)

    #
    # Pre-Launch Warnings
    #

    if not hw_wallet:
        emitter.echo("WARNING: --no-hw-wallet is enabled.", color='yellow')

    if etherscan:
        emitter.echo(
            "WARNING: --etherscan is enabled. "
            "A browser tab will be opened with deployed contracts and TXs as provided by Etherscan.",
            color='yellow')
    else:
        emitter.echo(
            "WARNING: --etherscan is disabled. "
            "If you want to see deployed contracts and TXs in your browser, activate --etherscan.",
            color='yellow')

    #
    # Connect to Registry
    #

    # Establish a contract registry from disk if specified
    registry_filepath = registry_outfile or registry_infile
    if dev:
        # TODO: Need a way to detect a geth--dev registry filepath here. (then deprecate the --dev flag)
        registry_filepath = os.path.join(DEFAULT_CONFIG_ROOT,
                                         'dev_contract_registry.json')
    registry = EthereumContractRegistry(registry_filepath=registry_filepath)
    emitter.echo(f"Using contract registry filepath {registry.filepath}")

    #
    # Connect to Blockchain
    #

    blockchain = BlockchainDeployerInterface(provider_uri=provider_uri,
                                             poa=poa,
                                             registry=registry)
    try:
        blockchain.connect(fetch_registry=False, sync_now=False)
    except BlockchainDeployerInterface.ConnectionFailed as e:
        emitter.echo(str(e), color='red', bold=True)
        raise click.Abort()

    #
    # Make Authenticated Deployment Actor
    #

    # Verify Address & collect password
    if not deployer_address:
        prompt = "Select deployer account"
        deployer_address = select_client_account(emitter=emitter,
                                                 blockchain=blockchain,
                                                 prompt=prompt)

    if not force:
        click.confirm("Selected {} - Continue?".format(deployer_address),
                      abort=True)

    password = None
    if not hw_wallet and not blockchain.client.is_local:
        password = get_client_password(checksum_address=deployer_address)

    # Produce Actor
    DEPLOYER = DeployerActor(blockchain=blockchain,
                             client_password=password,
                             deployer_address=deployer_address)

    # Verify ETH Balance
    emitter.echo(f"\n\nDeployer ETH balance: {DEPLOYER.eth_balance}")
    if DEPLOYER.eth_balance == 0:
        emitter.echo("Deployer address has no ETH.", color='red', bold=True)
        raise click.Abort()

    #
    # Action switch
    #

    if action == 'upgrade':
        if not contract_name:
            raise click.BadArgumentUsage(
                message="--contract-name is required when using --upgrade")
        existing_secret = click.prompt(
            'Enter existing contract upgrade secret', hide_input=True)
        new_secret = click.prompt('Enter new contract upgrade secret',
                                  hide_input=True,
                                  confirmation_prompt=True)
        DEPLOYER.upgrade_contract(contract_name=contract_name,
                                  existing_plaintext_secret=existing_secret,
                                  new_plaintext_secret=new_secret)
        return  # Exit

    elif action == 'rollback':
        if not contract_name:
            raise click.BadArgumentUsage(
                message="--contract-name is required when using --rollback")
        existing_secret = click.prompt(
            'Enter existing contract upgrade secret', hide_input=True)
        new_secret = click.prompt('Enter new contract upgrade secret',
                                  hide_input=True,
                                  confirmation_prompt=True)
        DEPLOYER.rollback_contract(contract_name=contract_name,
                                   existing_plaintext_secret=existing_secret,
                                   new_plaintext_secret=new_secret)
        return  # Exit

    elif action == "contracts":

        #
        # Deploy Single Contract (Amend Registry)
        #

        if contract_name:
            try:
                contract_deployer = DEPLOYER.deployers[contract_name]
            except KeyError:
                message = f"No such contract {contract_name}. Available contracts are {DEPLOYER.deployers.keys()}"
                emitter.echo(message, color='red', bold=True)
                raise click.Abort()
            else:
                emitter.echo(f"Deploying {contract_name}")
                if contract_deployer._upgradeable:
                    secret = DEPLOYER.collect_deployment_secret(
                        deployer=contract_deployer)
                    receipts, agent = DEPLOYER.deploy_contract(
                        contract_name=contract_name, plaintext_secret=secret)
                else:
                    receipts, agent = DEPLOYER.deploy_contract(
                        contract_name=contract_name, gas_limit=gas)
                paint_contract_deployment(
                    contract_name=contract_name,
                    contract_address=agent.contract_address,
                    receipts=receipts,
                    emitter=emitter,
                    chain_name=blockchain.client.chain_name,
                    open_in_browser=etherscan)
            return  # Exit

        #
        # Deploy Automated Series (Create Registry)
        #

        # Confirm filesystem registry writes.
        registry_filepath = DEPLOYER.blockchain.registry.filepath
        if os.path.isfile(registry_filepath):
            emitter.echo(
                f"\nThere is an existing contract registry at {registry_filepath}.\n"
                f"Did you mean 'nucypher-deploy upgrade'?\n",
                color='yellow')
            click.confirm("*DESTROY* existing local registry and continue?",
                          abort=True)
            os.remove(registry_filepath)

        # Stage Deployment
        secrets = DEPLOYER.collect_deployment_secrets()
        paint_staged_deployment(deployer=DEPLOYER, emitter=emitter)

        # Confirm Trigger Deployment
        if not actions.confirm_deployment(emitter=emitter, deployer=DEPLOYER):
            raise click.Abort()

        # Delay - Last chance to abort via KeyboardInterrupt
        paint_deployment_delay(emitter=emitter)

        # Execute Deployment
        deployment_receipts = DEPLOYER.deploy_network_contracts(
            secrets=secrets,
            emitter=emitter,
            interactive=not force,
            etherscan=etherscan)

        # Paint outfile paths
        registry_outfile = DEPLOYER.blockchain.registry.filepath
        emitter.echo('Generated registry {}'.format(registry_outfile),
                     bold=True,
                     color='blue')

        # Save transaction metadata
        receipts_filepath = DEPLOYER.save_deployment_receipts(
            receipts=deployment_receipts)
        emitter.echo(f"Saved deployment receipts to {receipts_filepath}",
                     color='blue',
                     bold=True)
        return  # Exit

    elif action == "allocations":
        if not allocation_infile:
            allocation_infile = click.prompt("Enter allocation data filepath")
        click.confirm("Continue deploying and allocating?", abort=True)
        DEPLOYER.deploy_beneficiaries_from_file(
            allocation_data_filepath=allocation_infile,
            allocation_outfile=allocation_outfile)
        return  # Exit

    elif action == "transfer":
        token_agent = NucypherTokenAgent(blockchain=blockchain)
        missing_options = list()
        if recipient_address is None:
            missing_options.append("--recipient-address")
        if amount is None:
            missing_options.append("--amount")
        if missing_options:
            raise click.BadOptionUsage(
                f"Need {' and '.join(missing_options)} to transfer tokens.")

        click.confirm(
            f"Transfer {amount} from {deployer_address} to {recipient_address}?",
            abort=True)
        receipt = token_agent.transfer(amount=amount,
                                       sender_address=deployer_address,
                                       target_address=recipient_address)
        emitter.echo(f"OK | Receipt: {receipt['transactionHash'].hex()}")
        return  # Exit

    else:
        raise click.BadArgumentUsage(message=f"Unknown action '{action}'")
Esempio n. 18
0
def test_multiversion_contract():
    # Prepare compiler
    base_dir = os.path.join(dirname(abspath(__file__)), "contracts",
                            "multiversion")
    v1_dir = os.path.join(base_dir, "v1")
    v2_dir = os.path.join(base_dir, "v2")
    root_dir = SolidityCompiler.default_contract_dir()
    solidity_compiler = SolidityCompiler(source_dirs=[
        SourceDirs(root_dir, {v2_dir}),
        SourceDirs(root_dir, {v1_dir})
    ])

    # Prepare chain
    blockchain_interface = BlockchainDeployerInterface(
        provider_uri='tester://pyevm/2', compiler=solidity_compiler)
    blockchain_interface.connect()
    origin = blockchain_interface.client.accounts[0]
    blockchain_interface.transacting_power = TransactingPower(
        password=INSECURE_DEVELOPMENT_PASSWORD, account=origin)
    blockchain_interface.transacting_power.activate()

    # Searching both contract through raw data
    contract_name = "VersionTest"
    requested_version = "v1.2.3"
    version, _data = blockchain_interface.find_raw_contract_data(
        contract_name=contract_name, requested_version=requested_version)
    assert version == requested_version
    version, _data = blockchain_interface.find_raw_contract_data(
        contract_name=contract_name, requested_version="latest")
    assert version == requested_version

    requested_version = "v1.1.4"
    version, _data = blockchain_interface.find_raw_contract_data(
        contract_name=contract_name, requested_version=requested_version)
    assert version == requested_version
    version, _data = blockchain_interface.find_raw_contract_data(
        contract_name=contract_name, requested_version="earliest")
    assert version == requested_version

    # Deploy different contracts and check their versions
    registry = InMemoryContractRegistry()
    contract, receipt = blockchain_interface.deploy_contract(
        deployer_address=origin,
        registry=registry,
        contract_name=contract_name,
        contract_version="v1.1.4")
    assert contract.version == "v1.1.4"
    assert contract.functions.VERSION().call() == 1
    contract, receipt = blockchain_interface.deploy_contract(
        deployer_address=origin,
        registry=registry,
        contract_name=contract_name,
        contract_version="earliest")
    assert contract.version == "v1.1.4"
    assert contract.functions.VERSION().call() == 1

    contract, receipt = blockchain_interface.deploy_contract(
        deployer_address=origin,
        registry=registry,
        contract_name=contract_name,
        contract_version="v1.2.3")
    assert contract.version == "v1.2.3"
    assert contract.functions.VERSION().call() == 2
    contract, receipt = blockchain_interface.deploy_contract(
        deployer_address=origin,
        registry=registry,
        contract_name=contract_name,
        contract_version="latest")
    assert contract.version == "v1.2.3"
    assert contract.functions.VERSION().call() == 2
    contract, receipt = blockchain_interface.deploy_contract(
        deployer_address=origin,
        registry=registry,
        contract_name=contract_name)
    assert contract.version == "v1.2.3"
    assert contract.functions.VERSION().call() == 2
Esempio n. 19
0
def test_multiversion_contract():

    # Prepare compiler
    base_dir = TEST_MULTIVERSION_CONTRACTS
    v1_dir, v2_dir = base_dir / 'v1', base_dir / 'v2'
    bundles = [
        SourceBundle(base_path=SOLIDITY_SOURCE_ROOT, other_paths=(v1_dir, )),
        SourceBundle(base_path=SOLIDITY_SOURCE_ROOT, other_paths=(v2_dir, ))
    ]
    compiled_contracts = multiversion_compile(source_bundles=bundles)

    # Prepare chain
    BlockchainDeployerInterface.GAS_STRATEGIES = {
        **BlockchainDeployerInterface.GAS_STRATEGIES, 'free':
        free_gas_price_strategy
    }

    blockchain_interface = BlockchainDeployerInterface(
        provider_uri='tester://pyevm/2', gas_strategy='free')
    blockchain_interface.connect(compile_now=False)
    blockchain_interface._raw_contract_cache = compiled_contracts

    origin = blockchain_interface.client.accounts[0]
    blockchain_interface.transacting_power = TransactingPower(
        password=INSECURE_DEVELOPMENT_PASSWORD,
        signer=Web3Signer(blockchain_interface.client),
        account=origin)
    blockchain_interface.transacting_power.activate()

    # Searching both contract through raw data
    contract_name = "VersionTest"
    requested_version = "v1.2.3"
    version, _data = blockchain_interface.find_raw_contract_data(
        contract_name=contract_name, requested_version=requested_version)
    assert version == requested_version
    version, _data = blockchain_interface.find_raw_contract_data(
        contract_name=contract_name, requested_version="latest")
    assert version == requested_version

    requested_version = "v1.1.4"
    version, _data = blockchain_interface.find_raw_contract_data(
        contract_name=contract_name, requested_version=requested_version)
    assert version == requested_version
    version, _data = blockchain_interface.find_raw_contract_data(
        contract_name=contract_name, requested_version="earliest")
    assert version == requested_version

    # Deploy different contracts and check their versions
    registry = InMemoryContractRegistry()
    contract, receipt = blockchain_interface.deploy_contract(
        deployer_address=origin,
        registry=registry,
        contract_name=contract_name,
        contract_version="v1.1.4")
    assert contract.version == "v1.1.4"
    assert contract.functions.VERSION().call() == 1
    contract, receipt = blockchain_interface.deploy_contract(
        deployer_address=origin,
        registry=registry,
        contract_name=contract_name,
        contract_version="earliest")
    assert contract.version == "v1.1.4"
    assert contract.functions.VERSION().call() == 1

    contract, receipt = blockchain_interface.deploy_contract(
        deployer_address=origin,
        registry=registry,
        contract_name=contract_name,
        contract_version="v1.2.3")
    assert contract.version == "v1.2.3"
    assert contract.functions.VERSION().call() == 2
    contract, receipt = blockchain_interface.deploy_contract(
        deployer_address=origin,
        registry=registry,
        contract_name=contract_name,
        contract_version="latest")
    assert contract.version == "v1.2.3"
    assert contract.functions.VERSION().call() == 2
    contract, receipt = blockchain_interface.deploy_contract(
        deployer_address=origin,
        registry=registry,
        contract_name=contract_name)
    assert contract.version == "v1.2.3"
    assert contract.functions.VERSION().call() == 2
Esempio n. 20
0
def simulate(config, action, nodes, federated_only, geth):
    """
    Simulate the nucypher blockchain network

    Arguments
    ==========

    action - Which action to perform; The choices are:
           - start: Start a multi-process nucypher network simulation
           - stop: Stop a running simulation gracefully

    Options
    ========

    --nodes - The quantity of nodes (processes) to execute during the simulation
    --duration = The number of periods to run the simulation before termination

    """
    if action == 'start':

        #
        # Blockchain Connection
        #
        if not federated_only:
            if geth:
                test_provider_uri = "ipc:///tmp/geth.ipc"
            else:
                test_provider_uri = "pyevm://tester"

            simulation_registry = TemporaryEthereumContractRegistry()
            simulation_interface = BlockchainDeployerInterface(provider_uri=test_provider_uri,
                                                               registry=simulation_registry,
                                                               compiler=SolidityCompiler())

            blockchain = TesterBlockchain(interface=simulation_interface, test_accounts=nodes, airdrop=False)

            accounts = blockchain.interface.w3.eth.accounts
            origin, *everyone_else = accounts

            # Set the deployer address from the freshly created test account
            simulation_interface.deployer_address = origin

            #
            # Blockchain Action
            #
            blockchain.ether_airdrop(amount=DEVELOPMENT_ETH_AIRDROP_AMOUNT)

            click.confirm("Deploy all nucypher contracts to {}?".format(test_provider_uri), abort=True)
            click.echo("Bootstrapping simulated blockchain network")

            # Deploy contracts
            token_deployer = NucypherTokenDeployer(blockchain=blockchain, deployer_address=origin)
            token_deployer.arm()
            token_deployer.deploy()
            token_agent = token_deployer.make_agent()

            miners_escrow_secret = os.urandom(DISPATCHER_SECRET_LENGTH)
            miner_escrow_deployer = MinerEscrowDeployer(token_agent=token_agent,
                                                        deployer_address=origin,
                                                        secret_hash=miners_escrow_secret)
            miner_escrow_deployer.arm()
            miner_escrow_deployer.deploy()
            miner_agent = miner_escrow_deployer.make_agent()

            policy_manager_secret = os.urandom(DISPATCHER_SECRET_LENGTH)
            policy_manager_deployer = PolicyManagerDeployer(miner_agent=miner_agent,
                                                            deployer_address=origin,
                                                            secret_hash=policy_manager_secret)
            policy_manager_deployer.arm()
            policy_manager_deployer.deploy()
            policy_agent = policy_manager_deployer.make_agent()

            airdrop_amount = DEVELOPMENT_TOKEN_AIRDROP_AMOUNT
            click.echo("Airdropping tokens {} to {} addresses".format(airdrop_amount, len(everyone_else)))
            _receipts = token_airdrop(token_agent=token_agent,
                                      origin=origin,
                                      addresses=everyone_else,
                                      amount=airdrop_amount)

            # Commit the current state of deployment to a registry file.
            click.echo("Writing filesystem registry")
            _sim_registry_name = blockchain.interface.registry.commit(filepath=DEFAULT_SIMULATION_REGISTRY_FILEPATH)

        click.echo("Ready to run swarm.")

        #
        # Swarm
        #

        # Select a port range to use on localhost for sim servers

        if not federated_only:
            sim_addresses = everyone_else
        else:
            sim_addresses = NotImplemented

        start_port = 8787
        counter = 0
        for sim_port_number, sim_address in enumerate(sim_addresses, start=start_port):

            #
            # Parse ursula parameters
            #

            rest_port = sim_port_number
            db_name = 'sim-{}'.format(rest_port)

            cli_exec = os.path.join(BASE_DIR, 'cli', 'main.py')
            python_exec = 'python'

            proc_params = '''
            python3 {} run_ursula --rest-port {} --db-name {}
            '''.format(python_exec, cli_exec, rest_port, db_name).split()

            if federated_only:
                proc_params.append('--federated-only')

            else:
                token_agent = NucypherTokenAgent(blockchain=blockchain)
                miner_agent = MinerAgent(token_agent=token_agent)
                miner = Miner(miner_agent=miner_agent, checksum_address=sim_address)

                # stake a random amount
                min_stake, balance = MIN_ALLOWED_LOCKED, miner.token_balance
                value = random.randint(min_stake, balance)

                # for a random lock duration
                min_locktime, max_locktime = MIN_LOCKED_PERIODS, MAX_MINTING_PERIODS
                periods = random.randint(min_locktime, max_locktime)

                miner.initialize_stake(amount=value, lock_periods=periods)
                click.echo("{} Initialized new stake: {} tokens for {} periods".format(sim_address, value, periods))

                proc_params.extend('--checksum-address {}'.format(sim_address).split())

            # Spawn
            click.echo("Spawning node #{}".format(counter+1))
            processProtocol = UrsulaProcessProtocol(command=proc_params)
            cli_exec = os.path.join(BASE_DIR, 'cli', 'main.py')
            ursula_proc = reactor.spawnProcess(processProtocol, cli_exec, proc_params)

            #
            # post-spawnProcess
            #

            # Start with some basic status data, then build on it

            rest_uri = "http://{}:{}".format('localhost', rest_port)

            sim_data = "Started simulated Ursula | ReST {}".format(rest_uri)
            rest_uri = "{host}:{port}".format(host='localhost', port=str(sim_port_number))
            sim_data.format(rest_uri)

            # if not federated_only:
            #     stake_infos = tuple(config.miner_agent.get_all_stakes(miner_address=sim_address))
            #     sim_data += '| ETH address {}'.format(sim_address)
            #     sim_data += '| {} Active stakes '.format(len(stake_infos))

            click.echo(sim_data)
            counter += 1

        click.echo("Starting the reactor")
        click.confirm("Start the reactor?", abort=True)
        try:
            reactor.run()
        finally:

            if not federated_only:
                click.echo("Removing simulation registry")
                os.remove(DEFAULT_SIMULATION_REGISTRY_FILEPATH)

            click.echo("Stopping simulated Ursula processes")
            for process in config.sim_processes:
                os.kill(process.pid, 9)
                click.echo("Killed {}".format(process))

            click.echo("Simulation completed")

    elif action == 'stop':
        # Kill the simulated ursulas
        for process in config.ursula_processes:
            process.transport.signalProcess('KILL')

    elif action == 'status':

        if not config.simulation_running:
            status_message = "Simulation not running."
        else:

            ursula_processes = len(config.ursula_processes)

            status_message = """
            
            | Node Swarm Simulation Status |
            
            Simulation processes .............. {}
            
            """.format(ursula_processes)

        click.echo(status_message)

    elif action == 'demo':
        """Run the finnegans wake demo"""
        demo_exec = os.path.join(BASE_DIR, 'cli', 'demos', 'finnegans-wake-demo.py')
        process_args = [sys.executable, demo_exec]

        if federated_only:
            process_args.append('--federated-only')

        subprocess.run(process_args, stdout=subprocess.PIPE)
def test_upgradeability(temp_dir_path):
    # Prepare remote source for compilation
    download_github_dir(GITHUB_SOURCE_LINK, temp_dir_path)

    # Prepare the blockchain
    BlockchainDeployerInterface.SOURCES = [
        SourceBundle(base_path=SOLIDITY_SOURCE_ROOT),
        SourceBundle(base_path=Path(temp_dir_path))
    ]

    provider_uri = 'tester://pyevm/2'  # TODO: Testerchain caching Issues
    try:
        blockchain_interface = BlockchainDeployerInterface(
            provider_uri=provider_uri, gas_strategy='free')
        blockchain_interface.connect()
        origin = blockchain_interface.client.accounts[0]
        BlockchainInterfaceFactory.register_interface(
            interface=blockchain_interface)
        transacting_power = TransactingPower(
            password=INSECURE_DEVELOPMENT_PASSWORD,
            signer=Web3Signer(blockchain_interface.client),
            account=origin)

        economics = make_token_economics(blockchain_interface)

        # Check contracts with multiple versions
        contract_name = AdjudicatorDeployer.contract_name
        skip_adjudicator_test = skip_test(blockchain_interface, contract_name)
        contract_name = StakingEscrowDeployer.contract_name
        skip_staking_escrow_test = skip_test(blockchain_interface,
                                             contract_name)
        contract_name = PolicyManagerDeployer.contract_name
        skip_policy_manager_test = skip_test(blockchain_interface,
                                             contract_name)

        if not skip_adjudicator_test and not skip_staking_escrow_test and not skip_policy_manager_test:
            return

        # Prepare master version of contracts and upgrade to the latest
        registry = InMemoryContractRegistry()

        token_deployer = NucypherTokenDeployer(registry=registry,
                                               economics=economics)
        token_deployer.deploy(transacting_power=transacting_power)

        staking_escrow_deployer = StakingEscrowDeployer(registry=registry,
                                                        economics=economics)
        staking_escrow_deployer.deploy(deployment_mode=constants.INIT,
                                       transacting_power=transacting_power)

        policy_manager_deployer = PolicyManagerDeployer(registry=registry,
                                                        economics=economics)
        deploy_base_contract(blockchain_interface,
                             policy_manager_deployer,
                             transacting_power=transacting_power,
                             skipt_test=skip_policy_manager_test)

        adjudicator_deployer = AdjudicatorDeployer(registry=registry,
                                                   economics=economics)
        deploy_base_contract(blockchain_interface,
                             adjudicator_deployer,
                             transacting_power=transacting_power,
                             skipt_test=skip_adjudicator_test)

        if skip_staking_escrow_test:
            worklock_deployer = WorklockDeployer(registry=registry,
                                                 economics=economics)
            worklock_deployer.deploy(transacting_power=transacting_power)

        staking_escrow_deployer = StakingEscrowDeployer(registry=registry,
                                                        economics=economics)
        deploy_base_contract(blockchain_interface,
                             staking_escrow_deployer,
                             transacting_power=transacting_power,
                             skipt_test=skip_staking_escrow_test)

        if not skip_staking_escrow_test:
            # TODO prepare at least one staker before calling upgrade
            staking_escrow_deployer.upgrade(
                transacting_power=transacting_power,
                contract_version="latest",
                confirmations=0)

        if not skip_policy_manager_test:
            policy_manager_deployer.upgrade(
                transacting_power=transacting_power,
                contract_version="latest",
                confirmations=0)

        if not skip_adjudicator_test:
            adjudicator_deployer.upgrade(transacting_power=transacting_power,
                                         contract_version="latest",
                                         confirmations=0)

    finally:
        # Unregister interface  # TODO: Move to method?
        with contextlib.suppress(KeyError):
            del BlockchainInterfaceFactory._interfaces[provider_uri]
Esempio n. 22
0
def test_upgradeability(temp_dir_path, token_economics):
    # Prepare remote source for compilation
    download_github_dir(GITHUB_SOURCE_LINK, temp_dir_path)
    solidity_compiler = SolidityCompiler(source_dirs=[
        SourceDirs(SolidityCompiler.default_contract_dir()),
        SourceDirs(temp_dir_path)
    ])

    # Prepare the blockchain
    blockchain_interface = BlockchainDeployerInterface(
        provider_uri='tester://pyevm/2', compiler=solidity_compiler)
    blockchain_interface.connect()
    origin = blockchain_interface.client.accounts[0]
    BlockchainInterfaceFactory.register_interface(
        interface=blockchain_interface)
    blockchain_interface.transacting_power = TransactingPower(
        password=INSECURE_DEVELOPMENT_PASSWORD, account=origin)
    blockchain_interface.transacting_power.activate()

    # Check contracts with multiple versions
    raw_contracts = blockchain_interface._raw_contract_cache
    contract_name = AdjudicatorDeployer.contract_name
    test_adjudicator = len(raw_contracts[contract_name]) > 1
    contract_name = StakingEscrowDeployer.contract_name
    test_staking_escrow = len(raw_contracts[contract_name]) > 1
    contract_name = PolicyManagerDeployer.contract_name
    test_policy_manager = len(raw_contracts[contract_name]) > 1

    if not test_adjudicator and not test_staking_escrow and not test_policy_manager:
        return

    # Prepare master version of contracts and upgrade to the latest
    registry = InMemoryContractRegistry()

    token_deployer = NucypherTokenDeployer(registry=registry,
                                           deployer_address=origin)
    token_deployer.deploy()

    staking_escrow_deployer = StakingEscrowDeployer(registry=registry,
                                                    deployer_address=origin)
    deploy_earliest_contract(blockchain_interface,
                             staking_escrow_deployer,
                             secret=STAKING_ESCROW_DEPLOYMENT_SECRET)
    if test_staking_escrow:
        upgrade_to_latest_contract(staking_escrow_deployer,
                                   secret=STAKING_ESCROW_DEPLOYMENT_SECRET)

    if test_policy_manager:
        policy_manager_deployer = PolicyManagerDeployer(
            registry=registry, deployer_address=origin)
        deploy_earliest_contract(blockchain_interface,
                                 policy_manager_deployer,
                                 secret=POLICY_MANAGER_DEPLOYMENT_SECRET)
        upgrade_to_latest_contract(policy_manager_deployer,
                                   secret=POLICY_MANAGER_DEPLOYMENT_SECRET)

    if test_adjudicator:
        adjudicator_deployer = AdjudicatorDeployer(registry=registry,
                                                   deployer_address=origin)
        deploy_earliest_contract(blockchain_interface,
                                 adjudicator_deployer,
                                 secret=ADJUDICATOR_DEPLOYMENT_SECRET)
        upgrade_to_latest_contract(adjudicator_deployer,
                                   secret=ADJUDICATOR_DEPLOYMENT_SECRET)
Esempio n. 23
0
def deploy(action, poa, etherscan, provider_uri, gas, deployer_address,
           contract_name, allocation_infile, allocation_outfile,
           registry_infile, registry_outfile, value, target_address,
           config_root, hw_wallet, force, dev):
    """
    Manage contract and registry deployment.

    \b
    Actions
    -----------------------------------------------------------------------------
    contracts              Compile and deploy contracts.
    allocations            Deploy pre-allocation contracts.
    upgrade                Upgrade NuCypher existing proxy contract deployments.
    rollback               Rollback a proxy contract's target.
    inspect                Echo owner information and bare contract metadata.
    transfer-tokens        Transfer tokens from a contract to another address using the owner's address.
    transfer-ownership     Transfer ownership of contracts to another address.
    """

    emitter = StdoutEmitter()

    #
    # Validate
    #

    # Ensure config root exists, because we need a default place to put output files.
    config_root = config_root or DEFAULT_CONFIG_ROOT
    if not os.path.exists(config_root):
        os.makedirs(config_root)

    if not provider_uri:
        raise click.BadOptionUsage(
            message=f"--provider is required to deploy.",
            option_name="--provider")

    #
    # Pre-Launch Warnings
    #

    if not hw_wallet:
        emitter.echo("WARNING: --no-hw-wallet is enabled.", color='yellow')

    if etherscan:
        emitter.echo(
            "WARNING: --etherscan is enabled. "
            "A browser tab will be opened with deployed contracts and TXs as provided by Etherscan.",
            color='yellow')
    else:
        emitter.echo(
            "WARNING: --etherscan is disabled. "
            "If you want to see deployed contracts and TXs in your browser, activate --etherscan.",
            color='yellow')

    #
    # Connect to Blockchain
    #

    if not BlockchainInterfaceFactory.is_interface_initialized(
            provider_uri=provider_uri):
        # Note: For test compatibility.
        deployer_interface = BlockchainDeployerInterface(
            provider_uri=provider_uri, poa=poa)
        BlockchainInterfaceFactory.register_interface(
            interface=deployer_interface, sync=False, show_sync_progress=False)
    else:
        deployer_interface = BlockchainInterfaceFactory.get_interface(
            provider_uri=provider_uri)

    if action == "inspect":
        if registry_infile:
            registry = LocalContractRegistry(filepath=registry_infile)
        else:
            registry = InMemoryContractRegistry.from_latest_publication()
        administrator = ContractAdministrator(
            registry=registry, deployer_address=deployer_address)
        paint_deployer_contract_inspection(emitter=emitter,
                                           administrator=administrator)
        return  # Exit

    #
    # Establish Registry
    #

    # Establish a contract registry from disk if specified
    default_registry_filepath = os.path.join(
        DEFAULT_CONFIG_ROOT, BaseContractRegistry.REGISTRY_NAME)
    registry_filepath = (registry_outfile
                         or registry_infile) or default_registry_filepath
    if dev:
        # TODO: Need a way to detect a geth --dev registry filepath here. (then deprecate the --dev flag)
        registry_filepath = os.path.join(config_root,
                                         'dev_contract_registry.json')
    registry = LocalContractRegistry(filepath=registry_filepath)
    emitter.message(f"Configured to registry filepath {registry_filepath}")

    #
    # Make Authenticated Deployment Actor
    #

    # Verify Address & collect password
    if not deployer_address:
        prompt = "Select deployer account"
        deployer_address = select_client_account(emitter=emitter,
                                                 prompt=prompt,
                                                 provider_uri=provider_uri,
                                                 show_balances=False)

    if not force:
        click.confirm("Selected {} - Continue?".format(deployer_address),
                      abort=True)

    password = None
    if not hw_wallet and not deployer_interface.client.is_local:
        password = get_client_password(checksum_address=deployer_address)

    # Produce Actor
    ADMINISTRATOR = ContractAdministrator(registry=registry,
                                          client_password=password,
                                          deployer_address=deployer_address)

    # Verify ETH Balance
    emitter.echo(f"\n\nDeployer ETH balance: {ADMINISTRATOR.eth_balance}")
    if ADMINISTRATOR.eth_balance == 0:
        emitter.echo("Deployer address has no ETH.", color='red', bold=True)
        raise click.Abort()

    #
    # Action switch
    #

    if action == 'upgrade':
        if not contract_name:
            raise click.BadArgumentUsage(
                message="--contract-name is required when using --upgrade")
        existing_secret = click.prompt(
            'Enter existing contract upgrade secret', hide_input=True)
        new_secret = click.prompt('Enter new contract upgrade secret',
                                  hide_input=True,
                                  confirmation_prompt=True)
        ADMINISTRATOR.upgrade_contract(
            contract_name=contract_name,
            existing_plaintext_secret=existing_secret,
            new_plaintext_secret=new_secret)
        return  # Exit

    elif action == 'rollback':
        if not contract_name:
            raise click.BadArgumentUsage(
                message="--contract-name is required when using --rollback")
        existing_secret = click.prompt(
            'Enter existing contract upgrade secret', hide_input=True)
        new_secret = click.prompt('Enter new contract upgrade secret',
                                  hide_input=True,
                                  confirmation_prompt=True)
        ADMINISTRATOR.rollback_contract(
            contract_name=contract_name,
            existing_plaintext_secret=existing_secret,
            new_plaintext_secret=new_secret)
        return  # Exit

    elif action == "contracts":

        #
        # Deploy Single Contract (Amend Registry)
        #

        if contract_name:
            try:
                contract_deployer = ADMINISTRATOR.deployers[contract_name]
            except KeyError:
                message = f"No such contract {contract_name}. Available contracts are {ADMINISTRATOR.deployers.keys()}"
                emitter.echo(message, color='red', bold=True)
                raise click.Abort()
            else:
                emitter.echo(f"Deploying {contract_name}")
                if contract_deployer._upgradeable:
                    secret = ADMINISTRATOR.collect_deployment_secret(
                        deployer=contract_deployer)
                    receipts, agent = ADMINISTRATOR.deploy_contract(
                        contract_name=contract_name, plaintext_secret=secret)
                else:
                    receipts, agent = ADMINISTRATOR.deploy_contract(
                        contract_name=contract_name, gas_limit=gas)
                paint_contract_deployment(
                    contract_name=contract_name,
                    contract_address=agent.contract_address,
                    receipts=receipts,
                    emitter=emitter,
                    chain_name=deployer_interface.client.chain_name,
                    open_in_browser=etherscan)
            return  # Exit

        #
        # Deploy Automated Series (Create Registry)
        #

        # Confirm filesystem registry writes.
        if os.path.isfile(registry_filepath):
            emitter.echo(
                f"\nThere is an existing contract registry at {registry_filepath}.\n"
                f"Did you mean 'nucypher-deploy upgrade'?\n",
                color='yellow')
            click.confirm("*DESTROY* existing local registry and continue?",
                          abort=True)
            os.remove(registry_filepath)

        # Stage Deployment
        secrets = ADMINISTRATOR.collect_deployment_secrets()
        paint_staged_deployment(deployer_interface=deployer_interface,
                                administrator=ADMINISTRATOR,
                                emitter=emitter)

        # Confirm Trigger Deployment
        if not confirm_deployment(emitter=emitter,
                                  deployer_interface=deployer_interface):
            raise click.Abort()

        # Delay - Last chance to abort via KeyboardInterrupt
        paint_deployment_delay(emitter=emitter)

        # Execute Deployment
        deployment_receipts = ADMINISTRATOR.deploy_network_contracts(
            secrets=secrets,
            emitter=emitter,
            interactive=not force,
            etherscan=etherscan)

        # Paint outfile paths
        registry_outfile = registry_filepath
        emitter.echo('Generated registry {}'.format(registry_outfile),
                     bold=True,
                     color='blue')

        # Save transaction metadata
        receipts_filepath = ADMINISTRATOR.save_deployment_receipts(
            receipts=deployment_receipts)
        emitter.echo(f"Saved deployment receipts to {receipts_filepath}",
                     color='blue',
                     bold=True)
        return  # Exit

    elif action == "allocations":
        if not allocation_infile:
            allocation_infile = click.prompt("Enter allocation data filepath")
        click.confirm("Continue deploying and allocating?", abort=True)
        ADMINISTRATOR.deploy_beneficiaries_from_file(
            allocation_data_filepath=allocation_infile,
            allocation_outfile=allocation_outfile)
        return  # Exit

    elif action == "transfer-tokens":
        token_agent = ContractAgency.get_agent(NucypherTokenAgent,
                                               registry=registry)
        if not target_address:
            target_address = click.prompt("Enter recipient's checksum address",
                                          type=EIP55_CHECKSUM_ADDRESS)
        if not value:
            stake_value_range = click.FloatRange(min=0, clamp=False)
            value = NU.from_tokens(
                click.prompt(f"Enter value in NU", type=stake_value_range))

        click.confirm(
            f"Transfer {value} from {deployer_address} to {target_address}?",
            abort=True)
        receipt = token_agent.transfer(amount=value,
                                       sender_address=deployer_address,
                                       target_address=target_address)
        emitter.echo(f"OK | Receipt: {receipt['transactionHash'].hex()}")
        return  # Exit

    elif action == "transfer-ownership":
        if not target_address:
            target_address = click.prompt("Enter new owner's checksum address",
                                          type=EIP55_CHECKSUM_ADDRESS)

        if contract_name:
            try:
                contract_deployer_class = ADMINISTRATOR.deployers[
                    contract_name]
            except KeyError:
                message = f"No such contract {contract_name}. Available contracts are {ADMINISTRATOR.deployers.keys()}"
                emitter.echo(message, color='red', bold=True)
                raise click.Abort()
            else:
                contract_deployer = contract_deployer_class(
                    registry=ADMINISTRATOR.registry,
                    deployer_address=ADMINISTRATOR.deployer_address)
                receipt = contract_deployer.transfer_ownership(
                    new_owner=target_address, transaction_gas_limit=gas)
                emitter.ipc(receipt, request_id=0, duration=0)  # TODO: #1216
                return  # Exit
        else:
            receipts = ADMINISTRATOR.relinquish_ownership(
                new_owner=target_address, transaction_gas_limit=gas)
            emitter.ipc(receipts, request_id=0, duration=0)  # TODO: #1216
            return  # Exit

    else:
        raise click.BadArgumentUsage(message=f"Unknown action '{action}'")
Esempio n. 24
0
def test_deployer_interface_multiversion_contract():

    # Prepare compiler
    base_dir = TEST_MULTIVERSION_CONTRACTS
    v1_dir, v2_dir = base_dir / 'v1', base_dir / 'v2'

    # TODO: Check type of sources
    # I am a contract administrator and I an compiling a new updated version of an existing contract...
    # Represents "Manually hardcoding" a new source directory on BlockchainDeployerInterface.SOURCES.
    BlockchainDeployerInterface.SOURCES = (SourceBundle(base_path=v1_dir),
                                           SourceBundle(base_path=v2_dir))

    # Prepare chain
    BlockchainInterfaceFactory._interfaces.clear()
    blockchain_interface = BlockchainDeployerInterface(
        provider_uri='tester://pyevm', gas_strategy='free')
    blockchain_interface.connect()
    BlockchainInterfaceFactory.register_interface(
        interface=blockchain_interface)  # Lets this test run in isolation

    origin = blockchain_interface.client.accounts[0]
    transacting_power = TransactingPower(
        password=INSECURE_DEVELOPMENT_PASSWORD,
        signer=Web3Signer(blockchain_interface.client),
        account=origin)

    # Searching both contract through raw data
    contract_name = "VersionTest"
    requested_version = "v1.2.3"
    version, _data = blockchain_interface.find_raw_contract_data(
        contract_name=contract_name, requested_version=requested_version)
    assert version == requested_version
    version, _data = blockchain_interface.find_raw_contract_data(
        contract_name=contract_name, requested_version="latest")
    assert version == requested_version

    requested_version = "v1.1.4"
    version, _data = blockchain_interface.find_raw_contract_data(
        contract_name=contract_name, requested_version=requested_version)
    assert version == requested_version
    version, _data = blockchain_interface.find_raw_contract_data(
        contract_name=contract_name, requested_version="earliest")
    assert version == requested_version

    # Deploy different contracts and check their versions
    registry = InMemoryContractRegistry()
    contract, receipt = blockchain_interface.deploy_contract(
        transacting_power=transacting_power,
        registry=registry,
        contract_name=contract_name,
        contract_version="v1.1.4")
    assert contract.version == "v1.1.4"
    assert contract.functions.VERSION().call() == 1
    contract, receipt = blockchain_interface.deploy_contract(
        transacting_power=transacting_power,
        registry=registry,
        contract_name=contract_name,
        contract_version="earliest")
    assert contract.version == "v1.1.4"
    assert contract.functions.VERSION().call() == 1

    contract, receipt = blockchain_interface.deploy_contract(
        transacting_power=transacting_power,
        registry=registry,
        contract_name=contract_name,
        contract_version="v1.2.3")
    assert contract.version == "v1.2.3"
    assert contract.functions.VERSION().call() == 2
    contract, receipt = blockchain_interface.deploy_contract(
        transacting_power=transacting_power,
        registry=registry,
        contract_name=contract_name,
        contract_version="latest")
    assert contract.version == "v1.2.3"
    assert contract.functions.VERSION().call() == 2
    contract, receipt = blockchain_interface.deploy_contract(
        transacting_power=transacting_power,
        registry=registry,
        contract_name=contract_name)
    assert contract.version == "v1.2.3"
    assert contract.functions.VERSION().call() == 2
Esempio n. 25
0
def estimate_gas():
    solidity_compiler = SolidityCompiler(test_contract_dir=CONTRACTS_DIR)

    # create a temporary registrar for the tester blockchain
    temporary_registry = TemporaryEthereumContractRegistry()

    # Configure a custom provider
    overrides = {'gas_limit': 4626271}
    pyevm_backend = OverridablePyEVMBackend(genesis_overrides=overrides)

    eth_tester = EthereumTester(backend=pyevm_backend,
                                auto_mine_transactions=True)
    pyevm_provider = EthereumTesterProvider(ethereum_tester=eth_tester)

    # Use the the custom provider and registrar to init an interface
    circumflex = BlockchainDeployerInterface(
        compiler=solidity_compiler,  # freshly recompile
        registry=temporary_registry,  # use temporary registrar
        providers=(pyevm_provider, ))  # use custom test provider

    # Create the blockchain
    testerchain = TesterBlockchain(interface=circumflex, test_accounts=10)
    origin, ursula1, ursula2, ursula3, alice1, *everyone_else = testerchain.interface.w3.eth.accounts
    circumflex.deployer_address = origin  # Set the deployer address from a freshly created test account

    token_deployer = NucypherTokenDeployer(blockchain=testerchain,
                                           deployer_address=origin)
    token_deployer.arm()
    token_deployer.deploy()
    token_agent = token_deployer.make_agent()

    miners_escrow_secret = os.urandom(constants.DISPATCHER_SECRET_LENGTH)
    miner_escrow_deployer = MinerEscrowDeployer(
        token_agent=token_agent,
        deployer_address=origin,
        secret_hash=testerchain.interface.w3.sha3(miners_escrow_secret))
    miner_escrow_deployer.arm()
    miner_escrow_deployer.deploy()
    miner_agent = miner_escrow_deployer.make_agent()

    policy_manager_secret = os.urandom(constants.DISPATCHER_SECRET_LENGTH)
    policy_manager_deployer = PolicyManagerDeployer(
        miner_agent=miner_agent,
        deployer_address=origin,
        secret_hash=testerchain.interface.w3.sha3(policy_manager_secret))
    policy_manager_deployer.arm()
    policy_manager_deployer.deploy()
    policy_agent = policy_manager_deployer.make_agent()

    web3 = testerchain.interface.w3

    print("Estimate gas:")
    # Pre deposit tokens
    tx = token_agent.contract.functions.approve(miner_agent.contract_address, constants.MIN_ALLOWED_LOCKED * 5)\
        .transact({'from': origin})
    testerchain.wait_for_receipt(tx)
    print("Pre-deposit tokens for 5 owners = " + str(
        miner_agent.contract.functions.preDeposit(
            everyone_else[0:5], [int(constants.MIN_ALLOWED_LOCKED)] *
            5, [int(constants.MIN_LOCKED_PERIODS)] *
            5).estimateGas({'from': origin})))

    # Give Ursula and Alice some coins
    print("Transfer tokens = " + str(
        token_agent.contract.functions.transfer(
            ursula1, constants.MIN_ALLOWED_LOCKED *
            10).estimateGas({'from': origin})))
    tx = token_agent.contract.functions.transfer(
        ursula1, constants.MIN_ALLOWED_LOCKED * 10).transact({'from': origin})
    testerchain.wait_for_receipt(tx)
    tx = token_agent.contract.functions.transfer(
        ursula2, constants.MIN_ALLOWED_LOCKED * 10).transact({'from': origin})
    testerchain.wait_for_receipt(tx)
    tx = token_agent.contract.functions.transfer(
        ursula3, constants.MIN_ALLOWED_LOCKED * 10).transact({'from': origin})
    testerchain.wait_for_receipt(tx)

    # Ursula and Alice give Escrow rights to transfer
    print("Approving transfer = " + str(
        token_agent.contract.functions.approve(
            miner_agent.contract_address, constants.MIN_ALLOWED_LOCKED *
            6).estimateGas({'from': ursula1})))
    tx = token_agent.contract.functions.approve(miner_agent.contract_address, constants.MIN_ALLOWED_LOCKED * 6)\
        .transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    tx = token_agent.contract.functions.approve(miner_agent.contract_address, constants.MIN_ALLOWED_LOCKED * 6)\
        .transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    tx = token_agent.contract.functions.approve(miner_agent.contract_address, constants.MIN_ALLOWED_LOCKED * 6)\
        .transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Ursula and Alice transfer some tokens to the escrow and lock them
    print("First initial deposit tokens = " + str(
        miner_agent.contract.functions.deposit(
            constants.MIN_ALLOWED_LOCKED * 3, int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula1})))
    tx = miner_agent.contract.functions.deposit(constants.MIN_ALLOWED_LOCKED * 3, int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second initial deposit tokens = " + str(
        miner_agent.contract.functions.deposit(
            constants.MIN_ALLOWED_LOCKED * 3, int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula2})))
    tx = miner_agent.contract.functions.deposit(constants.MIN_ALLOWED_LOCKED * 3, int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third initial deposit tokens = " + str(
        miner_agent.contract.functions.deposit(
            constants.MIN_ALLOWED_LOCKED * 3, int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula3})))
    tx = miner_agent.contract.functions.deposit(constants.MIN_ALLOWED_LOCKED * 3, int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Wait 1 period and confirm activity
    testerchain.time_travel(periods=1)
    print("First confirm activity = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula1})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second confirm activity = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula2})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third confirm activity = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula3})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Wait 1 period and mint tokens
    testerchain.time_travel(periods=1)
    print("First mining (1 stake) = " + str(
        miner_agent.contract.functions.mint().estimateGas({'from': ursula1})))
    tx = miner_agent.contract.functions.mint().transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second mining (1 stake) = " + str(
        miner_agent.contract.functions.mint().estimateGas({'from': ursula2})))
    tx = miner_agent.contract.functions.mint().transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third/last mining (1 stake) = " + str(
        miner_agent.contract.functions.mint().estimateGas({'from': ursula3})))
    tx = miner_agent.contract.functions.mint().transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    print("First confirm activity again = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula1})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second confirm activity again = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula2})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third confirm activity again = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula3})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Confirm again
    testerchain.time_travel(periods=1)
    print("First confirm activity + mint = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula1})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second confirm activity + mint = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula2})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third confirm activity + mint = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula3})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Get locked tokens
    print("Getting locked tokens = " + str(
        miner_agent.contract.functions.getLockedTokens(ursula1).estimateGas()))

    # Wait 1 period and withdraw tokens
    testerchain.time_travel(periods=1)
    print("First withdraw = " + str(
        miner_agent.contract.functions.withdraw(1).estimateGas(
            {'from': ursula1})))
    tx = miner_agent.contract.functions.withdraw(1).transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second withdraw = " + str(
        miner_agent.contract.functions.withdraw(1).estimateGas(
            {'from': ursula2})))
    tx = miner_agent.contract.functions.withdraw(1).transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third withdraw = " + str(
        miner_agent.contract.functions.withdraw(1).estimateGas(
            {'from': ursula3})))
    tx = miner_agent.contract.functions.withdraw(1).transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Wait 1 period and confirm activity
    testerchain.time_travel(periods=1)
    print("First confirm activity after downtime = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula1})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second confirm activity after downtime  = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula2})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third confirm activity after downtime  = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula3})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Ursula and Alice deposit some tokens to the escrow again
    print("First deposit tokens again = " + str(
        miner_agent.contract.functions.deposit(
            constants.MIN_ALLOWED_LOCKED * 2, int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula1})))
    tx = miner_agent.contract.functions.deposit(constants.MIN_ALLOWED_LOCKED * 2, int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second deposit tokens again = " + str(
        miner_agent.contract.functions.deposit(
            constants.MIN_ALLOWED_LOCKED * 2, int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula2})))
    tx = miner_agent.contract.functions.deposit(constants.MIN_ALLOWED_LOCKED * 2, int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third deposit tokens again = " + str(
        miner_agent.contract.functions.deposit(
            constants.MIN_ALLOWED_LOCKED * 2, int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula3})))
    tx = miner_agent.contract.functions.deposit(constants.MIN_ALLOWED_LOCKED * 2, int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Wait 1 period and mint tokens
    testerchain.time_travel(periods=1)
    print("First mining again = " + str(
        miner_agent.contract.functions.mint().estimateGas({'from': ursula1})))
    tx = miner_agent.contract.functions.mint().transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second mining again = " + str(
        miner_agent.contract.functions.mint().estimateGas({'from': ursula2})))
    tx = miner_agent.contract.functions.mint().transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third/last mining again = " + str(
        miner_agent.contract.functions.mint().estimateGas({'from': ursula3})))
    tx = miner_agent.contract.functions.mint().transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Create policy
    policy_id_1 = os.urandom(int(constants.POLICY_ID_LENGTH))
    policy_id_2 = os.urandom(int(constants.POLICY_ID_LENGTH))
    number_of_periods = 10
    print("First creating policy (1 node, 10 periods) = " + str(
        policy_agent.contract.functions.createPolicy(
            policy_id_1, number_of_periods, 0, [ursula1]).estimateGas(
                {
                    'from': alice1,
                    'value': 10000
                })))
    tx = policy_agent.contract.functions.createPolicy(policy_id_1, number_of_periods, 0, [ursula1])\
        .transact({'from': alice1, 'value': 10000})
    testerchain.wait_for_receipt(tx)
    print("Second creating policy (1 node, 10 periods) = " + str(
        policy_agent.contract.functions.createPolicy(
            policy_id_2, number_of_periods, 0, [ursula1]).estimateGas(
                {
                    'from': alice1,
                    'value': 10000
                })))
    tx = policy_agent.contract.functions.createPolicy(policy_id_2, number_of_periods, 0, [ursula1])\
        .transact({'from': alice1, 'value': 10000})
    testerchain.wait_for_receipt(tx)

    # Revoke policy
    print("Revoking policy = " + str(
        policy_agent.contract.functions.revokePolicy(policy_id_1).estimateGas(
            {'from': alice1})))
    tx = policy_agent.contract.functions.revokePolicy(policy_id_1).transact(
        {'from': alice1})
    testerchain.wait_for_receipt(tx)
    tx = policy_agent.contract.functions.revokePolicy(policy_id_2).transact(
        {'from': alice1})
    testerchain.wait_for_receipt(tx)

    # Create policy with more periods
    policy_id_1 = os.urandom(int(constants.POLICY_ID_LENGTH))
    policy_id_2 = os.urandom(int(constants.POLICY_ID_LENGTH))
    policy_id_3 = os.urandom(int(constants.POLICY_ID_LENGTH))
    number_of_periods = 100
    print("First creating policy (1 node, " + str(number_of_periods) +
          " periods, first reward) = " + str(
              policy_agent.contract.functions.createPolicy(
                  policy_id_1, number_of_periods, 50, [ursula2]).estimateGas(
                      {
                          'from': alice1,
                          'value': 10050
                      })))
    tx = policy_agent.contract.functions.createPolicy(policy_id_1, number_of_periods, 50, [ursula2])\
        .transact({'from': alice1, 'value': 10050})
    testerchain.wait_for_receipt(tx)
    testerchain.time_travel(periods=1)
    print("Second creating policy (1 node, " + str(number_of_periods) +
          " periods, first reward) = " + str(
              policy_agent.contract.functions.createPolicy(
                  policy_id_2, number_of_periods, 50, [ursula2]).estimateGas(
                      {
                          'from': alice1,
                          'value': 10050
                      })))
    tx = policy_agent.contract.functions.createPolicy(policy_id_2, number_of_periods, 50, [ursula2])\
        .transact({'from': alice1, 'value': 10050})
    testerchain.wait_for_receipt(tx)
    print("Third creating policy (1 node, " + str(number_of_periods) +
          " periods, first reward) = " + str(
              policy_agent.contract.functions.createPolicy(
                  policy_id_3, number_of_periods, 50, [ursula1]).estimateGas(
                      {
                          'from': alice1,
                          'value': 10050
                      })))
    tx = policy_agent.contract.functions.createPolicy(policy_id_3, number_of_periods, 50, [ursula1])\
        .transact({'from': alice1, 'value': 10050})
    testerchain.wait_for_receipt(tx)

    # Mine and revoke policy
    testerchain.time_travel(periods=10)
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula2})
    testerchain.wait_for_receipt(tx)
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula1})
    testerchain.wait_for_receipt(tx)

    testerchain.time_travel(periods=1)
    print("First mining after downtime = " + str(
        miner_agent.contract.functions.mint().estimateGas({'from': ursula1})))
    tx = miner_agent.contract.functions.mint().transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second mining after downtime = " + str(
        miner_agent.contract.functions.mint().estimateGas({'from': ursula2})))
    tx = miner_agent.contract.functions.mint().transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)

    testerchain.time_travel(periods=10)
    print("First revoking policy after downtime = " + str(
        policy_agent.contract.functions.revokePolicy(policy_id_1).estimateGas(
            {'from': alice1})))
    tx = policy_agent.contract.functions.revokePolicy(policy_id_1).transact(
        {'from': alice1})
    testerchain.wait_for_receipt(tx)
    print("Second revoking policy after downtime = " + str(
        policy_agent.contract.functions.revokePolicy(policy_id_2).estimateGas(
            {'from': alice1})))
    tx = policy_agent.contract.functions.revokePolicy(policy_id_2).transact(
        {'from': alice1})
    testerchain.wait_for_receipt(tx)
    print("Second revoking policy after downtime = " + str(
        policy_agent.contract.functions.revokePolicy(policy_id_3).estimateGas(
            {'from': alice1})))
    tx = policy_agent.contract.functions.revokePolicy(policy_id_3).transact(
        {'from': alice1})
    testerchain.wait_for_receipt(tx)

    # Create policy with multiple nodes
    policy_id_1 = os.urandom(int(constants.POLICY_ID_LENGTH))
    policy_id_2 = os.urandom(int(constants.POLICY_ID_LENGTH))
    policy_id_3 = os.urandom(int(constants.POLICY_ID_LENGTH))
    number_of_periods = 100
    print("First creating policy (3 nodes, 100 periods, first reward) = " +
          str(
              policy_agent.contract.functions.createPolicy(
                  policy_id_1, number_of_periods, 50,
                  [ursula1, ursula2, ursula3]).estimateGas({
                      'from': alice1,
                      'value': 30150
                  })))
    tx = policy_agent.contract.functions.createPolicy(policy_id_1, number_of_periods, 50, [ursula1, ursula2, ursula3])\
        .transact({'from': alice1, 'value': 30150})
    testerchain.wait_for_receipt(tx)
    print("Second creating policy (3 nodes, 100 periods, first reward) = " +
          str(
              policy_agent.contract.functions.createPolicy(
                  policy_id_2, number_of_periods, 50,
                  [ursula1, ursula2, ursula3]).estimateGas({
                      'from': alice1,
                      'value': 30150
                  })))
    tx = policy_agent.contract.functions.createPolicy(policy_id_2, number_of_periods, 50, [ursula1, ursula2, ursula3])\
        .transact({'from': alice1, 'value': 30150})
    testerchain.wait_for_receipt(tx)
    print("Third creating policy (2 nodes, 100 periods, first reward) = " +
          str(
              policy_agent.contract.functions.createPolicy(
                  policy_id_3, number_of_periods, 50,
                  [ursula1, ursula2]).estimateGas({
                      'from': alice1,
                      'value': 20100
                  })))
    tx = policy_agent.contract.functions.createPolicy(policy_id_3, number_of_periods, 50, [ursula1, ursula2])\
        .transact({'from': alice1, 'value': 20100})
    testerchain.wait_for_receipt(tx)

    for index in range(5):
        tx = miner_agent.contract.functions.confirmActivity().transact(
            {'from': ursula1})
        testerchain.wait_for_receipt(tx)
        tx = miner_agent.contract.functions.confirmActivity().transact(
            {'from': ursula2})
        testerchain.wait_for_receipt(tx)
        tx = miner_agent.contract.functions.confirmActivity().transact(
            {'from': ursula3})
        testerchain.wait_for_receipt(tx)
        testerchain.time_travel(periods=1)

    tx = miner_agent.contract.functions.mint().transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    tx = miner_agent.contract.functions.mint().transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    tx = miner_agent.contract.functions.mint().transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Check regular deposit
    print("First deposit tokens = " + str(
        miner_agent.contract.functions.deposit(
            int(constants.MIN_ALLOWED_LOCKED), int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula1})))
    tx = miner_agent.contract.functions.deposit(int(constants.MIN_ALLOWED_LOCKED), int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second deposit tokens = " + str(
        miner_agent.contract.functions.deposit(
            int(constants.MIN_ALLOWED_LOCKED), int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula2})))
    tx = miner_agent.contract.functions.deposit(int(constants.MIN_ALLOWED_LOCKED), int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third deposit tokens = " + str(
        miner_agent.contract.functions.deposit(
            int(constants.MIN_ALLOWED_LOCKED), int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula3})))
    tx = miner_agent.contract.functions.deposit(int(constants.MIN_ALLOWED_LOCKED), int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # ApproveAndCall
    testerchain.time_travel(periods=1)

    tx = miner_agent.contract.functions.mint().transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    tx = miner_agent.contract.functions.mint().transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    tx = miner_agent.contract.functions.mint().transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    print("First approveAndCall = " + str(
        token_agent.contract.functions.approveAndCall(
            miner_agent.contract_address,
            int(constants.MIN_ALLOWED_LOCKED) *
            2, web3.toBytes(int(constants.MIN_LOCKED_PERIODS))).estimateGas(
                {'from': ursula1})))
    tx = token_agent.contract.functions.approveAndCall(miner_agent.contract_address,
                                                       int(constants.MIN_ALLOWED_LOCKED) * 2,
                                                       web3.toBytes(int(constants.MIN_LOCKED_PERIODS)))\
        .transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second approveAndCall = " + str(
        token_agent.contract.functions.approveAndCall(
            miner_agent.contract_address,
            int(constants.MIN_ALLOWED_LOCKED) *
            2, web3.toBytes(int(constants.MIN_LOCKED_PERIODS))).estimateGas(
                {'from': ursula2})))
    tx = token_agent.contract.functions.approveAndCall(miner_agent.contract_address,
                                                       int(constants.MIN_ALLOWED_LOCKED) * 2,
                                                       web3.toBytes(int(constants.MIN_LOCKED_PERIODS)))\
        .transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third approveAndCall = " + str(
        token_agent.contract.functions.approveAndCall(
            miner_agent.contract_address,
            int(constants.MIN_ALLOWED_LOCKED) *
            2, web3.toBytes(int(constants.MIN_LOCKED_PERIODS))).estimateGas(
                {'from': ursula3})))
    tx = token_agent.contract.functions.approveAndCall(miner_agent.contract_address,
                                                       int(constants.MIN_ALLOWED_LOCKED) * 2,
                                                       web3.toBytes(int(constants.MIN_LOCKED_PERIODS)))\
        .transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Locking tokens
    testerchain.time_travel(periods=1)

    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula1})
    testerchain.wait_for_receipt(tx)
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula2})
    testerchain.wait_for_receipt(tx)
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula3})
    testerchain.wait_for_receipt(tx)

    print("First locking tokens = " + str(
        miner_agent.contract.functions.lock(int(
            constants.MIN_ALLOWED_LOCKED), int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula1})))
    tx = miner_agent.contract.functions.lock(int(constants.MIN_ALLOWED_LOCKED),
                                             int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second locking tokens = " + str(
        miner_agent.contract.functions.lock(int(
            constants.MIN_ALLOWED_LOCKED), int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula2})))
    tx = miner_agent.contract.functions.lock(int(constants.MIN_ALLOWED_LOCKED),
                                             int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third locking tokens = " + str(
        miner_agent.contract.functions.lock(int(
            constants.MIN_ALLOWED_LOCKED), int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula3})))
    tx = miner_agent.contract.functions.lock(int(constants.MIN_ALLOWED_LOCKED),
                                             int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Divide stake
    print("First divide stake = " + str(
        miner_agent.contract.functions.divideStake(
            1, int(constants.MIN_ALLOWED_LOCKED), 2).estimateGas(
                {'from': ursula1})))
    tx = miner_agent.contract.functions.divideStake(
        1, int(constants.MIN_ALLOWED_LOCKED), 2).transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second divide stake = " + str(
        miner_agent.contract.functions.divideStake(
            3, int(constants.MIN_ALLOWED_LOCKED), 2).estimateGas(
                {'from': ursula1})))
    tx = miner_agent.contract.functions.divideStake(
        3, int(constants.MIN_ALLOWED_LOCKED), 2).transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)

    # Divide almost finished stake
    testerchain.time_travel(periods=1)
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula1})
    testerchain.wait_for_receipt(tx)
    testerchain.time_travel(periods=1)
    print("Divide stake (next period is not confirmed) = " + str(
        miner_agent.contract.functions.divideStake(
            0, int(constants.MIN_ALLOWED_LOCKED), 2).estimateGas(
                {'from': ursula1})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Divide stake (next period is confirmed) = " + str(
        miner_agent.contract.functions.divideStake(
            0, int(constants.MIN_ALLOWED_LOCKED), 2).estimateGas(
                {'from': ursula1})))

    print("All done!")
Esempio n. 26
0
def deploy(click_config, action, poa, provider_uri, geth, enode,
           deployer_address, contract_name, allocation_infile,
           allocation_outfile, registry_infile, registry_outfile, no_compile,
           amount, recipient_address, config_root, sync, force):
    """Manage contract and registry deployment"""

    ETH_NODE = None

    #
    # Validate
    #

    # Ensure config root exists, because we need a default place to put output files.
    config_root = config_root or DEFAULT_CONFIG_ROOT
    if not os.path.exists(config_root):
        os.makedirs(config_root)

    #
    # Connect to Blockchain
    #

    if geth:
        # Spawn geth child process
        ETH_NODE = NuCypherGethDevnetProcess(config_root=config_root)
        ETH_NODE.ensure_account_exists(password=click_config.get_password(
            confirm=True))
        ETH_NODE.start()  # TODO: Graceful shutdown
        provider_uri = ETH_NODE.provider_uri

    # Establish a contract registry from disk if specified
    registry, registry_filepath = None, (registry_outfile or registry_infile)
    if registry_filepath is not None:
        registry = EthereumContractRegistry(
            registry_filepath=registry_filepath)

    # Deployment-tuned blockchain connection
    blockchain = BlockchainDeployerInterface(provider_uri=provider_uri,
                                             poa=poa,
                                             registry=registry,
                                             compiler=SolidityCompiler(),
                                             fetch_registry=False,
                                             sync_now=sync)

    #
    # Deployment Actor
    #

    if not deployer_address:
        for index, address in enumerate(blockchain.client.accounts):
            click.secho(f"{index} --- {address}")
        choices = click.IntRange(0, len(blockchain.client.accounts))
        deployer_address_index = click.prompt("Select deployer address",
                                              default=0,
                                              type=choices)
        deployer_address = blockchain.client.accounts[deployer_address_index]

    # Verify Address
    if not force:
        click.confirm("Selected {} - Continue?".format(deployer_address),
                      abort=True)

    # TODO: Integrate with Deployer Actor (Character)
    blockchain.transacting_power = BlockchainPower(blockchain=blockchain,
                                                   account=deployer_address)
    deployer = Deployer(blockchain=blockchain,
                        deployer_address=deployer_address)

    # Verify ETH Balance
    click.secho(f"\n\nDeployer ETH balance: {deployer.eth_balance}")
    if deployer.eth_balance == 0:
        click.secho("Deployer address has no ETH.", fg='red', bold=True)
        raise click.Abort()

    if not blockchain.client.is_local:
        # (~ dev mode; Assume accounts are already unlocked)
        password = click.prompt("Enter ETH node password", hide_input=True)
        blockchain.client.unlockAccount(deployer_address, password)

    # Add ETH Bootnode or Peer
    if enode:
        if geth:
            blockchain.w3.geth.admin.addPeer(enode)
            click.secho(f"Added ethereum peer {enode}")
        else:
            raise NotImplemented  # TODO: other backends

    #
    # Action switch
    #

    if action == 'upgrade':
        if not contract_name:
            raise click.BadArgumentUsage(
                message="--contract-name is required when using --upgrade")
        existing_secret = click.prompt(
            'Enter existing contract upgrade secret', hide_input=True)
        new_secret = click.prompt('Enter new contract upgrade secret',
                                  hide_input=True,
                                  confirmation_prompt=True)
        deployer.upgrade_contract(contract_name=contract_name,
                                  existing_plaintext_secret=existing_secret,
                                  new_plaintext_secret=new_secret)

    elif action == 'rollback':
        existing_secret = click.prompt(
            'Enter existing contract upgrade secret', hide_input=True)
        new_secret = click.prompt('Enter new contract upgrade secret',
                                  hide_input=True,
                                  confirmation_prompt=True)
        deployer.rollback_contract(contract_name=contract_name,
                                   existing_plaintext_secret=existing_secret,
                                   new_plaintext_secret=new_secret)

    elif action == "contracts":

        registry_filepath = deployer.blockchain.registry.filepath
        if os.path.isfile(registry_filepath):
            click.secho(
                f"\nThere is an existing contract registry at {registry_filepath}.\n"
                f"Did you mean 'nucypher-deploy upgrade'?\n",
                fg='yellow')
            click.confirm(
                "Optionally, destroy existing local registry and continue?",
                abort=True)
            click.confirm(
                f"Confirm deletion of contract registry '{registry_filepath}'?",
                abort=True)
            os.remove(registry_filepath)

        #
        # Deploy Single Contract
        #

        if contract_name:
            # TODO: Handle secret collection for single contract deployment

            try:
                deployer_func = deployer.deployers[contract_name]
            except KeyError:
                message = f"No such contract {contract_name}. Available contracts are {deployer.deployers.keys()}"
                click.secho(message, fg='red', bold=True)
                raise click.Abort()
            else:
                # Deploy single contract
                _txs, _agent = deployer_func()

            # TODO: Painting for single contract deployment
            if ETH_NODE:
                ETH_NODE.stop()
            return

        #
        # Stage Deployment
        #

        # Track tx hashes, and new agents
        __deployment_transactions = dict()
        __deployment_agents = dict()

        secrets = click_config.collect_deployment_secrets()
        click.clear()
        click.secho(NU_BANNER)

        w3 = deployer.blockchain.w3
        click.secho(f"Current Time ........ {maya.now().iso8601()}")
        click.secho(
            f"Web3 Provider ....... {deployer.blockchain.provider_uri}")
        click.secho(
            f"Block ............... {deployer.blockchain.client.block_number}")
        click.secho(
            f"Gas Price ........... {deployer.blockchain.client.gas_price}")

        click.secho(f"Deployer Address .... {deployer.checksum_address}")
        click.secho(f"ETH ................. {deployer.eth_balance}")
        click.secho(
            f"Chain ID ............ {deployer.blockchain.client.chain_id}")
        click.secho(
            f"Chain Name .......... {deployer.blockchain.client.chain_name}")

        # Ask - Last chance to gracefully abort
        if not force:
            click.secho(
                "\nDeployment successfully staged. Take a deep breath. \n",
                fg='green')
            if click.prompt("Type 'DEPLOY' to continue") != 'DEPLOY':
                raise click.Abort()

        # Delay - Last chance to crash and abort
        click.secho(f"Starting deployment in 3 seconds...", fg='red')
        time.sleep(1)
        click.secho(f"2...", fg='yellow')
        time.sleep(1)
        click.secho(f"1...", fg='green')
        time.sleep(1)
        click.secho(f"Deploying...", bold=True)

        #
        # DEPLOY < -------
        #

        txhashes, deployers = deployer.deploy_network_contracts(
            staker_secret=secrets.staker_secret,
            policy_secret=secrets.policy_secret,
            adjudicator_secret=secrets.adjudicator_secret,
            user_escrow_proxy_secret=secrets.escrow_proxy_secret)

        # Success
        __deployment_transactions.update(txhashes)

        #
        # Paint
        #

        total_gas_used = 0  # TODO: may be faulty
        for contract_name, transactions in __deployment_transactions.items():

            # Paint heading
            heading = '\n{} ({})'.format(
                contract_name, deployers[contract_name].contract_address)
            click.secho(heading, bold=True)
            click.echo('*' * (42 + 3 + len(contract_name)))

            for tx_name, txhash in transactions.items():

                # Wait for inclusion in the blockchain
                receipt = deployer.blockchain.w3.eth.waitForTransactionReceipt(
                    txhash)
                click.secho("OK", fg='green', nl=False, bold=True)

                # Accumulate gas
                total_gas_used += int(receipt['gasUsed'])

                # Paint
                click.secho(" | {}".format(tx_name), fg='yellow', nl=False)
                click.secho(" | {}".format(txhash.hex()),
                            fg='yellow',
                            nl=False)
                click.secho(" ({} gas)".format(receipt['cumulativeGasUsed']))
                click.secho("Block #{} | {}\n".format(
                    receipt['blockNumber'], receipt['blockHash'].hex()))

        # Paint outfile paths
        click.secho(
            "Cumulative Gas Consumption: {} gas".format(total_gas_used),
            bold=True,
            fg='blue')
        registry_outfile = deployer.blockchain.registry.filepath
        click.secho('Generated registry {}'.format(registry_outfile),
                    bold=True,
                    fg='blue')

        # Save transaction metadata
        receipts_filepath = deployer.save_deployment_receipts(
            transactions=__deployment_transactions)
        click.secho(f"Saved deployment receipts to {receipts_filepath}",
                    fg='blue',
                    bold=True)

    elif action == "allocations":
        if not allocation_infile:
            allocation_infile = click.prompt("Enter allocation data filepath")
        click.confirm("Continue deploying and allocating?", abort=True)
        deployer.deploy_beneficiaries_from_file(
            allocation_data_filepath=allocation_infile,
            allocation_outfile=allocation_outfile)

    elif action == "transfer":
        token_agent = NucypherTokenAgent(blockchain=blockchain)
        click.confirm(
            f"Transfer {amount} from {token_agent.contract_address} to {recipient_address}?",
            abort=True)
        txhash = token_agent.transfer(
            amount=amount,
            sender_address=token_agent.contract_address,
            target_address=recipient_address)
        click.secho(f"OK | {txhash}")

    elif action == "destroy-registry":
        registry_filepath = deployer.blockchain.registry.filepath
        click.confirm(
            f"Are you absolutely sure you want to destroy the contract registry at {registry_filepath}?",
            abort=True)
        os.remove(registry_filepath)
        click.secho(f"Successfully destroyed {registry_filepath}", fg='red')

    else:
        raise click.BadArgumentUsage(message=f"Unknown action '{action}'")

    if ETH_NODE:
        ETH_NODE.stop()
Esempio n. 27
0
def test_upgradeability(temp_dir_path):
    # Prepare remote source for compilation
    download_github_dir(GITHUB_SOURCE_LINK, temp_dir_path)

    # Prepare the blockchain
    BlockchainDeployerInterface.SOURCES = [
        SourceBundle(base_path=SOLIDITY_SOURCE_ROOT),
        SourceBundle(base_path=Path(temp_dir_path))
    ]

    provider_uri = 'tester://pyevm/2'  # TODO: Testerchain caching Issues
    try:
        blockchain_interface = BlockchainDeployerInterface(
            provider_uri=provider_uri, gas_strategy='free')
        blockchain_interface.connect()
        origin = blockchain_interface.client.accounts[0]
        BlockchainInterfaceFactory.register_interface(
            interface=blockchain_interface)
        blockchain_interface.transacting_power = TransactingPower(
            password=INSECURE_DEVELOPMENT_PASSWORD, account=origin)
        blockchain_interface.transacting_power.activate()

        economics = make_token_economics(blockchain_interface)

        # Check contracts with multiple versions
        raw_contracts = blockchain_interface._raw_contract_cache
        contract_name = AdjudicatorDeployer.contract_name
        test_adjudicator = len(raw_contracts[contract_name]) > 1
        contract_name = StakingEscrowDeployer.contract_name
        test_staking_escrow = len(raw_contracts[contract_name]) > 1
        contract_name = PolicyManagerDeployer.contract_name
        test_policy_manager = len(raw_contracts[contract_name]) > 1

        if not test_adjudicator and not test_staking_escrow and not test_policy_manager:
            return

        # Prepare master version of contracts and upgrade to the latest
        registry = InMemoryContractRegistry()

        token_deployer = NucypherTokenDeployer(registry=registry,
                                               deployer_address=origin,
                                               economics=economics)
        token_deployer.deploy()

        staking_escrow_deployer = StakingEscrowDeployer(
            registry=registry, deployer_address=origin, economics=economics)
        deploy_earliest_contract(blockchain_interface, staking_escrow_deployer)

        policy_manager_deployer = None
        if test_staking_escrow or test_policy_manager:
            policy_manager_deployer = PolicyManagerDeployer(
                registry=registry,
                deployer_address=origin,
                economics=economics)
            deploy_earliest_contract(blockchain_interface,
                                     policy_manager_deployer)

        adjudicator_deployer = None
        if test_staking_escrow or test_adjudicator:
            adjudicator_deployer = AdjudicatorDeployer(registry=registry,
                                                       deployer_address=origin,
                                                       economics=economics)
            deploy_earliest_contract(blockchain_interface,
                                     adjudicator_deployer)

        if test_staking_escrow:
            worklock_deployer = WorklockDeployer(registry=registry,
                                                 deployer_address=origin,
                                                 economics=economics)
            worklock_deployer.deploy()
            # TODO prepare at least one staker before calling upgrade
            staking_escrow_deployer.upgrade(contract_version="latest",
                                            confirmations=0)

        if test_policy_manager:
            policy_manager_deployer.upgrade(contract_version="latest",
                                            confirmations=0)

        if test_adjudicator:
            adjudicator_deployer.upgrade(contract_version="latest",
                                         confirmations=0)

    finally:
        # Unregister interface  # TODO: Move to method?
        with contextlib.suppress(KeyError):
            del BlockchainInterfaceFactory._interfaces[provider_uri]