Example #1
0
def test_eth_to_ceth_and_back_to_eth(
    basic_transfer_request: EthereumToSifchainTransferRequest,
    source_ethereum_address: str,
    rowan_source_integrationtest_env_credentials: SifchaincliCredentials,
    rowan_source_integrationtest_env_transfer_request:
    EthereumToSifchainTransferRequest,
    ethereum_network,
    smart_contracts_dir,
    rowan_amount,
    ceth_amount,
    bridgetoken_address,
):
    # logging.info("shark")
    # x = 4.9908339925e+18
    # s = "{:d}".format(int(x))
    # logging.info(f"xiss: {s}")
    # logging.info(f"xiss: {x}")
    # assert False
    basic_transfer_request.ethereum_address = source_ethereum_address
    basic_transfer_request.check_wait_blocks = True
    logging.info(f"rq: {basic_transfer_request}")
    request, credentials = generate_test_account(
        basic_transfer_request,
        rowan_source_integrationtest_env_transfer_request,
        rowan_source_integrationtest_env_credentials,
        target_ceth_balance=ceth_amount,
        target_rowan_balance=rowan_amount)
    # send some test account ceth back to a new ethereum address
    request.ethereum_address, _ = test_utilities.create_ethereum_address(
        smart_contracts_dir, ethereum_network)
    logging.info(f"get balance of test account")
    test_utilities.get_sifchain_addr_balance(
        request.sifchain_address,
        sifnodecli_node=request.sifnodecli_node,
        denom="ceth")
    logging.info(
        "send erowan back to ethereum chain, saving 100k for ceth transfer fees"
    )
    request.sifchain_symbol = "rowan"
    request.ethereum_symbol = bridgetoken_address
    request.amount = rowan_amount - 200000
    burn_lock_functions.transfer_sifchain_to_ethereum(request, credentials)
    test_utilities.get_eth_balance(request)

    logging.info("send eth back to ethereum chain")
    logging.info("get ceth balance to decide how much to return")
    request.sifchain_symbol = "ceth"
    request.ethereum_symbol = "eth"
    ceth_balance = test_utilities.get_sifchain_addr_balance(
        request.sifchain_address,
        sifnodecli_node=request.sifnodecli_node,
        denom="ceth")
    request.amount = ceth_balance - request.ceth_amount
    burn_lock_functions.transfer_sifchain_to_ethereum(request, credentials)
    logging.info("get final eth balance")
    test_utilities.get_eth_balance(request)
    test_utilities.get_sifchain_addr_balance(
        request.sifchain_address,
        sifnodecli_node=request.sifnodecli_node,
        denom="ceth")
Example #2
0
def test_eth_to_ceth(
    basic_transfer_request: EthereumToSifchainTransferRequest,
    source_ethereum_address: str,
):
    basic_transfer_request.ethereum_address = source_ethereum_address
    logging.info(f"transfer_request: {basic_transfer_request}")
    return generate_minimal_test_account(
        base_transfer_request=basic_transfer_request, target_ceth_balance=100)
Example #3
0
def test_transfer_eth_to_ceth_over_limit(
        basic_transfer_request: EthereumToSifchainTransferRequest,
        source_ethereum_address: str,
        rowan_source_integrationtest_env_credentials: SifchaincliCredentials,
        rowan_source_integrationtest_env_transfer_request: EthereumToSifchainTransferRequest,
):
    basic_transfer_request.ethereum_symbol = "eth"
    basic_transfer_request.ethereum_address = source_ethereum_address
    basic_transfer_request.amount = 35 * 10 ** 18
    with pytest.raises(Exception):
        basic_transfer_request.ethereum_address = source_ethereum_address
        generate_test_account(
            basic_transfer_request,
            rowan_source_integrationtest_env_transfer_request,
            rowan_source_integrationtest_env_credentials,
            target_ceth_balance=50 * 10 ** 19,
        )
Example #4
0
def test_ethereum_transactions_with_offline_relayer(
    basic_transfer_request: EthereumToSifchainTransferRequest,
    smart_contracts_dir,
    source_ethereum_address,
    bridgebank_address,
    integration_dir,
):
    logging.debug(
        "need one transaction to make sure ebrelayer writes out relaydb")
    basic_transfer_request.ethereum_address = source_ethereum_address
    generate_minimal_test_account(base_transfer_request=basic_transfer_request,
                                  target_ceth_balance=100)

    logging.info("shut down ebrelayer")
    time.sleep(10)
    test_utilities.get_shell_output(f"pkill -9 ebrelayer || true")

    logging.info("prepare transactions to be sent while ebrelayer is offline")
    amount = 9000
    new_addresses = list(map(lambda x: create_new_sifaddr(), range(3)))
    logging.debug(f"new_addresses: {new_addresses}")
    request: EthereumToSifchainTransferRequest = copy.deepcopy(
        basic_transfer_request)
    requests = list(
        map(
            lambda addr: {
                "amount": amount,
                "symbol": test_utilities.NULL_ADDRESS,
                "sifchain_address": addr
            }, new_addresses))
    json_requests = json.dumps(requests)

    logging.info("send ethereum transactions while ebrelayer is offline")
    yarn_result = test_utilities.run_yarn_command(" ".join([
        f"yarn --cwd {smart_contracts_dir}", "integrationtest:sendBulkLockTx",
        f"--amount {amount}", f"--symbol eth",
        f"--json_path {request.solidity_json_path}",
        f"--sifchain_address {new_addresses[0]}",
        f"--transactions \'{json_requests}\'",
        f"--ethereum_address {source_ethereum_address}",
        f"--bridgebank_address {bridgebank_address}"
    ]))
    logging.debug(f"bulk result: {yarn_result}")
    logging.info(
        "restart ebrelayer with outstanding locks on the ethereum side")
    test_utilities.get_shell_output(
        f"{integration_dir}/sifchain_start_ebrelayer.sh")
    time.sleep(5)
    for _ in new_addresses:
        # ebrelayer only reads blocks if there are new blocks generated
        test_utilities.advance_n_ethereum_blocks(test_utilities.n_wait_blocks,
                                                 request.smart_contracts_dir)
    for a in new_addresses:
        test_utilities.wait_for_sif_account(
            a, basic_transfer_request.sifnoded_node, 90)
        test_utilities.wait_for_sifchain_addr_balance(
            a, "ceth", amount, basic_transfer_request.sifnoded_node, 90)
Example #5
0
def test_eth_to_ceth_and_back_to_eth(
        basic_transfer_request: EthereumToSifchainTransferRequest,
        source_ethereum_address: str,
        rowan_source_integrationtest_env_credentials: SifchaincliCredentials,
        rowan_source_integrationtest_env_transfer_request:
    EthereumToSifchainTransferRequest, ethereum_network, smart_contracts_dir):
    basic_transfer_request.ethereum_address = source_ethereum_address
    basic_transfer_request.check_wait_blocks = True
    request, credentials = generate_test_account(
        basic_transfer_request,
        rowan_source_integrationtest_env_transfer_request,
        rowan_source_integrationtest_env_credentials,
        target_ceth_balance=10**17,
        target_rowan_balance=10**18)
    # send some test account ceth back to a new ethereum address
    request.ethereum_address, _ = test_utilities.create_ethereum_address(
        smart_contracts_dir, ethereum_network)
    request.amount = int(request.amount / 2)
    burn_lock_functions.transfer_sifchain_to_ethereum(request, credentials)
Example #6
0
def test_sifchain_transactions_with_offline_relayer(
    basic_transfer_request: EthereumToSifchainTransferRequest,
    rowan_source_integrationtest_env_credentials: test_utilities.
    SifchaincliCredentials,
    rowan_source_integrationtest_env_transfer_request:
    EthereumToSifchainTransferRequest,
    rowan_source,
    smart_contracts_dir,
    source_ethereum_address,
    integration_dir,
):
    basic_transfer_request.ethereum_address = source_ethereum_address
    request, credentials = generate_test_account(
        basic_transfer_request,
        rowan_source_integrationtest_env_transfer_request,
        rowan_source_integrationtest_env_credentials,
        target_ceth_balance=10**19,
        target_rowan_balance=10**19,
    )
    logging.info("shut down ebrelayer")
    time.sleep(10)
    test_utilities.get_shell_output(f"pkill -9 ebrelayer || true")

    logging.info("prepare transactions to be sent while ebrelayer is offline")
    amount = 9000

    new_eth_addrs = test_utilities.create_ethereum_addresses(
        smart_contracts_dir, basic_transfer_request.ethereum_network, 2)

    request.amount = amount
    request.sifchain_symbol = "ceth"
    request.ethereum_symbol = "eth"

    logging.info("send transactions while ebrelayer is offline")

    for a in new_eth_addrs:
        request.ethereum_address = a["address"]
        sifchain_balance = test_utilities.get_sifchain_addr_balance(
            request.sifchain_address, request.sifnoded_node, "ceth")
        logging.info(
            f"sifchain balance is {sifchain_balance}, request is {request}")
        test_utilities.send_from_sifchain_to_ethereum(transfer_request=request,
                                                      credentials=credentials)
        time.sleep(5)

    logging.info("restart ebrelayer")
    test_utilities.get_shell_output(
        f"{integration_dir}/sifchain_start_ebrelayer.sh")
    time.sleep(15)
    test_utilities.advance_n_ethereum_blocks(test_utilities.n_wait_blocks * 2,
                                             request.smart_contracts_dir)
    for a in new_eth_addrs:
        request.ethereum_address = a["address"]
        test_utilities.wait_for_eth_balance(request, amount, 600)
Example #7
0
def test_eth_to_ceth_and_back_to_eth(
    basic_transfer_request: EthereumToSifchainTransferRequest,
    source_ethereum_address: str,
    rowan_source_integrationtest_env_credentials: SifchaincliCredentials,
    rowan_source_integrationtest_env_transfer_request:
    EthereumToSifchainTransferRequest,
    ethereum_network,
    smart_contracts_dir,
    bridgetoken_address,
    sifchain_fees_int,
):
    basic_transfer_request.ethereum_address = source_ethereum_address
    basic_transfer_request.check_wait_blocks = True
    small_amount = 100

    logging.info(
        "the test account needs enough rowan and ceth for one burn and one lock, make sure it has that"
    )
    request, credentials = generate_test_account(
        basic_transfer_request,
        rowan_source_integrationtest_env_transfer_request,
        rowan_source_integrationtest_env_credentials,
        target_ceth_balance=test_utilities.burn_gas_cost +
        test_utilities.lock_gas_cost + small_amount,
        target_rowan_balance=sifchain_fees_int * 2 + small_amount)
    # send some test account ceth back to a new ethereum address
    request.ethereum_address, _ = test_utilities.create_ethereum_address(
        smart_contracts_dir, ethereum_network)
    request.sifchain_symbol = "rowan"
    request.ethereum_symbol = bridgetoken_address
    request.amount = small_amount
    burn_lock_functions.transfer_sifchain_to_ethereum(request, credentials)
    test_utilities.get_eth_balance(request)

    logging.info("send eth back to ethereum chain")
    request.sifchain_symbol = "ceth"
    request.ethereum_symbol = "eth"
    request.amount = small_amount
    burn_lock_functions.transfer_sifchain_to_ethereum(request, credentials)
Example #8
0
def process_args(cmdline: List[str]) -> RequestAndCredentials:
    arg_parser = transfer_argument_parser()
    args = add_credentials_arguments(arg_parser).parse_args(args=cmdline)
    configure_logging(args)

    logging.debug(f"command line arguments: {sys.argv} {args}")

    transfer_request = EthereumToSifchainTransferRequest.from_args(args)

    credentials = SifchaincliCredentials(
        keyring_passphrase=os.environ.get(args.keyring_passphrase_env_var[0]),
        from_key=args.from_key[0],
        keyring_backend=args.keyring_backend[0],
        sifnodecli_homedir=args.sifnodecli_homedir[0],
    )

    return RequestAndCredentials(transfer_request, credentials, args)
Example #9
0
def test_ebrelayer_restart(
    basic_transfer_request: EthereumToSifchainTransferRequest,
    source_ethereum_address: str,
    integration_dir,
):
    basic_transfer_request.ethereum_address = source_ethereum_address
    request, credentials = generate_minimal_test_account(
        base_transfer_request=basic_transfer_request,
        target_ceth_balance=10**15)
    balance = test_utilities.get_sifchain_addr_balance(
        request.sifchain_address, request.sifnodecli_node, "ceth")
    logging.info(
        "restart ebrelayer normally, leaving the last block db in place")
    test_utilities.get_shell_output(
        f"{integration_dir}/sifchain_start_ebrelayer.sh")
    test_utilities.advance_n_ethereum_blocks(test_utilities.n_wait_blocks,
                                             request.smart_contracts_dir)
    time.sleep(5)
    assert balance == test_utilities.get_sifchain_addr_balance(
        request.sifchain_address, request.sifnodecli_node, "ceth")
def test_bulk_transfers_from_sifchain(
        basic_transfer_request: EthereumToSifchainTransferRequest,
        rowan_source_integrationtest_env_credentials: SifchaincliCredentials,
        rowan_source_integrationtest_env_transfer_request: EthereumToSifchainTransferRequest,
        smart_contracts_dir,
        source_ethereum_address,
        rowan_source,
        rowan_source_key,
        bridgebank_address,
        bridgetoken_address,
        ethereum_network,
):
    basic_transfer_request.ethereum_address = source_ethereum_address
    logging.info(f"transfer_request: {basic_transfer_request}")
    # account_with_ceth, credentials_for_account_with_ceth = generate_test_account(
    #     base_transfer_request=basic_transfer_request,
    #     rowan_source_integrationtest_env_transfer_request=rowan_source_integrationtest_env_transfer_request,
    #     rowan_source_integrationtest_env_credentials=rowan_source_integrationtest_env_credentials,
    #     target_ceth_balance=5 * 10 ** 18,
    #     target_rowan_balance=50 * 10 ** 18
    # )
    n_transfers = int(test_utilities.get_optional_env_var("NTRANSFERS", 2))
    amount = "{:d}".format(5 * test_utilities.highest_gas_cost)
    new_addresses_and_keys = list(map(lambda x: create_new_sifaddr_and_key(), range(n_transfers)))
    logging.info(f"aandk: {new_addresses_and_keys}")
    new_addresses = list(map(lambda a: a[0], new_addresses_and_keys))
    logging.debug(f"new_addresses: {new_addresses}")
    new_eth_addrs = test_utilities.create_ethereum_addresses(smart_contracts_dir,
                                                             basic_transfer_request.ethereum_network,
                                                             len(new_addresses))
    logging.info(f"new eth addrs: {new_eth_addrs}")
    request: EthereumToSifchainTransferRequest = copy.deepcopy(basic_transfer_request)
    requests = list(map(lambda addr: {
        "amount": amount,
        "symbol": test_utilities.NULL_ADDRESS,
        "sifchain_address": addr
    }, new_addresses))
    request.amount = 5 * test_utilities.highest_gas_cost
    credentials_for_account_with_ceth = SifchaincliCredentials(from_key=rowan_source_key)
    for r in requests:
        request.ethereum_address = source_ethereum_address
        request.sifchain_address = rowan_source
        request.sifchain_destination_address = r["sifchain_address"]
        request.sifchain_symbol = "ceth"
        request.ethereum_symbol = "eth"
        logging.warning(f"requestis: {request}")
        test_utilities.send_from_sifchain_to_sifchain(request, credentials_for_account_with_ceth)
        time.sleep(3)
        request.sifchain_symbol = "rowan"
        request.ethereum_symbol = bridgetoken_address
        test_utilities.send_from_sifchain_to_sifchain(request, credentials_for_account_with_ceth)
        time.sleep(3)

    for a in new_addresses:
        test_utilities.wait_for_sif_account(a, basic_transfer_request.sifnodecli_node, 90)
        test_utilities.wait_for_sifchain_addr_balance(a, "ceth", amount, basic_transfer_request.sifnodecli_node, 180)
        test_utilities.wait_for_sifchain_addr_balance(a, "rowan", amount, basic_transfer_request.sifnodecli_node, 180)
    text_file = open("pfile.cmds", "w")
    simple_credentials = SifchaincliCredentials(
        keyring_passphrase=None,
        keyring_backend="test",
        from_key=None,
        sifnodecli_homedir=None
    )
    logging.info(f"all accounts are on sifchain and have the correct balance")
    for sifaddr, ethaddr in zip(new_addresses_and_keys, new_eth_addrs):
        r = copy.deepcopy(basic_transfer_request)
        r.sifchain_address = sifaddr[0]
        r.ethereum_address = ethaddr["address"]
        r.amount = 100
        simple_credentials.from_key = sifaddr[1]
        c = test_utilities.send_from_sifchain_to_ethereum_cmd(r, simple_credentials)
        text_file.write(f"{c}\n")
    text_file.close()
    test_utilities.get_shell_output("cat pfile.cmds | parallel --trim lr -v {}")
    test_utilities.advance_n_ethereum_blocks(test_utilities.n_wait_blocks, smart_contracts_dir)
    # test_utilities.get_shell_output("bash -x pfile.cmds")
    for sifaddr, ethaddr in zip(new_addresses_and_keys, new_eth_addrs):
        r = copy.deepcopy(basic_transfer_request)
        r.ethereum_address = ethaddr["address"]
        r.amount = 100
        test_utilities.wait_for_eth_balance(r, 100, 6000 * (n_transfers + 1))
Example #11
0
def test_rollback_chain(source_ethereum_address):
    new_account_key = get_shell_output("uuidgen")
    credentials = sifchain_cli_credentials_for_test(new_account_key)
    new_account = burn_lock_functions.create_new_sifaddr(
        credentials=credentials, keyname=new_account_key)
    credentials.from_key = new_account["name"]

    # Any amount will work
    amount = 11000

    request = EthereumToSifchainTransferRequest(
        sifchain_address=new_account["address"],
        smart_contracts_dir=get_required_env_var("SMART_CONTRACTS_DIR"),
        ethereum_address=source_ethereum_address,
        ethereum_private_key_env_var="ETHEREUM_PRIVATE_KEY",
        bridgebank_address=get_required_env_var("BRIDGE_BANK_ADDRESS"),
        ethereum_network=(os.environ.get("ETHEREUM_NETWORK") or ""),
        amount=amount)

    logging.info(f"create account with a balance of {request.amount}")
    burn_lock_functions.transfer_ethereum_to_sifchain(request, 50)

    new_addr = new_account["address"]

    snapshot = get_shell_output(
        f"{test_integration_dir}/snapshot_ganache_chain.sh")
    logging.info(f"created new account, took ganache snapshot {snapshot}")
    initial_user_balance = get_sifchain_addr_balance(new_addr, "",
                                                     request.sifchain_symbol)
    logging.info(f"initial_user_balance {initial_user_balance}")

    transfer_1 = send_from_ethereum_to_sifchain(transfer_request=request)
    logging.info(f"transfer started but it will never complete (by design)")

    logging.info("advance less than wait blocks")
    advance_n_ethereum_blocks(n_wait_blocks / 2, request.smart_contracts_dir)

    # the transaction should not have happened on the sifchain side yet
    # since we haven't waited for the right number of blocks.
    # roll back ganache to the snapshot and try another transfer that
    # should succeed.

    logging.info(
        f"apply snapshot {snapshot} - this eliminates transfer_1 (block {transfer_1})"
    )
    get_shell_output(
        f"{test_integration_dir}/apply_ganache_snapshot.sh {snapshot} 2>&1")

    logging.info("advance past block wait")
    advance_n_ethereum_blocks(n_wait_blocks * 2, request.smart_contracts_dir)
    time.sleep(5)

    second_user_balance = get_sifchain_addr_balance(new_addr, "",
                                                    request.sifchain_symbol)
    if second_user_balance == initial_user_balance:
        logging.info(
            f"got expected outcome of no balance change @ {initial_user_balance}"
        )
    else:
        raise Exception(
            f"balance should be the same after applying snapshot and rolling forward n_wait_blocks * 2.  initial_user_balance: {initial_user_balance} second_user_balance: {second_user_balance}"
        )

    request.amount = 10000

    logging.info(f"sending more eth: {request.amount} to {new_addr}")
    burn_lock_functions.transfer_ethereum_to_sifchain(request)

    # We want to know that ebrelayer will never do a second transaction.
    # We can't know that, so just delay a reasonable amount of time.
    logging.info("delay to give ebrelayer time to make a mistake")
    time.sleep(10)

    balance_after_sleep = get_sifchain_addr_balance(new_addr, "",
                                                    request.sifchain_symbol)
    logging.info(
        f"get_sifchain_addr_balance after sleep is {balance_after_sleep} for {new_addr}"
    )

    expected_balance = initial_user_balance + request.amount
    logging.info(f"look for a balance of {expected_balance}")
    wait_for_sifchain_addr_balance(new_addr, request.sifchain_symbol,
                                   expected_balance, "")
Example #12
0
def test_bulk_transfers_from_sifchain(
        basic_transfer_request: EthereumToSifchainTransferRequest,
        rowan_source_integrationtest_env_credentials: SifchaincliCredentials,
        rowan_source_integrationtest_env_transfer_request: EthereumToSifchainTransferRequest,
        smart_contracts_dir,
        source_ethereum_address,
        rowan_source,
        rowan_source_key,
        bridgebank_address,
        bridgetoken_address,
        ethereum_network,
        sifchain_fees_int,
):
    test_transfer_amount = 100  # just a tiny number of wei to move to confirm things are working
    tokens = test_utilities.get_required_env_var("TOKENS", "ceth,rowan").split(",")
    logging.info(f"tokens to be transferred are: {tokens}")
    logging.info("create new ethereum and sifchain addresses")
    basic_transfer_request.ethereum_address = source_ethereum_address
    n_transfers = int(test_utilities.get_optional_env_var("NTRANSFERS", 2))
    n_transactions = n_transfers * len(tokens)
    new_addresses_and_keys = list(map(lambda x: create_new_sifaddr_and_key(), range(n_transactions)))
    logging.debug(f"new_addresses_and_keys: {new_addresses_and_keys}")
    credentials_for_account_with_ceth = SifchaincliCredentials(from_key=rowan_source_key)
    request: EthereumToSifchainTransferRequest = copy.deepcopy(basic_transfer_request)
    ceth_amount = n_transactions * (test_utilities.highest_gas_cost + 100)
    request.amount = ceth_amount
    request.ethereum_address = source_ethereum_address
    request.sifchain_address = rowan_source
    addresses_to_populate = copy.deepcopy(new_addresses_and_keys)
    test_transfers = []
    for a in range(n_transfers):
        for t in tokens:
            request.sifchain_destination_address, from_key = addresses_to_populate.pop()

            # send ceth to pay for the burn
            request.amount = test_utilities.burn_gas_cost
            request.sifchain_symbol = "ceth"
            burn_lock_functions.transfer_sifchain_to_sifchain(request, credentials_for_account_with_ceth)

            # send rowan to pay the fee
            request.amount = sifchain_fees_int
            request.sifchain_symbol = "rowan"
            burn_lock_functions.transfer_sifchain_to_sifchain(request, credentials_for_account_with_ceth)

            # send the token itself
            request.amount = test_transfer_amount
            request.sifchain_symbol = t
            burn_lock_functions.transfer_sifchain_to_sifchain(request, credentials_for_account_with_ceth)
            transfer = (request.sifchain_destination_address, from_key, request.sifchain_symbol, request.amount)

            test_utilities.get_sifchain_addr_balance(request.sifchain_destination_address, request.sifnodecli_node, t)

            test_transfers.append(transfer)

    logging.debug(f"test_transfers is {test_transfers}")

    text_file = open("pfile.cmds", "w")
    simple_credentials = SifchaincliCredentials(
        keyring_passphrase=None,
        keyring_backend="test",
        from_key=None,
        sifnodecli_homedir=None
    )

    logging.info(f"all accounts are on sifchain and have the correct balance")

    new_eth_addrs = test_utilities.create_ethereum_addresses(
        smart_contracts_dir,
        basic_transfer_request.ethereum_network,
        n_transactions
    )
    logging.debug(f"new eth addrs: {new_eth_addrs}")

    ethereum_transfers = []
    for sifaddr, from_key, sifsymbol, amount in test_transfers:
        destination_ethereum_address_element = new_eth_addrs.pop()
        r = copy.deepcopy(basic_transfer_request)
        r.sifchain_symbol = sifsymbol
        r.sifchain_address = sifaddr
        r.ethereum_address = destination_ethereum_address_element["address"]
        r.amount = amount
        simple_credentials.from_key = from_key
        c = test_utilities.send_from_sifchain_to_ethereum_cmd(r, simple_credentials)
        ethereum_symbol = test_utilities.sifchain_symbol_to_ethereum_symbol(sifsymbol)
        transfer = (r.ethereum_address, ethereum_symbol, amount)
        ethereum_transfers.append(transfer)
        text_file.write(f"{c}\n")
    text_file.close()
    test_utilities.get_shell_output("cat pfile.cmds | parallel --trim lr -v {}")
    whitelist = test_utilities.get_whitelisted_tokens(basic_transfer_request)
    test_utilities.advance_n_ethereum_blocks(test_utilities.n_wait_blocks, smart_contracts_dir)
    for ethereum_address, ethereum_symbol, amount in ethereum_transfers:
        r = copy.deepcopy(basic_transfer_request)
        r.ethereum_address = ethereum_address
        r.ethereum_symbol = test_utilities.get_token_ethereum_address(
            ethereum_symbol,
            whitelist
        )
        r.amount = amount
        test_utilities.wait_for_eth_balance(
            transfer_request=r,
            target_balance=amount,
            max_seconds=60 * 60 * 10
        )