Skip to content
This repository has been archived by the owner on Jun 30, 2021. It is now read-only.

Plasma deposits #1217

Open
wants to merge 23 commits into
base: eth-blockchain
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .circleci/ci_e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ docker-compose up -d postgres mail
docker-compose run --rm ewallet sh <<EOF >/dev/null 2>&1
bin/ewallet initdb
bin/ewallet seed -e
bin/ewallet config blockchain_enabled false
bin/ewallet config internal_enabled true
bin/ewallet config base_url http://ewallet:4000
bin/ewallet config email_adapter smtp
bin/ewallet config smtp_host mail
Expand Down
19 changes: 19 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,31 @@ commands:
name: Attach workspace
at: ~/

add_rust_to_path:
description: "Add path to PATH env var"
steps:
- run:
name: Add rust to PATH env
command: echo 'export PATH=~/.cargo/bin/:$PATH' >> $BASH_ENV
- run:
name: Export flags
command: echo 'export RUSTFLAGS="-C target-feature=-crt-static"' >> $BASH_ENV

install_rust:
description: "Install Rust"
steps:
- run:
name: Install Rust
command: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
- add_rust_to_path


jobs:
build:
executor: builder
steps:
- checkout
- install_rust
- run: |
mkdir -p ~/var
elixir --version | tee ~/var/elixir-version
Expand Down
3 changes: 2 additions & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
elixir 1.8.1
erlang 21.0
erlang 22.3
rust 1.46.0
5 changes: 4 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM alpine:3.8
FROM alpine:3.12

LABEL maintainer="OmiseGO Team <[email protected]>"
LABEL description="Official image for OmiseGO eWallet"
Expand Down Expand Up @@ -31,6 +31,9 @@ RUN apk add --update --no-cache --virtual .ewallet-runtime \
libressl \
libressl-dev \
lksctp-tools

# ex_keccak
RUN apk add --no-cache rust=1.44.0-r0 cargo=1.44.0-r0

COPY rootfs /

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,58 +61,57 @@ defmodule AdminAPI.V1.BlockchainWalletControllerTest do
end
end

# TODO: update these tests when fixing deposits
# describe "/blockchain_wallet.deposit_to_childchain" do
# test_with_auths "deposit to childchain with the given attributes" do
# identifier = BlockchainHelper.rootchain_identifier()
# hot_wallet = BlockchainWallet.get_primary_hot_wallet(identifier)

# token =
# insert(:external_blockchain_token,
# blockchain_address: "0x0000000000000000000000000000000000000000"
# )

# adapter = BlockchainHelper.adapter()
# {:ok, _adapter_pid} = adapter.server().start_link([])

# attrs = %{
# token_id: token.id,
# amount: 100,
# address: hot_wallet.address,
# idempotency_token: UUID.generate()
# }

# response = request("/blockchain_wallet.deposit_to_childchain", attrs)

# assert response["success"]
# assert response["data"]["blockchain_transaction"] != nil
# assert response["data"]["type"] == "deposit"

# transaction = Transaction.get(response["data"]["id"], preload: :blockchain_transaction)
# {:ok, pid} = BlockchainTransactionTracker.lookup(transaction.blockchain_transaction_uuid)

# {:ok, %{pid: blockchain_listener_pid}} =
# adapter.lookup_listener(transaction.blockchain_transaction.hash)

# on_exit(fn ->
# :ok = GenServer.stop(pid)
# :ok = GenServer.stop(blockchain_listener_pid)
# end)
# end

# test_with_auths "fails to deposit with a missing address" do
# token = insert(:token, blockchain_address: "0x0000000000000000000000000000000000000000")

# response =
# request("/blockchain_wallet.deposit_to_childchain", %{
# token_id: token.id,
# amount: 100
# })

# refute response["success"]
# assert response["data"]["code"] == "client:invalid_parameter"
# end
# end
describe "/blockchain_wallet.deposit_to_childchain" do
test_with_auths "deposit to childchain with the given attributes" do
identifier = BlockchainHelper.rootchain_identifier()
hot_wallet = BlockchainWallet.get_primary_hot_wallet(identifier)

token =
insert(:external_blockchain_token,
blockchain_address: "0x0000000000000000000000000000000000000000"
)

adapter = BlockchainHelper.adapter()
{:ok, _adapter_pid} = adapter.server().start_link([])

attrs = %{
token_id: token.id,
amount: 100,
address: hot_wallet.address,
idempotency_token: UUID.generate()
}

response = request("/blockchain_wallet.deposit_to_childchain", attrs)

assert response["success"]
assert response["data"]["blockchain_transaction"] != nil
assert response["data"]["type"] == "deposit"

transaction = Transaction.get(response["data"]["id"], preload: :blockchain_transaction)
{:ok, pid} = BlockchainTransactionTracker.lookup(transaction.blockchain_transaction_uuid)

{:ok, %{pid: blockchain_listener_pid}} =
adapter.lookup_listener(transaction.blockchain_transaction.hash)

on_exit(fn ->
:ok = GenServer.stop(pid)
:ok = GenServer.stop(blockchain_listener_pid)
end)
end

test_with_auths "fails to deposit with a missing address" do
token = insert(:token, blockchain_address: "0x0000000000000000000000000000000000000000")

response =
request("/blockchain_wallet.deposit_to_childchain", %{
token_id: token.id,
amount: 100
})

refute response["success"]
assert response["data"]["code"] == "client:invalid_parameter"
end
end

describe "/blockchain_wallet.get" do
test_with_auths "returns a wallet when given an existing blockchain wallet address" do
Expand Down
10 changes: 3 additions & 7 deletions apps/eth_blockchain/lib/eth_blockchain/abi_encoder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,18 @@ defmodule EthBlockchain.ABIEncoder do
end

def encode_erc20_attrs(name, symbol, decimals, initial_amount) do
[{name, symbol, decimals, initial_amount}]
[name, symbol, decimals, initial_amount]
|> TypeEncoder.encode(%FunctionSelector{
function: nil,
types: [{:tuple, [:string, :string, {:uint, 8}, {:uint, 256}]}]
types: [:string, :string, {:uint, 8}, {:uint, 256}]
})
|> Base.encode16(case: :lower)
end

def child_chain_eth_deposit(tx_bytes) do
def child_chain_deposit(tx_bytes) do
{:ok, ABI.encode("deposit(bytes)", [tx_bytes])}
end

def child_chain_erc20_deposit(tx_bytes) do
{:ok, ABI.encode("depositFrom(bytes)", [tx_bytes])}
end

def mint("0x" <> _ = address, amount) do
{:ok,
ABI.encode("mint(address,uint)", [
Expand Down
34 changes: 6 additions & 28 deletions apps/eth_blockchain/lib/eth_blockchain/childchain.ex
Original file line number Diff line number Diff line change
Expand Up @@ -37,43 +37,21 @@ defmodule EthBlockchain.Childchain do
opts \\ []
) do
with :ok <- check_childchain(childchain_identifier),
# TODO: this is broken with new config, :get_contract_address does not exist anymore,
# need to use the eth or erc20 vaults instead
# (:get_childchain_eth_vault_address or :get_childchain_erc20_vault_address)
{:ok, contract_address} <- AdapterServer.childchain_call({:get_contract_address}, opts),
{:ok, tx_bytes} <-
AdapterServer.childchain_call({:get_deposit_tx_bytes, to, amount, currency}, opts) do
submit_deposit(tx_bytes, to, amount, currency, contract_address, opts)
submit_deposit(tx_bytes, to, amount, currency, opts)
end
end

defp submit_deposit(tx_bytes, to, amount, @eth, root_chain_contract, opts) do
Transaction.deposit_eth(
%{tx_bytes: tx_bytes, from: to, amount: amount, root_chain_contract: root_chain_contract},
opts
)
defp submit_deposit(tx_bytes, to, amount, @eth, opts) do
Transaction.deposit_eth(%{tx_bytes: tx_bytes, from: to, amount: amount}, opts)
end

defp submit_deposit(tx_bytes, to, amount, erc20, root_chain_contract, opts) do
defp submit_deposit(tx_bytes, to, amount, erc20, opts) do
with {:ok, _attrs} <-
Transaction.approve_erc20(
%{
from: to,
to: root_chain_contract,
amount: amount,
contract_address: erc20
},
opts
),
Transaction.approve_erc20(%{from: to, amount: amount, contract_address: erc20}, opts),
{:ok, _attrs} = response <-
Transaction.deposit_erc20(
%{
tx_bytes: tx_bytes,
from: to,
root_chain_contract: root_chain_contract
},
opts
) do
Transaction.deposit_erc20(%{tx_bytes: tx_bytes, from: to}, opts) do
response
end
end
Expand Down
2 changes: 1 addition & 1 deletion apps/eth_blockchain/lib/eth_blockchain/token.ex
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ defmodule EthBlockchain.Token do
end

defp parse_response({:ok, "0x" <> data}, _field, _opts) do
[{str}] = decode_abi(data, [{:tuple, [:string]}])
[str] = decode_abi(data, [:string])
{:ok, str}
end

Expand Down
33 changes: 18 additions & 15 deletions apps/eth_blockchain/lib/eth_blockchain/transaction.ex
Original file line number Diff line number Diff line change
Expand Up @@ -152,21 +152,22 @@ defmodule EthBlockchain.Transaction do
end

@doc """
Submit a deposit eth transaction to the specified root chain contract
Submit a deposit eth transaction
"""
def deposit_eth(
%{
tx_bytes: tx_bytes,
from: from,
amount: amount,
root_chain_contract: root_chain_contract
amount: amount
} = attrs,
opts \\ []
) do
with {:ok, meta} <- get_transaction_meta(attrs, :child_chain_deposit_eth, opts),
{:ok, encoded_abi_data} <- ABIEncoder.child_chain_eth_deposit(tx_bytes) do
with {:ok, vault_contract} <-
AdapterServer.childchain_call({:get_eth_vault_address}, opts),
{:ok, meta} <- get_transaction_meta(attrs, :child_chain_deposit_eth, opts),
{:ok, encoded_abi_data} <- ABIEncoder.child_chain_deposit(tx_bytes) do
%__MODULE__{
to: from_hex(root_chain_contract),
to: from_hex(vault_contract),
data: encoded_abi_data,
value: amount
}
Expand All @@ -176,20 +177,21 @@ defmodule EthBlockchain.Transaction do
end

@doc """
Submit a deposit transaction of an ERC20 token to the specified root chain contract
Submit a deposit transaction of an ERC20 token
"""
def deposit_erc20(
%{
tx_bytes: tx_bytes,
from: from,
root_chain_contract: root_chain_contract
from: from
} = attrs,
opts \\ []
) do
with {:ok, meta} <- get_transaction_meta(attrs, :child_chain_deposit_token, opts),
{:ok, encoded_abi_data} <- ABIEncoder.child_chain_erc20_deposit(tx_bytes) do
with {:ok, vault_contract} <-
AdapterServer.childchain_call({:get_erc20_vault_address}, opts),
{:ok, meta} <- get_transaction_meta(attrs, :child_chain_deposit_token, opts),
{:ok, encoded_abi_data} <- ABIEncoder.child_chain_deposit(tx_bytes) do
%__MODULE__{
to: from_hex(root_chain_contract),
to: from_hex(vault_contract),
data: encoded_abi_data
}
|> prepare_and_send(meta, from, opts)
Expand All @@ -203,14 +205,15 @@ defmodule EthBlockchain.Transaction do
def approve_erc20(
%{
from: from,
to: to,
amount: amount,
contract_address: contract_address
} = attrs,
opts \\ []
) do
with {:ok, meta} <- get_transaction_meta(attrs, :contract_transaction, opts),
{:ok, encoded_abi_data} <- ABIEncoder.approve(to, amount) do
with {:ok, vault_contract} <-
AdapterServer.childchain_call({:get_erc20_vault_address}, opts),
{:ok, meta} <- get_transaction_meta(attrs, :contract_transaction, opts),
{:ok, encoded_abi_data} <- ABIEncoder.approve(vault_contract, amount) do
%__MODULE__{
to: from_hex(contract_address),
data: encoded_abi_data
Expand Down
2 changes: 1 addition & 1 deletion apps/eth_blockchain/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ defmodule EthBlockchain.MixProject do
[
{:exth_crypto, "~> 0.1.6"},
{:deferred_config, "~> 0.1.0"},
{:ex_rlp, "~> 0.5.2"},
{:ex_rlp, "~> 0.5.3"},
{:utils, in_umbrella: true},
{:keychain, in_umbrella: true},
{:ewallet_config, in_umbrella: true},
Expand Down
Loading