def test_red_eyes_deployer(web3: Web3) -> None:
    """ A smoke test for deploying RedEyes version contracts """
    deployer = ContractDeployer(
        web3=web3,
        private_key=FAUCET_PRIVATE_KEY,
        gas_limit=GAS_LIMIT,
        gas_price=1,
        wait=10,
        contracts_version="0.4.0",
    )
    deployer.deploy_raiden_contracts(max_num_of_token_networks=None)
def deployed_raiden_info(deployer: ContractDeployer) -> DeployedContracts:
    return deployer.deploy_raiden_contracts(
        max_num_of_token_networks=1,
        reuse_secret_registry_from_deploy_file=None,
        settle_timeout_min=DEPLOY_SETTLE_TIMEOUT_MIN,
        settle_timeout_max=DEPLOY_SETTLE_TIMEOUT_MAX,
    )
def test_alderaan_deployer(web3: Web3) -> None:
    """A smoke test for deploying Alderaan version contracts"""
    deployer = ContractDeployer(
        web3=web3,
        private_key=FAUCET_PRIVATE_KEY,
        gas_limit=GAS_LIMIT,
        gas_price=1,
        wait=10,
        contracts_version=ALDERAAN_VERSION,
    )
    deployer.deploy_raiden_contracts(
        max_num_of_token_networks=2,
        reuse_secret_registry_from_deploy_file=None,
        settle_timeout_min=DEPLOY_SETTLE_TIMEOUT_MIN,
        settle_timeout_max=DEPLOY_SETTLE_TIMEOUT_MAX,
    )
def test_deploy_script_raiden_0_37_0(
    deployer_0_37_0: ContractDeployer, ) -> None:
    """Checks that `verify_deployment_data` works fine with older contracts."""
    data = deployer_0_37_0.deploy_raiden_contracts(
        max_num_of_token_networks=1,
        reuse_secret_registry_from_deploy_file=None,
        settle_timeout_min=DEPLOY_SETTLE_TIMEOUT_MIN,
        settle_timeout_max=DEPLOY_SETTLE_TIMEOUT_MAX,
    )

    deployer_0_37_0.verify_deployment_data(deployment_data=data)
def test_deploy_raiden_reuse_secret_registry(
        deployer: ContractDeployer,
        deployed_raiden_info: DeployedContracts) -> None:
    """Run deploy_raiden_contracts with a previous SecretRegistry deployment data"""
    with NamedTemporaryFile() as previous_deployment_file:
        previous_deployment_file.write(
            bytearray(json.dumps(deployed_raiden_info), "ascii"))
        previous_deployment_file.flush()
        new_deployment = deployer.deploy_raiden_contracts(
            1,
            reuse_secret_registry_from_deploy_file=Path(
                previous_deployment_file.name),
            settle_timeout_min=DEPLOY_SETTLE_TIMEOUT_MIN,
            settle_timeout_max=DEPLOY_SETTLE_TIMEOUT_MAX,
        )
        assert (new_deployment["contracts"][CONTRACT_SECRET_REGISTRY] ==
                deployed_raiden_info["contracts"][CONTRACT_SECRET_REGISTRY])
        assert (
            new_deployment["contracts"][CONTRACT_TOKEN_NETWORK_REGISTRY] !=
            deployed_raiden_info["contracts"][CONTRACT_TOKEN_NETWORK_REGISTRY])
def deployed_raiden_info_0_4_0(
        deployer_0_4_0: ContractDeployer) -> DeployedContracts:
    return deployer_0_4_0.deploy_raiden_contracts(
        max_num_of_token_networks=None)
def deployed_raiden_info(deployer: ContractDeployer) -> DeployedContracts:
    return deployer.deploy_raiden_contracts(max_num_of_token_networks=1)
def test_deploy_script_raiden(web3: Web3, deployer: ContractDeployer,
                              deployed_raiden_info: DeployedContracts) -> None:
    """ Run raiden contracts deployment function and tamper with deployed_contracts_info

    This checks if deploy_raiden_contracts() works correctly in the happy case,
    to make sure no code dependencies have been changed, affecting the deployment script.
    This does not check however that the cli command works correctly.
    This also tampers with deployed_contracts_info to make sure an error is raised in
    verify_deployed_contracts()
    """
    deployed_contracts_info = deployed_raiden_info

    deployer.verify_deployment_data(deployment_data=deployed_contracts_info)

    deployed_contracts_info_fail = deepcopy(deployed_contracts_info)
    deployed_contracts_info_fail["contracts_version"] = "0.0.0"
    with pytest.raises(RuntimeError):
        deployer.verify_deployment_data(
            deployment_data=deployed_contracts_info_fail)

    deployed_contracts_info_fail = deepcopy(deployed_contracts_info)
    deployed_contracts_info_fail["chain_id"] = 0
    with pytest.raises(RuntimeError):
        deployer.verify_deployment_data(
            deployment_data=deployed_contracts_info_fail)

    deployed_contracts_info_fail = deepcopy(deployed_contracts_info)
    deployed_contracts_info_fail["contracts"][CONTRACT_SECRET_REGISTRY][
        "address"] = EMPTY_ADDRESS
    with pytest.raises(RuntimeError):
        deployer.verify_deployment_data(deployed_contracts_info_fail)

    deployed_contracts_info_fail = deepcopy(deployed_contracts_info)
    deployed_contracts_info_fail["contracts"][CONTRACT_SECRET_REGISTRY][
        "address"] = EMPTY_ADDRESS
    with pytest.raises(RuntimeError):
        deployer.verify_deployment_data(deployed_contracts_info_fail)

    deployed_contracts_info_fail = deepcopy(deployed_contracts_info)
    deployed_contracts_info_fail["contracts"][CONTRACT_TOKEN_NETWORK_REGISTRY][
        "address"] = EMPTY_ADDRESS
    with pytest.raises(RuntimeError):
        deployer.verify_deployment_data(deployed_contracts_info_fail)

    deployed_contracts_info_fail = deepcopy(deployed_contracts_info)
    deployed_contracts_info_fail["contracts"][CONTRACT_SECRET_REGISTRY][
        "block_number"] = 0
    with pytest.raises(RuntimeError):
        deployer.verify_deployment_data(deployed_contracts_info_fail)

    deployed_contracts_info_fail = deepcopy(deployed_contracts_info)
    deployed_contracts_info_fail["contracts"][CONTRACT_SECRET_REGISTRY][
        "block_number"] = 0
    with pytest.raises(RuntimeError):
        deployer.verify_deployment_data(deployed_contracts_info_fail)

    deployed_contracts_info_fail = deepcopy(deployed_contracts_info)
    deployed_contracts_info_fail["contracts"][CONTRACT_TOKEN_NETWORK_REGISTRY][
        "block_number"] = 0
    with pytest.raises(RuntimeError):
        deployer.verify_deployment_data(deployed_contracts_info_fail)

    deployed_contracts_info_fail = deepcopy(deployed_contracts_info)
    deployed_contracts_info_fail["contracts"][CONTRACT_TOKEN_NETWORK_REGISTRY][
        "gas_cost"] = 0
    with pytest.raises(RuntimeError):
        deployer.verify_deployment_data(deployed_contracts_info_fail)

    deployed_contracts_info_fail = deepcopy(deployed_contracts_info)
    deployed_contracts_info_fail["contracts"][CONTRACT_TOKEN_NETWORK_REGISTRY][
        "address"] = EMPTY_ADDRESS
    with pytest.raises(RuntimeError):
        deployer.verify_deployment_data(deployed_contracts_info_fail)

    deployed_contracts_info_fail = deepcopy(deployed_contracts_info)
    deployed_contracts_info_fail["contracts_version"] = "0.4.0"
    with pytest.raises(RuntimeError):
        deployer.verify_deployment_data(deployed_contracts_info_fail)

    # check that it fails if sender has no eth
    deployer = ContractDeployer(web3=web3,
                                private_key=get_random_privkey(),
                                gas_limit=GAS_LIMIT,
                                gas_price=1,
                                wait=10)
    with pytest.raises(ValidationError):
        deployer.deploy_raiden_contracts(1)
def main(keystore_file: str, contract_version: str, password: str, output: str, rpc_url: str):
    web3 = Web3(HTTPProvider(rpc_url, request_kwargs={'timeout': 60}))
    web3.middleware_onion.inject(geth_poa_middleware, layer=0)

    with open(keystore_file, 'r') as keystore:
        encrypted_key = keystore.read()
        private_key = web3.eth.account.decrypt(encrypted_key, password)
        account = Account.privateKeyToAccount(private_key)

    if private_key is None:
        print('No private key found')
        exit(1)

    owner = account.address

    if web3.eth.getBalance(owner) == 0:
        print('Account with insuficient funds.')
        exit(1)

    print(f'Deploying contracts {contract_version} on behalf of {owner}')

    deployer = ContractDeployer(
        web3=web3,
        private_key=private_key,
        gas_limit=GAS_LIMIT,
        gas_price=GAS_PRICE,
        wait=120,
        contracts_version=contract_version,
    )

    print('Deploying Raiden contracts')
    try:
        deployed_contracts_info = deployer.deploy_raiden_contracts(
            max_num_of_token_networks=UNLIMITED,
            settle_timeout_min=SETTLE_TIMEOUT_MIN,
            settle_timeout_max=SETTLE_TIMEOUT_MAX,
            reuse_secret_registry_from_deploy_file=None
        )
    except Exception as err:
        print(f'Raiden Contract Deployment failed: {err}')
        exit(1)

    deployed_contracts = {
        contract_name: info['address']
        for contract_name, info in deployed_contracts_info['contracts'].items()
    }

    try:
        deployer.store_and_verify_deployment_info_raiden(
            deployed_contracts_info=deployed_contracts_info
        )
    except Exception as err:
        print(f'Contract verification failed: {err}')
        exit(1)

    token_network_registry_address = deployed_contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]
    print(f'Registry contract deployed @ {token_network_registry_address}')

    print('Deploying TTT contract')
    try:
        ttt_abi, ttt_token_address = deploy_token(deployer)
    except Exception as err:
        print(f'TTT deployment failed: {err}')
        exit(1)

    print(f'Deployed TTT contract @ {ttt_token_address}')

    print('Registering TTT')
    try:
        deployer.register_token_network(
            token_registry_abi=ttt_abi,
            token_registry_address=token_network_registry_address,
            token_address=ttt_token_address,
            channel_participant_deposit_limit=UNLIMITED,
            token_network_deposit_limit=UNLIMITED,
        )
    except Exception as err:
        print(f'Registration of TTT failed: {err}')
        exit(1)

    print('Deploying SVT contract')
    try:
        svt_abi, svt_token_address = deploy_token(deployer, 'ServiceToken', 'SVT')
    except Exception as err:
        print(f'SVT Deployment failed: {err}')
        exit(1)

    print(f'Deployed SVT contract @ {svt_token_address}')

    print('Deploying Raiden service contracts')
    try:
        deployed_service_contracts_info = deployer.deploy_service_contracts(
            token_address=svt_token_address,
            user_deposit_whole_balance_limit=UNLIMITED,
            service_registry_controller=owner,
            initial_service_deposit_price=INITIAL_SERVICE_DEPOSIT_PRICE,
            service_deposit_bump_numerator=SERVICE_DEPOSIT_BUMP_NUMERATOR,
            service_deposit_bump_denominator=SERVICE_DEPOSIT_BUMP_DENOMINATOR,
            decay_constant=SERVICE_DEPOSIT_DECAY_CONSTANT,
            min_price=SERVICE_DEPOSIT_MIN_PRICE,
            registration_duration=SERVICE_REGISTRATION_DURATION,
            token_network_registry_address=token_network_registry_address
        )
    except Exception as err:
        print(f'Service contract deployment failed: {err}')
        exit(1)

    try:
        deployer.store_and_verify_deployment_info_services(
            deployed_contracts_info=deployed_service_contracts_info,
            token_address=svt_token_address,
            user_deposit_whole_balance_limit=UNLIMITED,
            token_network_registry_address=token_network_registry_address,
        )
    except Exception as err:
        print(f'Service contract verification failed: {err}')
        exit(1)

    if os.path.exists("user_deposit_address"):
        os.remove("user_deposit_address")

    print(f'Storing deployment info to {output}')

    try:
        with open(output, 'w+') as address_file:
            contracts_info = deployed_service_contracts_info['contracts']
            user_deposit_address = contracts_info[CONTRACT_USER_DEPOSIT]['address']
            one_to_n_address = contracts_info[CONTRACT_ONE_TO_N]['address']
            address_file.write(f'#!/bin/sh\n')
            address_file.write(f'export TTT_TOKEN_ADDRESS={ttt_token_address}\n')
            address_file.write(f'export SVT_TOKEN_ADDRESS={svt_token_address}\n')
            address_file.write(f'export USER_DEPOSIT_ADDRESS={user_deposit_address}\n')
            address_file.write(f'export TOKEN_NETWORK_REGISTRY_ADDRESS={token_network_registry_address}\n')
            address_file.write(f'export TOKEN_NETWORK_REGISTRY_ADDRESS={token_network_registry_address}\n')
            address_file.write(f'export ONE_TO_N_ADDRESS={one_to_n_address}\n')
            address_file.close()
    except Exception as err:
        print(f'Writing environment variables failed: {err}')

    print('done')