From 3b132b9b116030e65a02c6c084bbb950030e72b7 Mon Sep 17 00:00:00 2001 From: Mason Fischer Date: Thu, 6 Dec 2018 15:17:05 -0500 Subject: [PATCH] Setup docker-compose --- .dockerignore | 9 + Dockerfile | 68 ++++++- Makefile | 14 ++ config/dev.exs | 18 +- config/docker.env | 12 ++ config/prod.exs | 27 +-- config/test.exs | 5 +- docker-compose.yml | 31 +++ lib/blacksmith/application.ex | 4 +- lib/crypto.ex | 7 +- .../contracts/ellipticoin_staking_contract.ex | 36 +++- lib/ethereum/helpers.ex | 12 +- lib/models/block.ex | 2 +- lib/redis.ex | 3 +- lib/redis/pubsub.ex | 12 +- lib/release/tasks.ex | 9 + lib/router.ex | 178 +++++++++--------- lib/staking_contract_monitor.ex | 7 +- lib/transaction_processor.ex | 10 +- mix.exs | 35 ++-- mix.lock | 14 +- native/transaction_processor/src/main.rs | 6 +- rel/config.exs | 24 ++- rel/config/config.exs | 20 ++ rel/hooks/pre_start/echo.sh | 1 + rel/hooks/pre_start/wait_for_postgres | 5 + rel/plugins/.gitignore | 3 + rel/vm.args | 30 +++ submit_block.exs | 40 ++++ 29 files changed, 447 insertions(+), 195 deletions(-) create mode 100644 Makefile create mode 100644 config/docker.env create mode 100644 docker-compose.yml create mode 100644 lib/release/tasks.ex create mode 100644 rel/config/config.exs create mode 100755 rel/hooks/pre_start/echo.sh create mode 100755 rel/hooks/pre_start/wait_for_postgres create mode 100644 rel/plugins/.gitignore create mode 100644 rel/vm.args create mode 100644 submit_block.exs diff --git a/.dockerignore b/.dockerignore index fdfbde4..d845b8e 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,11 @@ deps _build +.git/ +.gitignore +config/dev* +config/test* +Dockerfile +Makefile +README* +test/ +priv/static/ diff --git a/Dockerfile b/Dockerfile index 1542035..eac8fcd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,58 @@ -FROM elixir:latest -MAINTAINER Mason Fischer -RUN apt-get update -RUN apt-get install -y curl wget -RUN apt-get update -RUN apt-get install -y git build-essential libtool autoconf clang libclang-dev llvm librocksdb-dev libgmp-dev -RUN wget https://download.libsodium.org/libsodium/releases/LATEST.tar.gz && tar -xf LATEST.tar.gz && cd ./libsodium-stable && ./configure && make && make install -RUN mix local.hex --force && mix local.rebar --force -RUN curl https://sh.rustup.rs -sSf | sh -s -- -y -RUN . $HOME/.cargo/env && rustup default nightly +# Copied from https://hexdocs.pm/distillery/guides/working_with_docker.html#the-dockerfile +# Switch alpine once this issue is fixed: https://github.com/rust-lang/rustup.rs/issues/640#issuecomment-274550200 +FROM elixir:1.7.4 AS builder +ARG APP_NAME=blacksmith +ARG APP_VERSION=0.1.0 +ARG MIX_ENV=prod +ARG PHOENIX_SUBDIR=. +ENV APP_NAME=${APP_NAME} \ + APP_VERSION=${APP_VERSION} \ + MIX_ENV=${MIX_ENV} + +WORKDIR /opt/app + +RUN apt-get update && apt-get install -y \ + autoconf \ + build-essential \ + curl \ + git \ + libgmp-dev \ + libtool \ + rebar &&\ + mix local.rebar --force && \ + mix local.hex --force + +RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain nightly +ENV PATH=/root/.cargo/bin:$PATH +COPY . . +RUN mix do deps.get, deps.compile, compile + +RUN mkdir -p /opt/built +RUN ls rel/hooks +RUN mix release --verbose --env=prod +RUN cp _build/${MIX_ENV}/rel/${APP_NAME}/releases/${APP_VERSION}/${APP_NAME}.tar.gz /opt/built +RUN cd /opt/built && \ + tar -xzf ${APP_NAME}.tar.gz && \ + rm ${APP_NAME}.tar.gz && \ + cp /opt/app/deps/libsecp256k1/priv/libsecp256k1_nif.so lib/libsecp256k1-0.1.10/priv + +RUN find / -name transaction_processor +FROM debian:stretch +ARG APP_NAME + +ENV REPLACE_OS_VARS=true \ + APP_NAME=${APP_NAME} + +WORKDIR /opt/app + +COPY --from=builder /opt/built . +RUN apt-get update && apt-get install -y \ + bash \ + libgmp-dev \ + libssl-dev \ + postgresql-client \ + openssl + +ENV LANG C.UTF-8 +ENV LC_ALL C.UTF-8 +CMD trap 'exit' INT;echo $MIX_ENV; echo $WEB3_URL; /opt/app/bin/${APP_NAME} foreground diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..57b6891 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +APP_NAME ?= `grep 'app: *:' mix.exs | sed -e 's/\[//g' -e 's/ //g' -e 's/app://' -e 's/[:,]//g'` +APP_VSN ?= `grep 'version:' mix.exs | cut -d '"' -f2` +BUILD ?= `git rev-parse --short HEAD` + +build: + docker build --build-arg APP_NAME=$(APP_NAME) \ + --build-arg APP_VSN=$(APP_VSN) \ + -t $(APP_NAME):$(APP_VSN)-$(BUILD) \ + -t $(APP_NAME):latest . + +run: + docker run --env-file config/docker.env \ + --expose 4045 -p 4045:4045 \ + --rm -it $(APP_NAME):latest diff --git a/config/dev.exs b/config/dev.exs index 5163b8b..e0d1705 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -1,30 +1,20 @@ use Mix.Config -private_key = - <<238, 163, 60, 8, 21, 24, 67, 133, 67, 178, 163, 66, 57, 255, 25, 13, 1, 184, 12, 138, 211, - 125, 187, 121, 14, 43, 17, 237, 131, 168, 205, 133>> - config :blacksmith, base_contracts_path: "./base_contracts" config :blacksmith, port: 4047 -config :blacksmith, private_key: private_key config :blacksmith, staking_contract_address: "756d0ABF6235AB135126fe772CDaE195C3DECc0e" |> Base.decode16!(case: :mixed) -config :ex_wire, private_key, private_key -# private_key: -# <<18, 116, 234, 41, 220, 113, 180, 178, 230, 67, 159, 221, 16, 149, 69, 232, 193, 88, 94, 43, -# 22, 188, 212, 82, 54, 254, 32, 251, 249, 25, 167, 13>> -# config :ethereumex, :web3_url, "ws://localhost:8545/" -# config :ethereumex, :web3_url, "wss://ropsten.infura.io/ws/v3/28d900c929bf4df88e0a4adc9f790e22" config :ethereumex, :client_type, :websocket config :ethereumex, :web3_url, "wss://rinkeby.infura.io/ws/v3/28d900c929bf4df88e0a4adc9f790e22" -# config :ethereumex, :client_type, :http +config :blacksmith, :redis_url, "redis://127.0.0.1:6379/" config :blacksmith, Blacksmith.Repo, adapter: Ecto.Adapters.Postgres, - database: "test_mix", + database: "blacksmith_dev", username: "masonf", password: "", - hostname: "localhost" + hostname: "localhost", + log: false diff --git a/config/docker.env b/config/docker.env new file mode 100644 index 0000000..a35b976 --- /dev/null +++ b/config/docker.env @@ -0,0 +1,12 @@ +MIX_ENV=PROD +APP_NAME=blacksmith +POSTGRES_HOST=postgres +POSTGRES_USER=postgres +POSTGRES_PASS= +POSTGRES_DB=blacksmith +REDIS_URL=redis://redis:6379/ +PORT=4045 +STAKING_CONTRACT_ADDRESS=756d0ABF6235AB135126fe772CDaE195C3DECc0e +WEB3_URL=wss://rinkeby.infura.io/ws +ETHEREUM_PRIVATE_KEY=1274EA29DC71B4B2E6439FDD109545E8C1585E2B16BCD45236FE20FBF919A70D +REPLACE_OS_VARS=true diff --git a/config/prod.exs b/config/prod.exs index 4290fbe..3ebd818 100644 --- a/config/prod.exs +++ b/config/prod.exs @@ -1,27 +1,18 @@ use Mix.Config -private_key = - <<238, 163, 60, 8, 21, 24, 67, 133, 67, 178, 163, 66, 57, 255, 25, 13, 1, 184, 12, 138, 211, - 125, 187, 121, 14, 43, 17, 237, 131, 168, 205, 133>> - config :blacksmith, base_contracts_path: "./base_contracts" -config :blacksmith, port: 4047 -config :blacksmith, private_key: private_key +config :blacksmith, port: String.to_integer(System.get_env("PORT") || "4045") config :blacksmith, staking_contract_address: - "756d0ABF6235AB135126fe772CDaE195C3DECc0e" |> Base.decode16!(case: :mixed) + (System.get_env("STAKING_CONTRACT_ADDRESS") || "") |> Base.decode16!(case: :mixed) -# config :ex_wire, private_key, private_key -# private_key: -# <<18, 116, 234, 41, 220, 113, 180, 178, 230, 67, 159, 221, 16, 149, 69, 232, 193, 88, 94, 43, -# 22, 188, 212, 82, 54, 254, 32, 251, 249, 25, 167, 13>> -config :ethereumex, :web3_url, "wss://ropsten.infura.io/ws/v3/28d900c929bf4df88e0a4adc9f790e22" -# config :ethereumex, :client_type, :websocket +config :ethereumex, :web3_url, System.get_env("WEB3_URL") +config :ethereumex, :client_type, :websocket config :blacksmith, Blacksmith.Repo, - adapter: Ecto.Adapters.Postgres, - database: "test_mix", - username: "masonf", - password: "", - hostname: "localhost" + username: System.get_env("DATABASE_USER"), + password: System.get_env("DATABASE_PASS"), + database: System.get_env("DATABASE_NAME"), + hostname: System.get_env("DATABASE_HOST"), + pool_size: 15 diff --git a/config/test.exs b/config/test.exs index ffcb1b3..5c3c8ae 100644 --- a/config/test.exs +++ b/config/test.exs @@ -15,8 +15,9 @@ config :ex_wire, 22, 188, 212, 82, 54, 254, 32, 251, 249, 25, 167, 13>> config :ethereumex, :web3_url, "ws://localhost:8545/" -# config :ethereumex, :web3_url, "wss://rinkeby.infura.io/ws" -# config :ethereumex, :client_type, :websocket +config :ethereumex, :web3_url, "wss://rinkeby.infura.io/ws" +config :ethereumex, :client_type, :websocket +config :blacksmith, :redis_url, "redis://127.0.0.1:6379/" config :blacksmith, :ethereumex_auto_mine, true config :blacksmith, Blacksmith.Repo, diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f82c99d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,31 @@ +version: '3.5' + +services: + blacksmith: + build: . + ports: + - "4045:4045" + env_file: + - config/docker.env + depends_on: + - postgres + - redis + postgres: + image: postgres:10-alpine + # build: + # context: https://github.com/docker-library/postgres.git + # dockerfile: 11/alpine/Dockerfile + # args: + # - POSTGRES_DB=blacksmith + volumes: + - "./tmp/volumes/postgres:/var/lib/postgresql/data" + ports: + - "5432:5432" + environment: + - POSTGRES_DB=blacksmith + redis: + image: redis:5-alpine + volumes: + - "./volumes/redis:/data" + ports: + - "6379:6379" diff --git a/lib/blacksmith/application.ex b/lib/blacksmith/application.ex index 77ec740..49e591b 100644 --- a/lib/blacksmith/application.ex +++ b/lib/blacksmith/application.ex @@ -3,8 +3,8 @@ defmodule Blacksmith.Application do use Application def start(_type, _args) do - :pg2.create("websocket::blocks") - + # :pg2.create("websocket::blocks") + # children = [ supervisor(Blacksmith.Repo, []), {Redis, name: Redis}, diff --git a/lib/crypto.ex b/lib/crypto.ex index fbd7187..e1bfa99 100644 --- a/lib/crypto.ex +++ b/lib/crypto.ex @@ -7,10 +7,13 @@ defmodule Crypto do :libsodium_crypto_sign_ed25519.keypair() end - def hash(value) do - :crypto.hash(:sha256, value) + def hash(message) do + sha256(message) end + def keccak256(message), do: :keccakf1600.sha3_256(message) + def sha256(message), do: :crypto.hash(:sha256, message) + def sign(message, secret_key), do: sign_ed25519(message, secret_key) def sign_ed25519(message, secret_key) do diff --git a/lib/ethereum/contracts/ellipticoin_staking_contract.ex b/lib/ethereum/contracts/ellipticoin_staking_contract.ex index 2972629..142a6a5 100644 --- a/lib/ethereum/contracts/ellipticoin_staking_contract.ex +++ b/lib/ethereum/contracts/ellipticoin_staking_contract.ex @@ -12,9 +12,6 @@ defmodule Ethereum.Contracts.EllipticoinStakingContract do abi = ExW3.load_abi(abi_file_name("EllipticoinStakingContract")) ExW3.Contract.register(__MODULE__, abi: abi) ExW3.Contract.at(__MODULE__, bytes_to_hex(contract_address)) - # IO.inspect bytes_to_hex(contract_address) - # IO.inspect ExW3.Contract.call(__MODULE__, :winner) - # IO.inspect Ethereum.Contracts.EllipticoinStakingContract.winner() GenServer.start_link(__MODULE__, %{}, opts) end @@ -25,17 +22,36 @@ defmodule Ethereum.Contracts.EllipticoinStakingContract do gas: 6_721_975 }) - def submit_block(block_hash, <>, address), - do: - ExW3.Contract.send(__MODULE__, :submitBlock, [block_hash, recovery_id + 27, r, s], %{ - from: address, - gas: 6_721_975 - }) + def submit_block(block_hash, <>) do +abi_encoded_data = ABI.encode("submitBlock(bytes32,uint8,bytes32,bytes32)", [block_hash, recovery_id + 27, r, s]) + contract_address = Application.fetch_env!(:blacksmith, :staking_contract_address) + ethereum_private_key = Application.fetch_env!(:blacksmith, :ethereum_private_key) + +IO.inspect recovery_id + 27, label: "v" +IO.inspect r |> Base.encode16(case: :lower), label: "r" +IO.inspect s |> Base.encode16(case: :lower), label: "s" + {:ok, transaction_count} = Ethereumex.WebSocketClient.eth_get_transaction_count(Ethereum.Helpers.bytes_to_hex(Ethereum.Helpers.my_ethereum_address())) + # IO.inspect Ethereum.Helpers.bytes_to_hex(Ethereum.Helpers.my_ethereum_address()) + IO.inspect Ethereumex.WebSocketClient.eth_get_balance(Ethereum.Helpers.bytes_to_hex(Ethereum.Helpers.my_ethereum_address())) + transaction_data = %Blockchain.Transaction{ + data: abi_encoded_data, + gas_price: 1000000003, + gas_limit: 4712388, + nonce: Ethereum.Helpers.hex_to_int(transaction_count), + to: contract_address, + value: 0 + } + |> Blockchain.Transaction.Signature.sign_transaction(ethereum_private_key) + |> Blockchain.Transaction.serialize() + |> ExRLP.encode() + |> Base.encode16(case: :lower) + IO.inspect Ethereumex.WebSocketClient.eth_send_raw_transaction("0x" <> transaction_data) + end def last_signature() do {:ok, v, r, s} = ExW3.Contract.call(__MODULE__, :lastSignature) - {:ok, :binary.encode_unsigned(v) <> r <> s} + {:ok, r <> s <> :binary.encode_unsigned(v)} end def winner(), diff --git a/lib/ethereum/helpers.ex b/lib/ethereum/helpers.ex index caf8c5b..535aa6a 100644 --- a/lib/ethereum/helpers.ex +++ b/lib/ethereum/helpers.ex @@ -1,4 +1,5 @@ defmodule Ethereum.Helpers do + require Integer @address_size 20 def deploy(module_name, args \\ []) do @@ -91,7 +92,7 @@ defmodule Ethereum.Helpers do def sign(message, private_key) do message_size = byte_size(message) - message_hash = Crypto.hash("\x19Ethereum Signed Message:\n#{message_size}" <> message) + message_hash = Crypto.keccak256("\x19Ethereum Signed Message:\n#{message_size}" <> message) {:ok, signature, recovery_id} = :libsecp256k1.ecdsa_sign_compact(message_hash, private_key, :default, <<>>) @@ -105,9 +106,12 @@ defmodule Ethereum.Helpers do :binary.part(data, length - n, n) end - def hex_to_bytes("0x" <> hex), do: Base.decode16!(hex, case: :lower) + def hex_to_bytes("0x" <> hex), do: hex_to_bytes(hex) + def hex_to_bytes(hex) when Integer.is_odd(byte_size(hex)), + do: hex_to_bytes("0" <> hex) + def hex_to_bytes(hex), do: Base.decode16!(hex, case: :lower) def hex_to_int(hex), do: hex_to_bytes(hex) |> :binary.decode_unsigned() def bytes_to_hex(bytes), do: "0x" <> Base.encode16(bytes, case: :lower) - def abi_file_name(contract_name), do: Path.join(["priv", "ethereum_contracts", "#{contract_name}.abi"]) - defp bin_file_name(contract_name), do: Path.join(["priv", "ethereum_contracts", "#{contract_name}.bin"]) + def abi_file_name(contract_name), do: Application.app_dir(:blacksmith, ["priv", "ethereum_contracts", "#{contract_name}.abi"]) + defp bin_file_name(contract_name), do: Application.app_dir(:blacksmith, ["priv", "ethereum_contracts", "#{contract_name}.bin"]) end diff --git a/lib/models/block.ex b/lib/models/block.ex index cd7cd44..b295896 100644 --- a/lib/models/block.ex +++ b/lib/models/block.ex @@ -49,7 +49,7 @@ defmodule Models.Block do winner: winner, changeset_hash: changeset_hash } - + def as_cbor(block), do: Cbor.encode(as_map(block)) def forge(winner) do diff --git a/lib/redis.ex b/lib/redis.ex index 9770c10..b525b79 100644 --- a/lib/redis.ex +++ b/lib/redis.ex @@ -7,7 +7,8 @@ defmodule Redis do end def init(_args) do - {:ok, redis} = Redix.start_link() + connection_url = Application.fetch_env!(:blacksmith, :redis_url) + {:ok, redis} = Redix.start_link(connection_url) {:ok, redis} end diff --git a/lib/redis/pubsub.ex b/lib/redis/pubsub.ex index cedd4f1..edc8663 100644 --- a/lib/redis/pubsub.ex +++ b/lib/redis/pubsub.ex @@ -6,7 +6,8 @@ defmodule Redis.PubSub do end def init(_args) do - {:ok, pubsub} = Redix.PubSub.start_link() + connection_url = Application.fetch_env!(:blacksmith, :redis_url) + {:ok, pubsub} = Redix.PubSub.start_link(connection_url) channels = [ :transaction_processor @@ -33,8 +34,15 @@ defmodule Redis.PubSub do {:noreply, state} end + def handle_info({:redix_pubsub, _pid, _from, :subscribed, %{channel: _channel}}, state) do + {:noreply, state} + + end + + + def handle_info( - {:redix_pubsub, _pid, :message, %{channel: channel, payload: payload}}, + {:redix_pubsub, _pid, _from, :message, %{channel: channel, payload: payload}}, state = %{subscriptions: subscriptions, pubsub: _pubsub} ) do Enum.each(subscriptions[String.to_atom(channel)], fn subscriber -> diff --git a/lib/release/tasks.ex b/lib/release/tasks.ex new file mode 100644 index 0000000..d6b020a --- /dev/null +++ b/lib/release/tasks.ex @@ -0,0 +1,9 @@ +defmodule Release.Tasks do + def migrate do + {:ok, _} = Application.ensure_all_started(:blacksmith) + + path = Application.app_dir(:blacksmith, ["priv", "repo", "migrations"]) + + Ecto.Migrator.run(Blacksmith.Repo, path, :up, all: true) + end +end diff --git a/lib/router.ex b/lib/router.ex index b15c149..940c711 100644 --- a/lib/router.ex +++ b/lib/router.ex @@ -1,93 +1,93 @@ defmodule Router do - use Plug.Router - - if Mix.env() == :dev do - use Plug.Debugger, otp_app: :blacksmith - end - - alias Blacksmith.Plug.CBOR - alias HTTP.SignatureAuth - alias Models.Contract - alias Ethereum.Contracts.EllipticoinStakingContract - - plug(CORSPlug) - - plug(Plug.Parsers, - parsers: [CBOR], - body_reader: {CacheBodyReader, :read_body, []}, - cbor_decoder: Cbor - ) - - # plug( - # SignatureAuth, - # only_methods: ["POST", "PUT"] + # use Plug.Router + # + # if Mix.env() == :dev do + # use Plug.Debugger, otp_app: :blacksmith + # end + # + # alias Blacksmith.Plug.CBOR + # alias HTTP.SignatureAuth + # alias Models.Contract + # alias Ethereum.Contracts.EllipticoinStakingContract + # + # plug(CORSPlug) + # + # plug(Plug.Parsers, + # parsers: [CBOR], + # body_reader: {CacheBodyReader, :read_body, []}, + # cbor_decoder: Cbor # ) # - use Plug.ErrorHandler - - plug(:match) - plug(:dispatch) - - get "/:address/:contract_name" do - result = - conn - |> parse_get_request() - - {:ok, result} = Contract.get(result) - - send_resp(conn, 200, result) - end - - post "/nodes" do - P2P.add_peer(conn.params.url) - - send_resp(conn, 200, "") - end - - post "/blocks" do - {:ok, winner} = EllipticoinStakingContract.winner() - SignatureAuth.verify_block_signature(conn, winner) - - # Block.apply(conn.params) - send_resp(conn, 200, "") - end - - get "/blocks" do - _number = - if conn.query_params["number"] do - Integer.parse(conn.query_params["number"]) - else - nil - end - - send_resp(conn, 200, "{\"blocks\": []}") - end - - post "/transactions" do - SignatureAuth.verify_signature(conn) - - Contract.post(conn.params) - - send_resp(conn, 200, "") - end - - def parse_get_request(conn) do - params = Cbor.decode!(Base.decode16!(conn.query_params["params"])) - address = Base.decode16!(conn.path_params["address"], case: :lower) - - %{ - address: address, - method: String.to_atom(conn.query_params["method"]), - params: params, - contract_name: conn.path_params["contract_name"] - } - end - - match _ do - send_resp(conn, 404, "Not Found") - end - - def handle_errors(conn, %{kind: _kind, reason: _reason, stack: _stack}) do - send_resp(conn, conn.status, "") - end + # # plug( + # # SignatureAuth, + # # only_methods: ["POST", "PUT"] + # # ) + # # + # use Plug.ErrorHandler + # + # plug(:match) + # plug(:dispatch) + # + # get "/:address/:contract_name" do + # result = + # conn + # |> parse_get_request() + # + # {:ok, result} = Contract.get(result) + # + # send_resp(conn, 200, result) + # end + # + # post "/nodes" do + # P2P.add_peer(conn.params.url) + # + # send_resp(conn, 200, "") + # end + # + # post "/blocks" do + # {:ok, winner} = EllipticoinStakingContract.winner() + # SignatureAuth.verify_block_signature(conn, winner) + # + # # Block.apply(conn.params) + # send_resp(conn, 200, "") + # end + # + # get "/blocks" do + # _number = + # if conn.query_params["number"] do + # Integer.parse(conn.query_params["number"]) + # else + # nil + # end + # + # send_resp(conn, 200, "{\"blocks\": []}") + # end + # + # post "/transactions" do + # SignatureAuth.verify_signature(conn) + # + # Contract.post(conn.params) + # + # send_resp(conn, 200, "") + # end + # + # def parse_get_request(conn) do + # params = Cbor.decode!(Base.decode16!(conn.query_params["params"])) + # address = Base.decode16!(conn.path_params["address"], case: :lower) + # + # %{ + # address: address, + # method: String.to_atom(conn.query_params["method"]), + # params: params, + # contract_name: conn.path_params["contract_name"] + # } + # end + # + # match _ do + # send_resp(conn, 404, "Not Found") + # end + # + # def handle_errors(conn, %{kind: _kind, reason: _reason, stack: _stack}) do + # send_resp(conn, conn.status, "") + # end end diff --git a/lib/staking_contract_monitor.ex b/lib/staking_contract_monitor.ex index 0ff38c9..298ae37 100644 --- a/lib/staking_contract_monitor.ex +++ b/lib/staking_contract_monitor.ex @@ -37,6 +37,7 @@ defmodule StakingContractMonitor do Logger.info "Winner: #{Ethereum.Helpers.bytes_to_hex(winner)}" if winner == Ethereum.Helpers.my_ethereum_address() do + Logger.info("Won block #{Ethereum.Helpers.hex_to_int(number)}") {:ok, block} = Block.forge(winner) P2P.broadcast_block(block) submit_block(block) @@ -54,14 +55,16 @@ defmodule StakingContractMonitor do ethereum_address = ethereum_private_key |> Ethereum.Helpers.address_from_private_key() |> Ethereum.Helpers.bytes_to_hex() + last_signature = EllipticoinStakingContract.last_signature() + |> ok + IO.inspect (last_signature |> Base.encode16(case: :lower)), label: "last signature" {:ok, signature} = EllipticoinStakingContract.last_signature() |> ok |> Ethereum.Helpers.sign(ethereum_private_key) EllipticoinStakingContract.submit_block( block.block_hash, - signature, - ethereum_address + signature ) end end diff --git a/lib/transaction_processor.ex b/lib/transaction_processor.ex index a08c752..263ed75 100644 --- a/lib/transaction_processor.ex +++ b/lib/transaction_processor.ex @@ -10,10 +10,11 @@ defmodule TransactionProcessor do end def init(state) do - {:ok, redis} = Redix.start_link() + connection_url = Application.fetch_env!(:blacksmith, :redis_url) + {:ok, redis} = Redix.start_link(connection_url) Port.open({:spawn_executable, path_to_executable()}, - args: ["redis://127.0.0.1/"] + args: [connection_url] ) {:ok, @@ -52,9 +53,8 @@ defmodule TransactionProcessor do {:noreply, state} end - def path_to_executable() do - Path.expand("../priv/native/#{@crate}", __DIR__) - end + def path_to_executable(), do: + Application.app_dir(:blacksmith, ["priv", "native", @crate]) def mode() do if(Mix.env() == :prod, do: :release, else: :debug) diff --git a/mix.exs b/mix.exs index 4e31eeb..f4ed521 100644 --- a/mix.exs +++ b/mix.exs @@ -6,9 +6,10 @@ defmodule Blacksmith.Mixfile do app: :blacksmith, version: "0.1.0", elixir: "~> 1.7", - build_embedded: Mix.env() == :prod, + build_embedded: false, start_permanent: Mix.env() == :prod, compilers: [:rustler] ++ Mix.compilers(), + compilers: Mix.compilers(), rustler_crates: rustler_crates(), deps: deps(), elixirc_paths: elixirc_paths(Mix.env()) @@ -40,43 +41,43 @@ defmodule Blacksmith.Mixfile do defp extra_applications(:dev), do: extra_applications(:all) ++ [:remix] defp extra_applications(_all), do: [:cowboy, :ranch, :redix, :plug] + defp extra_applications(_all), do: [] defp deps do [ + {:abi, "~> 0.1"}, {:artificery, [env: :prod, github: "mana-ethereum/artificery", branch: "hayesgm/allow-extra-args", override: true]}, {:benchee, "~> 0.11", only: [:dev, :test]}, - {:cbor, "~> 0.1"}, - {:abi, "~> 0.1"}, + {:binary, "~> 0.0.5"}, {:bypass, "~> 0.8", only: :test}, + {:cbor, "~> 0.1"}, {:cors_plug, "~> 1.5"}, {:cowboy, "~> 2.3"}, {:dialyxir, "~> 1.0.0-rc.3", only: [:dev, :test], runtime: false}, {:distillery, "~> 2.0", runtime: false}, {:ecto, "~> 3.0"}, - {:websockex, [env: :prod, github: "mana-ethereum/websockex", branch: "master", override: true]}, + {:ecto_sql, "~> 3.0-rc.1"}, + {:ethereumex, + [github: "masonforest/ethereumex", branch: "websocket-client", override: true]}, {:ex_machina, "~> 2.2"}, - {:poison, "~> 4.0", override: true}, + {:exth_crypto, "~> 0.1.4", override: true}, + {:exw3, github: "masonforest/exw3", branch: "websocket-client"}, {:httpoison, "~> 1.3"}, + {:keccakf1600, hex: :keccakf1600_orig}, {:libsodium, "~> 0.0.10"}, - {:binary, "~> 0.0.5"}, + {:mana, [github: "mana-ethereum/mana", app: false]}, {:ok, "~> 2.0"}, {:plug, "~> 1.5"}, - {:ecto_sql, "~> 3.0-rc.1"}, - {:exw3, github: "masonforest/exw3", branch: "websocket-client"}, - {:keccakf1600, "~> 2.0.0", hex: :keccakf1600_orig}, + {:plug_cowboy, "~> 2.0"}, + {:poison, "~> 4.0", override: true}, {:postgrex, "~> 0.14.0"}, - {:exth_crypto, "~> 0.1.4", override: true}, - {:mana, [github: "mana-ethereum/mana", app: false]}, - {:ethereumex, - [github: "masonforest/ethereumex", branch: "websocket-client", override: true]}, {:redix, "0.8.0"}, - {:remix, "~> 0.0.1", only: :dev}, {:redix_pubsub, "~> 0.5.0"}, - {:plug_cowboy, "~> 2.0"}, - # Use [this branch](https://github.com/cristianberneanu/rustler) + {:remix, "~> 0.0.1", only: :dev}, # Until [this PR](https://github.com/hansihe/rustler/pull/166) is merged + # Use [this branch](https://github.com/cristianberneanu/rustler) {:rustler, [path: "./priv/rustler/rustler_mix", override: true]}, - + {:websockex, [env: :prod, github: "mana-ethereum/websockex", branch: "master", override: true]}, ] end end diff --git a/mix.lock b/mix.lock index d5198b7..10526f0 100644 --- a/mix.lock +++ b/mix.lock @@ -10,10 +10,10 @@ "certifi": {:hex, :certifi, "2.4.2", "75424ff0f3baaccfd34b1214184b6ef616d89e420b258bb0a5ea7d7bc628f7f0", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"}, "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"}, "cors_plug": {:hex, :cors_plug, "1.5.2", "72df63c87e4f94112f458ce9d25800900cc88608c1078f0e4faddf20933eda6e", [:mix], [{:plug, "~> 1.3 or ~> 1.4 or ~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, - "cowboy": {:hex, :cowboy, "2.6.0", "dc1ff5354c89e36a3e3ef8d10433396dcff0dcbb1d4223b58c64c2d51a6d88d9", [:rebar3], [{:cowlib, "~> 2.7.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"}, + "cowboy": {:hex, :cowboy, "2.6.1", "f2e06f757c337b3b311f9437e6e072b678fcd71545a7b2865bdaa154d078593f", [:rebar3], [{:cowlib, "~> 2.7.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"}, "cowlib": {:hex, :cowlib, "2.7.0", "3ef16e77562f9855a2605900cedb15c1462d76fb1be6a32fc3ae91973ee543d2", [:rebar3], [], "hexpm"}, "credo": {:hex, :credo, "1.0.0", "aaa40fdd0543a0cf8080e8c5949d8c25f0a24e4fc8c1d83d06c388f5e5e0ea42", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, - "db_connection": {:hex, :db_connection, "2.0.2", "440c05518b0bdca0469dafaf45403597430448c1281def14ef9ccaa41833ea1e", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm"}, + "db_connection": {:hex, :db_connection, "2.0.3", "b4e8aa43c100e16f122ccd6798cd51c48c79fd391c39d411f42b3cd765daccb0", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm"}, "decimal": {:hex, :decimal, "1.5.0", "b0433a36d0e2430e3d50291b1c65f53c37d56f83665b43d79963684865beab68", [:mix], [], "hexpm"}, "deep_merge": {:hex, :deep_merge, "0.2.0", "c1050fa2edf4848b9f556fba1b75afc66608a4219659e3311d9c9427b5b680b3", [:mix], [], "hexpm"}, "dialyxir": {:hex, :dialyxir, "1.0.0-rc.4", "71b42f5ee1b7628f3e3a6565f4617dfb02d127a0499ab3e72750455e986df001", [:mix], [{:erlex, "~> 0.1", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm"}, @@ -25,9 +25,9 @@ "ethereumex": {:git, "https://github.com/masonforest/ethereumex.git", "9895948bb829e92a27c111e3ffafb08ef28bb913", [branch: "websocket-client"]}, "ex_doc": {:hex, :ex_doc, "0.19.1", "519bb9c19526ca51d326c060cb1778d4a9056b190086a8c6c115828eaccea6cf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.7", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, "ex_machina": {:hex, :ex_machina, "2.2.2", "d84217a6fb7840ff771d2561b8aa6d74a0d8968e4b10ecc0d7e9890dc8fb1c6a", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm"}, - "ex_rlp": {:hex, :ex_rlp, "0.3.1", "190554f7b26f79734fc5a772241eec14a71b2e83576e43f451479feb017013e9", [:mix], [], "hexpm"}, + "ex_rlp": {:hex, :ex_rlp, "0.5.0", "4f3a042e819640d2b05e2ed478d464cbb9740bbbf97e03ac2667def7b023325e", [:mix], [], "hexpm"}, "exth_crypto": {:hex, :exth_crypto, "0.1.6", "8e636a9bcb75d8e32451be96e547a495121ed2178d078db294edb0f81f7cf2e8", [:mix], [{:binary, "~> 0.0.4", [hex: :binary, repo: "hexpm", optional: false]}, {:keccakf1600, "~> 2.0.0", [hex: :keccakf1600_orig, repo: "hexpm", optional: false]}, {:libsecp256k1, "~> 0.1.9", [hex: :libsecp256k1, repo: "hexpm", optional: false]}], "hexpm"}, - "exw3": {:git, "https://github.com/masonforest/exw3.git", "227b898316946599b601c18fe4614a533d98aeb8", [branch: "websocket-client"]}, + "exw3": {:git, "https://github.com/masonforest/exw3.git", "00ab15b05ebcee6bda4b9e61d90d650464d982a0", [branch: "websocket-client"]}, "hackney": {:hex, :hackney, "1.14.3", "b5f6f5dcc4f1fba340762738759209e21914516df6be440d85772542d4a5e412", [:rebar3], [{:certifi, "2.4.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, "httpoison": {:hex, :httpoison, "1.3.1", "7ac607311f5f706b44e8b3fab736d0737f2f62a31910ccd9afe7227b43edb7f0", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, "idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, @@ -37,7 +37,7 @@ "libsodium": {:hex, :libsodium, "0.0.10", "24584e6f5a60aed53542054c15fb31719bbf2d811d9a84f626734faf64d41304", [:rebar3], [], "hexpm"}, "makeup": {:hex, :makeup, "0.5.5", "9e08dfc45280c5684d771ad58159f718a7b5788596099bdfb0284597d368a882", [:mix], [{:nimble_parsec, "~> 0.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, "makeup_elixir": {:hex, :makeup_elixir, "0.10.0", "0f09c2ddf352887a956d84f8f7e702111122ca32fbbc84c2f0569b8b65cbf7fa", [:mix], [{:makeup, "~> 0.5.5", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"}, - "mana": {:git, "https://github.com/mana-ethereum/mana.git", "1a81f64a9d7ae6367d5dc62bab7c2b0af491ba53", []}, + "mana": {:git, "https://github.com/mana-ethereum/mana.git", "15958ecf47ca087132a36f14d3d7f00c37b61aa7", []}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, @@ -49,14 +49,14 @@ "plug_cowboy": {:hex, :plug_cowboy, "2.0.0", "ab0c92728f2ba43c544cce85f0f220d8d30fc0c90eaa1e6203683ab039655062", [:mix], [{:cowboy, "~> 2.5", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "plug_crypto": {:hex, :plug_crypto, "1.0.0", "18e49317d3fa343f24620ed22795ec29d4a5e602d52d1513ccea0b07d8ea7d4d", [:mix], [], "hexpm"}, "poison": {:hex, :poison, "4.0.1", "bcb755a16fac91cad79bfe9fc3585bb07b9331e50cfe3420a24bcc2d735709ae", [:mix], [], "hexpm"}, + "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"}, "postgrex": {:hex, :postgrex, "0.14.1", "63247d4a5ad6b9de57a0bac5d807e1c32d41e39c04b8a4156a26c63bcd8a2e49", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"}, "progress_bar": {:hex, :progress_bar, "1.7.0", "51f45955245a257b49ef8d85528bbfe2c307c58891aefe8dd8bcf6015e6c4482", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"}, - "ranch": {:hex, :ranch, "1.7.0", "9583f47160ca62af7f8d5db11454068eaa32b56eeadf984d4f46e61a076df5f2", [:rebar3], [], "hexpm"}, + "ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm"}, "redix": {:hex, :redix, "0.8.0", "4e5a849856b33fe1d6163afe1ca9345a03a134cbf0258e44251a8378ab647fec", [:mix], [], "hexpm"}, "redix_pubsub": {:hex, :redix_pubsub, "0.5.0", "ce238708d8c0c98a13e912e1d5ff093fc7958816e3cdffae5763c33a439f7701", [:mix], [{:redix, "~> 0.8", [hex: :redix, repo: "hexpm", optional: false]}], "hexpm"}, "remix": {:hex, :remix, "0.0.2", "f06115659d8ede8d725fae1708920ef73353a1b39efe6a232d2a38b1f2902109", [:mix], [], "hexpm"}, "rocksdb": {:hex, :rocksdb, "0.23.3", "1e088c3870265d4c037c4ca274c4153dae739ce48d3c6536230c6b22226ff44e", [:rebar3], [], "hexpm"}, - "rustler": {:git, "https://github.com/cristianberneanu/rustler.git", "344ab4f0949297aad789f18b58086bbdca1133d5", []}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"}, "telemetry": {:hex, :telemetry, "0.2.0", "5b40caa3efe4deb30fb12d7cd8ed4f556f6d6bd15c374c2366772161311ce377", [:mix], [], "hexpm"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"}, diff --git a/native/transaction_processor/src/main.rs b/native/transaction_processor/src/main.rs index 82a2271..88fbdb4 100644 --- a/native/transaction_processor/src/main.rs +++ b/native/transaction_processor/src/main.rs @@ -2,6 +2,7 @@ extern crate redis; extern crate vm; +use std::env; use std::sync::Arc; use std::{thread, time, process, io}; @@ -24,7 +25,10 @@ struct Ctx { impl Ctx { fn new() -> Ctx { - let client = Client::open("redis://localhost/").unwrap(); + let args: Vec = env::args().collect(); + let connection_string: &str = &args[1]; + println!("Connection string: {:?}", connection_string); + let client = Client::open(connection_string).unwrap(); Ctx { client: Arc::new(client), } diff --git a/rel/config.exs b/rel/config.exs index d3921ec..ce76415 100644 --- a/rel/config.exs +++ b/rel/config.exs @@ -2,7 +2,8 @@ # They can then be used by adding `plugin MyPlugin` to # either an environment, or release definition, where # `MyPlugin` is the name of the plugin module. -Path.join(["rel", "plugins", "*.exs"]) +~w(rel plugins *.exs) +|> Path.join() |> Path.wildcard() |> Enum.map(&Code.eval_file(&1)) @@ -13,7 +14,7 @@ use Mix.Releases.Config, default_environment: Mix.env() # For a full list of config options for both releases -# and environments, visit https://hexdocs.pm/distillery/configuration.html +# and environments, visit https://hexdocs.pm/distillery/config/distillery.html # You may define one or more environments in this file, @@ -30,13 +31,15 @@ environment :dev do # dev mode. set dev_mode: true set include_erts: false - set cookie: :"{=xwT[hRc}E0X~gPAxcuqAy.4h>W!XuC!9&gzC,Kz~P=9RQ6zw$U{$4]BB&I(6R;" + set cookie: :"p7Hr^:*uOm_{IzLCvOuTHc?JnCmtkdlE)Tq{6fabt@s)1kv`}0gTs<(42EE/`8._" end environment :prod do set include_erts: true set include_src: false - set cookie: :"OoVocNmmQX_A:)pO]%Q)VMZ0cf|:lW_!ow~ba@FJy30W&`K^DJ.x9be&%>gr^=Hm" + set cookie: :"|X^}BrYC6%BQYK;Y3o?jWJ]^hXR>0/zz)euGL&qq.V`tTE|HD6EZxr_CtEdPlfsF" + set vm_args: "rel/vm.args" + set pre_start_hooks: "rel/hooks/pre_start" end # You may define one or more releases in this file. @@ -47,10 +50,15 @@ end release :blacksmith do set version: current_version(:blacksmith) set applications: [ - :runtime_tools, - :cbor, - :libsodium, - :rustler, + :crypto, + :libsecp256k1, + :runtime_tools + ] + set config_providers: [ + {Mix.Releases.Config.Providers.Elixir, ["${RELEASE_ROOT_DIR}/etc/config.exs"]} + ] + set overlays: [ + {:copy, "rel/config/config.exs", "etc/config.exs"} ] end diff --git a/rel/config/config.exs b/rel/config/config.exs new file mode 100644 index 0000000..85ba32f --- /dev/null +++ b/rel/config/config.exs @@ -0,0 +1,20 @@ +use Mix.Config + +config :blacksmith, base_contracts_path: "./base_contracts" +config :blacksmith, port: String.to_integer(System.get_env("PORT") || "4045") + +config :blacksmith, + staking_contract_address: + (System.get_env("STAKING_CONTRACT_ADDRESS") || "") |> Base.decode16!(case: :mixed) + +config :ethereumex, :web3_url, System.get_env("WEB3_URL") +config :ethereumex, :client_type, :websocket +config :blacksmith, private_key: (System.get_env("ETHEREUM_PRIVATE_KEY") || "") |> Base.decode16!() + +config :blacksmith, :redis_url, System.get_env("REDIS_URL") +config :blacksmith, Blacksmith.Repo, + username: System.get_env("POSTGRES_USER"), + password: System.get_env("POSTGRES_PASS"), + database: System.get_env("POSTGRES_DB"), + hostname: System.get_env("POSTGRES_HOST"), + pool_size: 15 diff --git a/rel/hooks/pre_start/echo.sh b/rel/hooks/pre_start/echo.sh new file mode 100755 index 0000000..a0bbc3f --- /dev/null +++ b/rel/hooks/pre_start/echo.sh @@ -0,0 +1 @@ +echo "we're starting!" diff --git a/rel/hooks/pre_start/wait_for_postgres b/rel/hooks/pre_start/wait_for_postgres new file mode 100755 index 0000000..7e33bc4 --- /dev/null +++ b/rel/hooks/pre_start/wait_for_postgres @@ -0,0 +1,5 @@ +until psql -h postgres -U "postgres" -c '\q' 2>/dev/null; do + >&2 echo "Postgres is unavailable - sleeping" + sleep 1 +done +echo "Successfully connected to Postgres" diff --git a/rel/plugins/.gitignore b/rel/plugins/.gitignore new file mode 100644 index 0000000..4fa3b5c --- /dev/null +++ b/rel/plugins/.gitignore @@ -0,0 +1,3 @@ +*.* +!*.exs +!.gitignore \ No newline at end of file diff --git a/rel/vm.args b/rel/vm.args new file mode 100644 index 0000000..93f34bb --- /dev/null +++ b/rel/vm.args @@ -0,0 +1,30 @@ +## This file provide the arguments provided to the VM at startup +## You can find a full list of flags and their behaviours at +## http://erlang.org/doc/man/erl.html + +## Name of the node +-name <%= release_name %>@127.0.0.1 + +## Cookie for distributed erlang +-setcookie <%= release.profile.cookie %> + +## Heartbeat management; auto-restarts VM if it dies or becomes unresponsive +## (Disabled by default..use with caution!) +##-heart + +## Enable kernel poll and a few async threads +##+K true +##+A 5 +## For OTP21+, the +A flag is not used anymore, +## +SDio replace it to use dirty schedulers +##+SDio 5 + +## Increase number of concurrent ports/sockets +##-env ERL_MAX_PORTS 4096 + +## Tweak GC to run more often +##-env ERL_FULLSWEEP_AFTER 10 + +# Enable SMP automatically based on availability +# On OTP21+, this is not needed anymore. +-smp auto diff --git a/submit_block.exs b/submit_block.exs new file mode 100644 index 0000000..22bbabe --- /dev/null +++ b/submit_block.exs @@ -0,0 +1,40 @@ +block_hash = Base.decode16!("D2F673028681EA277726AC3AFF96B4B3E4606551B66BCE1A61A2832171475634") + +<> = + Base.decode16!( + "13CCB1C4E01E76D4421A316FF8D7A175E9D77FB9285A62389B1E590F9F603AA6057CF3A933DA29E7ECFD69CD0C9CBAE696646D3959DFBEBF4D483930E5EBA01201" + ) + +abi_encoded_data = ABI.encode("submitBlock(bytes32,uint8,bytes32,bytes32)", [block_hash, v, r, s]) +contract_address = Application.fetch_env!(:blacksmith, :staking_contract_address) +ethereum_private_key = Application.fetch_env!(:blacksmith, :ethereum_private_key) + +# IO.inspect contract_address |> Base.encode16, label: "contract address" +# IO.inspect v, label: "v" +# IO.inspect r |> Base.encode16, label: "r" +# IO.inspect s |> Base.encode16, label: "s" +# IO.inspect block_hash |> Base.encode16, label: "block_hash" + +{:ok, transaction_count} = + Ethereumex.WebSocketClient.eth_get_transaction_count( + Ethereum.Helpers.bytes_to_hex(Ethereum.Helpers.my_ethereum_address()) + ) + +# IO.inspect (Ethereum.Helpers.hex_to_int(transaction_count) + 1), label: "noce" +transaction_data = + %Blockchain.Transaction{ + data: abi_encoded_data, + gas_price: 20_000_000_000, + gas_limit: 4_712_388, + data: abi_encoded_data, + nonce: Ethereum.Helpers.hex_to_int(transaction_count), + to: contract_address, + value: 0 + } + |> Blockchain.Transaction.Signature.sign_transaction(ethereum_private_key) + |> Blockchain.Transaction.serialize() + |> ExRLP.encode() + |> Base.encode16(case: :lower) + +IO.puts("0x" <> transaction_data) +IO.inspect(Ethereumex.WebSocketClient.eth_send_raw_transaction("0x" <> transaction_data))