Example #1
0
def test_transfer_eth_to_ceth_using_replay_blocks(integration_dir,
                                                  smart_contracts_dir,
                                                  ensure_relayer_restart):
    starting_block = test_utilities.current_ethereum_block_number(
        smart_contracts_dir)
    logging.info("stopping ebrelayer")
    test_utilities.get_shell_output("pkill -9 ebrelayer || true")
    request, credentials = build_request()
    logging.info("(no transactions should happen without a relayer)")
    # test_utilities.whitelist_token(request.ethereum_symbol, request.smart_contracts_dir, True)
    logging.info(
        f"send {request.amount / 10**18} eth ({request.amount} wei) to {request.sifchain_address}"
    )
    test_utilities.send_from_ethereum_to_sifchain(request)
    # test_utilities.get_shell_output(f"{integration_dir}/sifchain_start_ebrelayer.sh")

    logging.info("replay blocks using ebrelayer replayEthereum")
    ews = test_utilities.get_required_env_var("ETHEREUM_WEBSOCKET_ADDRESS")
    bra = test_utilities.get_required_env_var("BRIDGE_REGISTRY_ADDRESS")
    mon = test_utilities.get_required_env_var("MONIKER")
    mn = test_utilities.get_required_env_var("MNEMONIC")
    cn = test_utilities.get_required_env_var("CHAINNET")
    ending_block = test_utilities.current_ethereum_block_number(
        smart_contracts_dir) + 1
    cmd = f"""ebrelayer replayEthereum tcp://0.0.0.0:26657 {ews} {bra} {mon} '{mn}' {starting_block} {ending_block} 1 2 --chain-id {cn} --gas 5000000000000 \
  --gas-prices 0.5rowan"""
    test_utilities.get_shell_output(cmd)
    time.sleep(15)
    logging.info(
        f"check the ending balance of {request.sifchain_address} after replaying blocks"
    )
    ending_balance = test_utilities.get_sifchain_addr_balance(
        request.sifchain_address, request.sifnodecli_node,
        request.sifchain_symbol)
    assert (ending_balance == request.amount)

    # now do it again
    test_utilities.get_shell_output(cmd)
    time.sleep(5)
    ending_balance2 = test_utilities.get_sifchain_addr_balance(
        request.sifchain_address, request.sifnodecli_node,
        request.sifchain_symbol)
    assert (ending_balance2 == request.amount)

    # now start ebrelayer and do another transfer
    test_utilities.advance_n_ethereum_blocks(test_utilities.n_wait_blocks + 1,
                                             smart_contracts_dir)
    test_utilities.get_shell_output(
        f"{integration_dir}/sifchain_start_ebrelayer.sh")
    burn_lock_functions.transfer_ethereum_to_sifchain(request, 15)
    ending_balance3 = test_utilities.get_sifchain_addr_balance(
        request.sifchain_address, request.sifnodecli_node,
        request.sifchain_symbol)
    assert (ending_balance3 == request.amount * 2)
Example #2
0
def test_transfer_eth_to_ceth_using_replay_blocks(
        integration_dir, smart_contracts_dir, solidity_json_path,
        source_ethereum_address, validator_address, ensure_relayer_restart):
    starting_block = test_utilities.current_ethereum_block_number(
        smart_contracts_dir)
    logging.info("stopping ebrelayer")
    test_utilities.get_shell_output("pkill -9 ebrelayer || true")
    request, credentials = build_request(smart_contracts_dir,
                                         source_ethereum_address,
                                         solidity_json_path)
    logging.info("(no transactions should happen without a relayer)")
    logging.info(
        f"send {request.amount / 10 ** 18} eth ({request.amount} wei) to {request.sifchain_address}"
    )
    test_utilities.send_from_ethereum_to_sifchain(request)

    logging.info("make sure no balances changed while the relayer was offline")
    test_utilities.advance_n_ethereum_blocks(test_utilities.n_wait_blocks,
                                             smart_contracts_dir)
    time.sleep(5)
    balance_with_no_relayer = test_utilities.get_sifchain_addr_balance(
        request.sifchain_address, request.sifnoded_node,
        request.sifchain_symbol)
    assert (balance_with_no_relayer == 0)

    logging.info("replay blocks using ebrelayer replayEthereum")
    ews = test_utilities.get_required_env_var("ETHEREUM_WEBSOCKET_ADDRESS")
    bra = test_utilities.get_required_env_var("BRIDGE_REGISTRY_ADDRESS")
    mon = test_utilities.get_required_env_var("MONIKER")
    mn = test_utilities.get_required_env_var("MNEMONIC")
    cn = test_utilities.get_required_env_var("CHAINNET")
    ending_block = test_utilities.current_ethereum_block_number(
        smart_contracts_dir) + 1
    cmd = f"""yes | ebrelayer replayEthereum tcp://0.0.0.0:26657 {ews} {bra} {mon} '{mn}' {starting_block} {ending_block} 1 2 --chain-id {cn} --gas 5000000000000 \
 --keyring-backend test --node tcp://0.0.0.0:26657 --from {mon}"""
    test_utilities.get_shell_output(cmd)
    time.sleep(5)
    logging.info(
        f"check the ending balance of {request.sifchain_address} after replaying blocks"
    )
    ending_balance = test_utilities.get_sifchain_addr_balance(
        request.sifchain_address, request.sifnoded_node,
        request.sifchain_symbol)
    assert (ending_balance == request.amount)

    # now do it again
    test_utilities.get_shell_output(cmd)
    time.sleep(5)
    ending_balance2 = test_utilities.get_sifchain_addr_balance(
        request.sifchain_address, request.sifnoded_node,
        request.sifchain_symbol)
    assert (ending_balance2 == request.amount)
Example #3
0
def test_can_mint_token_and_peg_it_for_everything_in_whitelist(
        basic_transfer_request: EthereumToSifchainTransferRequest,
        smart_contracts_dir, bridgebank_address, solidity_json_path,
        operator_address, ethereum_network, source_ethereum_address,
        rowan_source):
    logging.info(
        "token_refresh needs to use the operator private key, setting that to ETHEREUM_PRIVATE_KEY"
    )
    os.environ["ETHEREUM_PRIVATE_KEY"] = test_utilities.get_required_env_var(
        "OPERATOR_PRIVATE_KEY")
    request = copy.deepcopy(basic_transfer_request)
    request.sifchain_address = rowan_source
    request.ethereum_address = source_ethereum_address
    amount_in_tokens = int(test_utilities.get_required_env_var("TOKEN_AMOUNT"))

    tokens = test_utilities.get_whitelisted_tokens(request)
    logging.info(f"whitelisted tokens: {tokens}")

    for t in tokens:
        destination_symbol = "c" + t["symbol"]
        if t["symbol"] == "erowan":
            destination_symbol = "rowan"
        try:
            logging.info(f"sending {t}")
            request.amount = amount_in_tokens * (10**int(t["decimals"]))
            request.ethereum_symbol = t["token"]
            request.sifchain_symbol = destination_symbol
            request.ethereum_address = operator_address
            test_utilities.mint_tokens(request, operator_address)
            test_utilities.send_from_ethereum_to_sifchain(request)
        except Exception as e:
            # try to get as many tokens across the bridge as you can,
            # don't stop if one of them fails
            logging.info(f"failed to mint and send for {t}, error was {e}")
    logging.info(f"sent new batch of tokens to {rowan_source}")
    test_utilities.get_sifchain_addr_balance(rowan_source,
                                             request.sifnoded_node, "rowan")
Example #4
0
def transfer_ethereum_to_sifchain(
        transfer_request: EthereumToSifchainTransferRequest,
        max_seconds: int = default_timeout_for_ganache):
    logging.debug(
        f"transfer_ethereum_to_sifchain {transfer_request.as_json()}")
    assert transfer_request.ethereum_address
    assert transfer_request.sifchain_address

    # it's possible that this is the first transfer to the address, so there's
    # no balance to retrieve.  Catch that exception.

    original_log_level = decrease_log_level()

    try:
        sifchain_starting_balance = get_sifchain_addr_balance(
            transfer_request.sifchain_address,
            transfer_request.sifnodecli_node, transfer_request.sifchain_symbol)
    except:
        logging.debug(
            f"transfer_ethereum_to_sifchain failed to get starting balance, this is probably a new account"
        )
        sifchain_starting_balance = 0

    status = {
        "action": "transfer_ethereum_to_sifchain",
        "sifchain_starting_balance": sifchain_starting_balance,
        "transfer_request": transfer_request.__dict__,
    }
    logging.debug(
        f"transfer_ethereum_to_sifchain_json: {json.dumps(status)}", )

    force_log_level(original_log_level)
    starting_block = send_from_ethereum_to_sifchain(transfer_request)
    logging.debug(
        f"send_from_ethereum_to_sifchain ethereum block number: {starting_block}"
    )
    original_log_level = decrease_log_level()

    half_n_wait_blocks = n_wait_blocks / 2
    logging.debug("wait half the blocks, transfer should not complete")
    if transfer_request.manual_block_advance:
        advance_n_ethereum_blocks(half_n_wait_blocks,
                                  transfer_request.smart_contracts_dir)
        time.sleep(5)
    else:
        wait_for_ethereum_block_number(block_number=starting_block +
                                       half_n_wait_blocks,
                                       transfer_request=transfer_request)

    # we still may not have an account
    try:
        sifchain_balance_before_required_elapsed_blocks = get_sifchain_addr_balance(
            transfer_request.sifchain_address,
            transfer_request.sifnodecli_node, transfer_request.sifchain_symbol)
    except:
        sifchain_balance_before_required_elapsed_blocks = 0

    if transfer_request.check_wait_blocks and sifchain_balance_before_required_elapsed_blocks != sifchain_starting_balance:
        print_error_message(
            f"balance should not have changed yet.  Starting balance {sifchain_starting_balance},"
            f" current balance {sifchain_balance_before_required_elapsed_blocks}"
        )

    if transfer_request.manual_block_advance:
        advance_n_ethereum_blocks(half_n_wait_blocks,
                                  transfer_request.smart_contracts_dir)
    else:
        wait_for_ethereum_block_number(block_number=starting_block +
                                       n_wait_blocks,
                                       transfer_request=transfer_request)

    target_balance = sifchain_starting_balance + transfer_request.amount

    # You can't get the balance of an account that doesn't exist yet,
    # so wait for the account to be there before asking for the balance
    logging.debug(f"wait for account {transfer_request.sifchain_address}")
    wait_for_sif_account(sif_addr=transfer_request.sifchain_address,
                         sifchaincli_node=transfer_request.sifnodecli_node,
                         max_seconds=max_seconds)

    wait_for_sifchain_addr_balance(
        sifchain_address=transfer_request.sifchain_address,
        symbol=transfer_request.sifchain_symbol,
        sifchaincli_node=transfer_request.sifnodecli_node,
        target_balance=target_balance,
        max_seconds=max_seconds,
        debug_prefix=
        f"transfer_ethereum_to_sifchain waiting for balance {transfer_request}"
    )

    force_log_level(original_log_level)

    result = {
        **status,
        "sifchain_ending_balance": target_balance,
    }
    logging.debug(f"transfer_ethereum_to_sifchain completed {result}")
    return result
Example #5
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, "")