Exemplo n.º 1
0
def env_or_truffle_artifact(contract_name, contract_env_var, smart_contract_artifact_dir, ethereum_network_id):
    result = test_utilities.get_optional_env_var(contract_env_var, None)
    return result if result else test_utilities.contract_address(
        smart_contract_artifact_dir=smart_contract_artifact_dir,
        contract_name=contract_name,
        ethereum_network_id=ethereum_network_id
    )
Exemplo n.º 2
0
def ethereum_network_id(is_ropsten_testnet):
    result = test_utilities.get_optional_env_var("ETHEREUM_NETWORK_ID", None)
    if result:
        return result
    else:
        result = 3 if is_ropsten_testnet else 5777
        return result
Exemplo n.º 3
0
def chain_id(is_ropsten_testnet):
    result = test_utilities.get_optional_env_var("CHAINNET", None)
    if result:
        return result
    else:
        id = "swing-set" if is_ropsten_testnet else "localnet"
        return id
Exemplo n.º 4
0
def operator_private_key(ganache_keys_file, operator_address):
    result = test_utilities.get_optional_env_var(
        "OPERATOR_PRIVATE_KEY",
        test_utilities.ganache_private_key(ganache_keys_file, operator_address)
    )
    os.environ["OPERATOR_PRIVATE_KEY"] = result
    return result
Exemplo n.º 5
0
def rowan_source(is_ropsten_testnet, validator_address):
    """A sifchain address or key that has rowan and can send that rowan to other address"""
    result = test_utilities.get_optional_env_var("ROWAN_SOURCE", None)
    if result:
        return result
    if is_ropsten_testnet:
        assert result
    else:
        assert validator_address
        return validator_address
Exemplo n.º 6
0
def rowan_source_key(is_ropsten_testnet, rowan_source):
    """A sifchain address or key that has rowan and can send that rowan to other address"""
    result = test_utilities.get_optional_env_var("ROWAN_SOURCE_KEY", rowan_source)
    if result:
        return result
    if is_ropsten_testnet:
        # Ropsten requires that you manually set the ROWAN_SOURCE_KEY environment variable
        assert result
    else:
        return test_utilities.get_required_env_var("MONIKER")
Exemplo n.º 7
0
def test_bulk_transfers(
    basic_transfer_request: EthereumToSifchainTransferRequest,
    smart_contracts_dir,
    source_ethereum_address,
    bridgebank_address,
    integration_dir,
    ganache_timed_blocks,
):
    n_transfers = int(test_utilities.get_optional_env_var("NTRANSFERS", 1))
    ganache_delay = test_utilities.get_optional_env_var("GANACHE_DELAY", 1)
    # test_utilities.get_shell_output(f"{integration_dir}/ganache_start.sh {ganache_delay}")
    amount = 9000
    new_addresses = list(
        map(lambda x: create_new_sifaddr(), range(n_transfers)))
    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)
    yarn_result = test_utilities.run_yarn_command(" ".join([
        f"yarn --cwd {smart_contracts_dir}", "integrationtest:sendBulkLockTx",
        f"--amount {amount}", f"--symbol eth",
        f"--sifchain_address {new_addresses[0]}",
        f"--transactions \'{json_requests}\'",
        f"--ethereum_address {source_ethereum_address}",
        f"--bridgebank_address {bridgebank_address}"
    ]))
    logging.info(f"bulk result: {yarn_result}")
    test_utilities.wait_for_ethereum_block_number(
        yarn_result["blockNumber"] + test_utilities.n_wait_blocks,
        basic_transfer_request)
    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, 90)
Exemplo n.º 8
0
def source_ethereum_address(is_ropsten_testnet, smart_contracts_dir):
    """account with some starting eth that can be transferred out"""
    addr = test_utilities.get_optional_env_var("ETHEREUM_ADDRESS", "")
    if is_ropsten_testnet:
        assert addr
        return addr
    else:
        if addr:
            logging.debug("using ETHEREUM_ADDRESS provided for source_ethereum_address")
            return addr
        else:
            result = test_utilities.ganache_owner_account(smart_contracts_dir)
            logging.debug(
                f"Using source_ethereum_address {result} from ganache_owner_account.  (Set ETHEREUM_ADDRESS env var to set it manually)")
            assert result
            return result
Exemplo n.º 9
0
def source_ethereum_address(is_ropsten_testnet, smart_contracts_dir):
    """
    Account with some starting eth that can be transferred out.

    Our test wallet can only use one address/privatekey combination,
    so if you set OPERATOR_ACCOUNT you have to set ETHEREUM_PRIVATE_KEY to the operator private key
    """
    addr = test_utilities.get_optional_env_var("ETHEREUM_ADDRESS", "")
    if addr:
        logging.debug("using ETHEREUM_ADDRESS provided for source_ethereum_address")
        return addr
    if is_ropsten_testnet:
        # Ropsten requires that you manually set the ETHEREUM_ADDRESS environment variable
        assert addr
    result = test_utilities.ganache_owner_account(smart_contracts_dir)
    logging.debug(
        f"Using source_ethereum_address {result} from ganache_owner_account.  (Set ETHEREUM_ADDRESS env var to set it manually)")
    assert result
    return result
Exemplo n.º 10
0
def smart_contract_artifact_dir(smart_contracts_dir):
    result = test_utilities.get_optional_env_var("SMART_CONTRACT_ARTIFACT_DIR", None)
    return result if result else os.path.join(smart_contracts_dir, "build/contracts")
Exemplo n.º 11
0
def ganache_keys_file(sifnode_base_dir):
    return test_utilities.get_optional_env_var(
        "GANACHE_KEYS_FILE",
        os.path.join(sifnode_base_dir, "test/integration/vagrant/data/ganachekeys.json")
    )
Exemplo n.º 12
0
from copy import copy, deepcopy
from functools import lru_cache
from json import JSONDecodeError

import pytest

import burn_lock_functions
from burn_lock_functions import EthereumToSifchainTransferRequest
from integration_env_credentials import sifchain_cli_credentials_for_test
import test_utilities
from test_utilities import get_required_env_var, get_shell_output, SifchaincliCredentials, amount_in_wei, \
    get_optional_env_var, ganache_owner_account

smart_contracts_dir = get_required_env_var("SMART_CONTRACTS_DIR")

ethereum_address = get_optional_env_var(
    "ETHEREUM_ADDRESS", ganache_owner_account(smart_contracts_dir))


def build_request(
) -> (EthereumToSifchainTransferRequest, SifchaincliCredentials):
    new_account_key = get_shell_output("uuidgen")
    credentials = sifchain_cli_credentials_for_test(new_account_key)
    new_addr = burn_lock_functions.create_new_sifaddr(credentials=credentials,
                                                      keyname=new_account_key)
    credentials.from_key = new_addr["name"]
    request = EthereumToSifchainTransferRequest(
        sifchain_address=new_addr["address"],
        smart_contracts_dir=smart_contracts_dir,
        ethereum_address=ethereum_address,
        ethereum_private_key_env_var="ETHEREUM_PRIVATE_KEY",
        bridgebank_address=get_required_env_var("BRIDGE_BANK_ADDRESS"),
Exemplo n.º 13
0
def operator_address(smart_contracts_dir):
    return test_utilities.get_optional_env_var("OPERATOR_ADDRESS",
                                               test_utilities.ganache_owner_account(smart_contracts_dir))
Exemplo n.º 14
0
def validator_address():
    return test_utilities.get_optional_env_var("OWNER_ADDR", None)
Exemplo n.º 15
0
def test_bulk_transfers(
    basic_transfer_request: EthereumToSifchainTransferRequest,
    smart_contracts_dir,
    source_ethereum_address,
    bridgebank_address,
    bridgetoken_address,
    ethereum_network,
):
    n_transfers = int(test_utilities.get_optional_env_var("NTRANSFERS", 2))
    ganache_delay = test_utilities.get_optional_env_var("GANACHE_DELAY", 1)
    # test_utilities.get_shell_output(f"{integration_dir}/ganache_start.sh {ganache_delay}")
    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))
    json_requests = json.dumps(requests)
    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}",
        f"--ethereum_network {ethereum_network}",
    ]))
    requests = list(
        map(
            lambda addr: {
                "amount": amount,
                "symbol": bridgetoken_address,
                "sifchain_address": addr
            }, new_addresses))
    json_requests = json.dumps(requests)
    yarn_result = test_utilities.run_yarn_command(" ".join([
        f"yarn --cwd {smart_contracts_dir}",
        "integrationtest:sendBulkLockTx",
        f"--amount {amount}",
        "--lock_or_burn burn",
        f"--symbol {bridgetoken_address}",
        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}",
        f"--ethereum_network {ethereum_network}",
    ]))
    logging.info(f"bulk result: {yarn_result}")
    manual_advance = False
    if manual_advance:
        test_utilities.advance_n_ethereum_blocks(test_utilities.n_wait_blocks,
                                                 smart_contracts_dir)
    test_utilities.wait_for_ethereum_block_number(
        yarn_result["blockNumber"] + test_utilities.n_wait_blocks,
        basic_transfer_request)
    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.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, 300)
Exemplo n.º 16
0
def solidity_json_path(smart_contracts_dir):
    return test_utilities.get_optional_env_var("SOLIDITY_JSON_PATH", f"{smart_contracts_dir}/build/contracts")
Exemplo n.º 17
0
def n_sifchain_accounts():
    return int(test_utilities.get_optional_env_var("N_SIFCHAIN_ACCOUNTS", 1))
def create_new_sifaddr():
    new_account_key = test_utilities.get_shell_output("uuidgen")
    credentials = sifchain_cli_credentials_for_test(new_account_key)
    new_addr = burn_lock_functions.create_new_sifaddr(credentials=credentials, keyname=new_account_key)
    return new_addr["address"]


def create_new_sifaddr_and_key():
    new_account_key = test_utilities.get_shell_output("uuidgen")
    credentials = sifchain_cli_credentials_for_test(new_account_key)
    new_addr = burn_lock_functions.create_new_sifaddr(credentials=credentials, keyname=new_account_key)
    return new_addr["address"], new_addr["name"]


@pytest.mark.skipif(not test_utilities.get_optional_env_var("NTRANSFERS", None), reason="run by hand and specify NTRANSFERS")
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(
Exemplo n.º 19
0
def validator_password():
    return test_utilities.get_optional_env_var("VALIDATOR1_PASSWORD", None)
Exemplo n.º 20
0
def chain_id(is_ropsten_testnet):
    id = "sandpit" if is_ropsten_testnet else 5777
    return test_utilities.get_optional_env_var("CHAINNET", id)
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))
Exemplo n.º 22
0
import copy
import logging

import pytest
import time

import burn_lock_functions
import test_utilities
from integration_env_credentials import sifchain_cli_credentials_for_test
from test_utilities import EthereumToSifchainTransferRequest, SifchaincliCredentials


@pytest.mark.skipif(
    not test_utilities.get_optional_env_var("DESTINATION_ACCOUNT", None),
    reason="run by hand and specify DESTINATION_ACCOUNT")
def test_token_distribution(
    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,
):
    tokens = test_utilities.get_whitelisted_tokens(basic_transfer_request)
    request = basic_transfer_request
    amount_in_tokens = 10000000
Exemplo n.º 23
0
def validator_address():
    return test_utilities.get_optional_env_var("VALIDATOR1_ADDR", None)
Exemplo n.º 24
0
def smart_contracts_dir(sifnode_base_dir):
    return test_utilities.get_optional_env_var("SMART_CONTRACTS_DIR", os.path.join(sifnode_base_dir, "smart-contracts"))
Exemplo n.º 25
0
def ethereum_network():
    return test_utilities.get_optional_env_var("ETHEREUM_NETWORK", "")
Exemplo n.º 26
0
def sifnoded_node():
    return test_utilities.get_optional_env_var("SIFNODE", None)
Exemplo n.º 27
0
def rowan_amount():
    """the meaning of rowan_amount is determined by the test using it"""
    return int(int(test_utilities.get_optional_env_var("ROWAN_AMOUNT", 10 ** 18)))
Exemplo n.º 28
0
def chain_id(is_ropsten_testnet):
    result = test_utilities.get_optional_env_var("DEPLOYMENT_NAME", "localnet")
    return result
Exemplo n.º 29
0
import logging
from copy import deepcopy

import burn_lock_functions
import test_utilities
from burn_lock_functions import EthereumToSifchainTransferRequest
from integration_env_credentials import sifchain_cli_credentials_for_test
from test_utilities import get_required_env_var, get_shell_output, SifchaincliCredentials, get_optional_env_var

smart_contracts_dir = get_required_env_var("SMART_CONTRACTS_DIR")
ethereum_network = get_optional_env_var("ETHEREUM_NETWORK", "")
amount = int(get_optional_env_var("AMOUNT", "20000"))
bridgebank_address = get_required_env_var("BRIDGE_BANK_ADDRESS")


def build_request(
        sifnodecli_node, source_ethereum_address, chain_id
) -> (EthereumToSifchainTransferRequest, SifchaincliCredentials):
    new_account_key = get_shell_output("uuidgen")
    credentials = sifchain_cli_credentials_for_test(new_account_key)
    new_addr = burn_lock_functions.create_new_sifaddr(credentials=credentials,
                                                      keyname=new_account_key)
    credentials.from_key = new_addr["name"]
    ceth_fee = 2 * (10**16)
    request = EthereumToSifchainTransferRequest(
        sifchain_address=new_addr["address"],
        smart_contracts_dir=smart_contracts_dir,
        ethereum_address=source_ethereum_address,
        ethereum_private_key_env_var="ETHEREUM_PRIVATE_KEY",
        bridgebank_address=bridgebank_address,
        ethereum_network=ethereum_network,
Exemplo n.º 30
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
        )