From 11bcecad9638f4f65b93a31adb5bb8b76dbecbce Mon Sep 17 00:00:00 2001 From: Luke Imhoff Date: Mon, 14 May 2018 13:44:08 -0500 Subject: [PATCH] Explorer.JSONRPC -> EthereumJSONRPC Extract Explorer.JSONRPC to its own OTP application, apps/ethereum_jsonrpc. It is not ready to be a completely separate library because it knowns the internal params format used for Explorer.Chain. --- apps/ethereum_jsonrpc/README.md | 33 +- apps/ethereum_jsonrpc/config/config.exs | 30 +- apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex | 301 ++++++++++++++++- .../lib/ethereum_jsonrpc/application.ex | 16 + .../lib/ethereum_jsonrpc}/block.ex | 60 ++-- .../lib/ethereum_jsonrpc}/blocks.ex | 12 +- .../lib/ethereum_jsonrpc}/log.ex | 20 +- .../lib/ethereum_jsonrpc}/logs.ex | 4 +- .../lib/ethereum_jsonrpc}/parity.ex | 8 +- .../lib/ethereum_jsonrpc}/parity/trace.ex | 22 +- .../ethereum_jsonrpc}/parity/trace/action.ex | 12 +- .../ethereum_jsonrpc}/parity/trace/result.ex | 10 +- .../lib/ethereum_jsonrpc}/parity/traces.ex | 4 +- .../lib/ethereum_jsonrpc}/receipt.ex | 46 +-- .../lib/ethereum_jsonrpc}/receipts.ex | 12 +- .../lib/ethereum_jsonrpc}/transaction.ex | 63 ++-- .../lib/ethereum_jsonrpc}/transactions.ex | 10 +- apps/ethereum_jsonrpc/mix.exs | 44 ++- .../test/ethereum_jsonrpc/block_test.exs | 5 + .../test/ethereum_jsonrpc/blocks_test.exs | 5 + .../test/ethereum_jsonrpc/log_test.exs | 5 + .../parity/trace/action_test.exs | 5 + .../parity/trace/result_test.exs | 5 + .../ethereum_jsonrpc/parity/trace_test.exs | 5 + .../test/ethereum_jsonrpc/parity_test.exs | 5 + .../test/ethereum_jsonrpc/receipt_test.exs | 5 + .../test/ethereum_jsonrpc}/receipts_test.exs | 6 +- .../ethereum_jsonrpc/transaction_test.exs | 5 + .../ethereum_jsonrpc/transactions_test.exs | 5 + .../test/ethereum_jsonrpc_test.exs | 8 - apps/ethereum_jsonrpc/test/test_helper.exs | 6 + apps/explorer/config/config.exs | 5 - apps/explorer/lib/explorer/application.ex | 1 - .../lib/explorer/indexer/address_fetcher.ex | 11 +- .../lib/explorer/indexer/block_fetcher.ex | 11 +- apps/explorer/lib/explorer/jsonrpc.ex | 309 ------------------ apps/explorer/mix.exs | 2 + .../explorer/indexer/address_fetcher_test.exs | 2 - .../explorer/indexer/block_fetcher_test.exs | 3 - .../test/explorer/jsonrpc/block_test.exs | 5 - .../test/explorer/jsonrpc/blocks_test.exs | 5 - .../test/explorer/jsonrpc/log_test.exs | 5 - .../jsonrpc/parity/trace/action_test.exs | 5 - .../jsonrpc/parity/trace/result_test.exs | 5 - .../explorer/jsonrpc/parity/trace_test.exs | 5 - .../test/explorer/jsonrpc/parity_test.exs | 5 - .../test/explorer/jsonrpc/receipt_test.exs | 5 - .../explorer/jsonrpc/transaction_test.exs | 5 - .../explorer/jsonrpc/transactions_test.exs | 5 - coveralls.json | 2 +- 50 files changed, 595 insertions(+), 578 deletions(-) create mode 100644 apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/application.ex rename apps/{explorer/lib/explorer/jsonrpc => ethereum_jsonrpc/lib/ethereum_jsonrpc}/block.ex (90%) rename apps/{explorer/lib/explorer/jsonrpc => ethereum_jsonrpc/lib/ethereum_jsonrpc}/blocks.ex (98%) rename apps/{explorer/lib/explorer/jsonrpc => ethereum_jsonrpc/lib/ethereum_jsonrpc}/log.ex (85%) rename apps/{explorer/lib/explorer/jsonrpc => ethereum_jsonrpc/lib/ethereum_jsonrpc}/logs.ex (88%) rename apps/{explorer/lib/explorer/jsonrpc => ethereum_jsonrpc/lib/ethereum_jsonrpc}/parity.ex (97%) rename apps/{explorer/lib/explorer/jsonrpc => ethereum_jsonrpc/lib/ethereum_jsonrpc}/parity/trace.ex (98%) rename apps/{explorer/lib/explorer/jsonrpc => ethereum_jsonrpc/lib/ethereum_jsonrpc}/parity/trace/action.ex (93%) rename apps/{explorer/lib/explorer/jsonrpc => ethereum_jsonrpc/lib/ethereum_jsonrpc}/parity/trace/result.ex (91%) rename apps/{explorer/lib/explorer/jsonrpc => ethereum_jsonrpc/lib/ethereum_jsonrpc}/parity/traces.ex (85%) rename apps/{explorer/lib/explorer/jsonrpc => ethereum_jsonrpc/lib/ethereum_jsonrpc}/receipt.ex (78%) rename apps/{explorer/lib/explorer/jsonrpc => ethereum_jsonrpc/lib/ethereum_jsonrpc}/receipts.ex (97%) rename apps/{explorer/lib/explorer/jsonrpc => ethereum_jsonrpc/lib/ethereum_jsonrpc}/transaction.ex (70%) rename apps/{explorer/lib/explorer/jsonrpc => ethereum_jsonrpc/lib/ethereum_jsonrpc}/transactions.ex (98%) create mode 100644 apps/ethereum_jsonrpc/test/ethereum_jsonrpc/block_test.exs create mode 100644 apps/ethereum_jsonrpc/test/ethereum_jsonrpc/blocks_test.exs create mode 100644 apps/ethereum_jsonrpc/test/ethereum_jsonrpc/log_test.exs create mode 100644 apps/ethereum_jsonrpc/test/ethereum_jsonrpc/parity/trace/action_test.exs create mode 100644 apps/ethereum_jsonrpc/test/ethereum_jsonrpc/parity/trace/result_test.exs create mode 100644 apps/ethereum_jsonrpc/test/ethereum_jsonrpc/parity/trace_test.exs create mode 100644 apps/ethereum_jsonrpc/test/ethereum_jsonrpc/parity_test.exs create mode 100644 apps/ethereum_jsonrpc/test/ethereum_jsonrpc/receipt_test.exs rename apps/{explorer/test/explorer/jsonrpc => ethereum_jsonrpc/test/ethereum_jsonrpc}/receipts_test.exs (92%) create mode 100644 apps/ethereum_jsonrpc/test/ethereum_jsonrpc/transaction_test.exs create mode 100644 apps/ethereum_jsonrpc/test/ethereum_jsonrpc/transactions_test.exs delete mode 100644 apps/ethereum_jsonrpc/test/ethereum_jsonrpc_test.exs delete mode 100644 apps/explorer/lib/explorer/jsonrpc.ex delete mode 100644 apps/explorer/test/explorer/jsonrpc/block_test.exs delete mode 100644 apps/explorer/test/explorer/jsonrpc/blocks_test.exs delete mode 100644 apps/explorer/test/explorer/jsonrpc/log_test.exs delete mode 100644 apps/explorer/test/explorer/jsonrpc/parity/trace/action_test.exs delete mode 100644 apps/explorer/test/explorer/jsonrpc/parity/trace/result_test.exs delete mode 100644 apps/explorer/test/explorer/jsonrpc/parity/trace_test.exs delete mode 100644 apps/explorer/test/explorer/jsonrpc/parity_test.exs delete mode 100644 apps/explorer/test/explorer/jsonrpc/receipt_test.exs delete mode 100644 apps/explorer/test/explorer/jsonrpc/transaction_test.exs delete mode 100644 apps/explorer/test/explorer/jsonrpc/transactions_test.exs diff --git a/apps/ethereum_jsonrpc/README.md b/apps/ethereum_jsonrpc/README.md index adcc1c460d..d546954ce5 100644 --- a/apps/ethereum_jsonrpc/README.md +++ b/apps/ethereum_jsonrpc/README.md @@ -1,21 +1,36 @@ -# EthereumJsonrpc +# EthereumJSONRPC -**TODO: Add description** +Ethereum JSONRPC client. + +## Configuration + +Configuration for parity URLs can be provided with the following mix +config: + +```elixir +config :ethereum_jsonrpc, + url: "https://sokol.poa.network", + trace_url: "https://sokol-trace.poa.network", + http: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] +``` + +Note: the tracing node URL is provided separately from `:url`, +via `:trace_url`. The trace URL and is used for +`fetch_internal_transactions`, which is only a supported method on +tracing nodes. The `:http` option is passed directly to the HTTP +library (`HTTPoison`), which forwards the options down to `:hackney`. ## Installation -If [available in Hex](https://hex.pm/docs/publish), the package can be installed -by adding `ethereum_jsonrpc` to your list of dependencies in `mix.exs`: +The OTP application `:ethereum_jsonrpc` can be used in other umbrella +OTP applications by adding `ethereum_jsonrpc` to your list of +dependencies in `mix.exs`: ```elixir def deps do [ - {:ethereum_jsonrpc, "~> 0.1.0"} + {:ethereum_jsonrpc, in_umbrella: true} ] end ``` -Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) -and published on [HexDocs](https://hexdocs.pm). Once published, the docs can -be found at [https://hexdocs.pm/ethereum_jsonrpc](https://hexdocs.pm/ethereum_jsonrpc). - diff --git a/apps/ethereum_jsonrpc/config/config.exs b/apps/ethereum_jsonrpc/config/config.exs index 828d6537f6..a1c766314a 100644 --- a/apps/ethereum_jsonrpc/config/config.exs +++ b/apps/ethereum_jsonrpc/config/config.exs @@ -2,29 +2,7 @@ # and its dependencies with the aid of the Mix.Config module. use Mix.Config -# This configuration is loaded before any dependency and is restricted -# to this project. If another project depends on this project, this -# file won't be loaded nor affect the parent project. For this reason, -# if you want to provide default values for your application for -# 3rd-party users, it should be done in your "mix.exs" file. - -# You can configure your application as: -# -# config :ethereum_jsonrpc, key: :value -# -# and access this configuration in your application as: -# -# Application.get_env(:ethereum_jsonrpc, :key) -# -# You can also configure a 3rd-party app: -# -# config :logger, level: :info -# - -# It is also possible to import configuration files, relative to this -# directory. For example, you can emulate configuration per environment -# by uncommenting the line below and defining dev.exs, test.exs and such. -# Configuration from the imported file will override the ones defined -# here (which is why it is important to import them last). -# -# import_config "#{Mix.env}.exs" +config :ethereum_jsonrpc, + http: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]], + trace_url: "https://sokol-trace.poa.network", + url: "https://sokol.poa.network" diff --git a/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex index 82c7b2b45a..5e282cd5d8 100644 --- a/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex @@ -1,18 +1,303 @@ -defmodule EthereumJsonrpc do +defmodule EthereumJSONRPC do @moduledoc """ - Documentation for EthereumJsonrpc. + Ethereum JSONRPC client. + + ## Configuration + + Configuration for parity URLs can be provided with the following mix config: + + config :ethereum_jsonrpc, + url: "https://sokol.poa.network", + trace_url: "https://sokol-trace.poa.network", + http: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] + + Note: the tracing node URL is provided separately from `:url`, via `:trace_url`. The trace URL and is used for + `fetch_internal_transactions`, which is only a supported method on tracing nodes. The `:http` option is passed + directly to the HTTP library (`HTTPoison`), which forwards the options down to `:hackney`. + """ + + require Logger + + alias EthereumJSONRPC.{Blocks, Parity, Receipts, Transactions} + + @typedoc """ + Truncated 20-byte [KECCAK-256](https://en.wikipedia.org/wiki/SHA-3) hash encoded as a hexadecimal number in a + `String.t`. + """ + @type address :: String.t() + + @typedoc """ + Binary data encoded as a single hexadecimal number in a `String.t` """ + @type data :: String.t() + + @typedoc """ + A full 32-byte [KECCAK-256](https://en.wikipedia.org/wiki/SHA-3) hash encoded as a hexadecimal number in a `String.t` + + ## Example + + "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" + + """ + @type hash :: String.t() + + @typedoc """ + 8 byte [KECCAK-256](https://en.wikipedia.org/wiki/SHA-3) hash of the proof-of-work. + """ + @type nonce :: String.t() + + @typedoc """ + A number encoded as a hexadecimal number in a `String.t` + + ## Example + + "0x1b4" + + """ + @type quantity :: String.t() + + @typedoc """ + Unix timestamp encoded as a hexadecimal number in a `String.t` + """ + @type timestamp :: String.t() @doc """ - Hello world. + Lists changes for a given filter subscription. + """ + def check_for_updates(filter_id) do + request = %{ + "id" => filter_id, + "jsonrpc" => "2.0", + "method" => "eth_getFilterChanges", + "params" => [filter_id] + } - ## Examples + json_rpc(request, config(:url)) + end - iex> EthereumJsonrpc.hello - :world + @doc """ + Fetches configuration for this module under `key` + Configuration can be set a compile time using `config` + + config :ethereume_jsonrpc, key, value + + Configuration can be set a runtime using `Application.put_env/3` + + Application.put_env(:ethereume_jsonrpc, key, value) + + """ + def config(key) do + Application.fetch_env!(:ethereum_jsonrpc, key) + end + + @doc """ + Fetches address balances by address hashes. + """ + def fetch_balances_by_hash(address_hashes) do + batched_requests = + for hash <- address_hashes do + %{ + "id" => hash, + "jsonrpc" => "2.0", + "method" => "eth_getBalance", + "params" => [hash, "latest"] + } + end + + batched_requests + |> json_rpc(config(:url)) + |> handle_balances() + end + + defp handle_balances({:ok, results}) do + native_results = + for response <- results, into: %{} do + {response["id"], hexadecimal_to_integer(response["result"])} + end + + {:ok, native_results} + end + + defp handle_balances({:error, _reason} = err), do: err + + @doc """ + Fetches blocks by block hashes. + + Transaction data is included for each block. """ - def hello do - :world + def fetch_blocks_by_hash(block_hashes) do + batched_requests = + for block_hash <- block_hashes do + %{ + "id" => block_hash, + "jsonrpc" => "2.0", + "method" => "eth_getBlockByHash", + "params" => [block_hash, true] + } + end + + batched_requests + |> json_rpc(config(:url)) + |> handle_get_block_by_number() + |> case do + {:ok, _next, results} -> {:ok, results} + {:error, reason} -> {:error, reason} + end end + + @doc """ + Fetches blocks by block number range. + """ + def fetch_blocks_by_range(block_start, block_end) do + block_start + |> build_batch_get_block_by_number(block_end) + |> json_rpc(config(:url)) + |> handle_get_block_by_number() + end + + @doc """ + Fetches internal transactions from client-specific API. + """ + def fetch_internal_transactions(hashes) when is_list(hashes) do + Parity.fetch_internal_transactions(hashes) + end + + def fetch_transaction_receipts(hashes) when is_list(hashes) do + Receipts.fetch(hashes) + end + + @doc """ + 1. POSTs JSON `payload` to `url` + 2. Decodes the response + 3. Handles the response + + ## Returns + + * Handled response + * `{:error, reason}` if POST failes + """ + def json_rpc(payload, url) do + json = encode_json(payload) + headers = [{"Content-Type", "application/json"}] + + case HTTPoison.post(url, json, headers, config(:http)) do + {:ok, %HTTPoison.Response{body: body, status_code: code}} -> + body |> decode_json(payload, url) |> handle_response(code) + + {:error, %HTTPoison.Error{reason: reason}} -> + {:error, reason} + end + end + + @doc """ + Creates a filter subscription that can be polled for retreiving new blocks. + """ + def listen_for_new_blocks do + id = DateTime.utc_now() |> DateTime.to_unix() + + request = %{ + "id" => id, + "jsonrpc" => "2.0", + "method" => "eth_newBlockFilter", + "params" => [] + } + + json_rpc(request, config(:url)) + end + + @doc """ + Converts `t:nonce/0` to `t:non_neg_integer/0` + """ + def nonce_to_integer(nonce) do + hexadecimal_to_integer(nonce) + end + + @doc """ + Converts `t:quantity/0` to `t:non_neg_integer/0`. + """ + def quantity_to_integer(quantity) do + hexadecimal_to_integer(quantity) + end + + @doc """ + Converts `t:timestamp/0` to `t:DateTime.t/0` + """ + def timestamp_to_datetime(timestamp) do + timestamp + |> hexadecimal_to_integer() + |> Timex.from_unix() + end + + defp build_batch_get_block_by_number(block_start, block_end) do + for current <- block_start..block_end do + %{ + "id" => current, + "jsonrpc" => "2.0", + "method" => "eth_getBlockByNumber", + "params" => [int_to_hash_string(current), true] + } + end + end + + defp encode_json(data), do: Jason.encode_to_iodata!(data) + + defp decode_json(body, posted_payload, url) do + Jason.decode!(body) + rescue + Jason.DecodeError -> + Logger.error(""" + failed to decode json payload: + + url: #{inspect(url)} + + body: #{inspect(body)} + + posted payload: #{inspect(posted_payload)} + + """) + + raise("bad jason") + end + + defp handle_get_block_by_number({:ok, results}) do + {blocks, next} = + Enum.reduce(results, {[], :more}, fn + %{"result" => nil}, {blocks, _} -> {blocks, :end_of_chain} + %{"result" => %{} = block}, {blocks, next} -> {[block | blocks], next} + end) + + elixir_blocks = Blocks.to_elixir(blocks) + elixir_transactions = Blocks.elixir_to_transactions(elixir_blocks) + blocks_params = Blocks.elixir_to_params(elixir_blocks) + transactions_params = Transactions.elixir_to_params(elixir_transactions) + + {:ok, next, + %{ + blocks: blocks_params, + transactions: transactions_params + }} + end + + defp handle_get_block_by_number({:error, reason}) do + {:error, reason} + end + + defp handle_response(resp, 200) do + case resp do + [%{} | _] = batch_resp -> {:ok, batch_resp} + %{"error" => error} -> {:error, error} + %{"result" => result} -> {:ok, result} + end + end + + defp handle_response(resp, _status) do + {:error, resp} + end + + defp hexadecimal_to_integer("0x" <> hexadecimal_digits) do + String.to_integer(hexadecimal_digits, 16) + end + + defp int_to_hash_string(number), do: "0x" <> Integer.to_string(number, 16) end diff --git a/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/application.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/application.ex new file mode 100644 index 0000000000..38c398e23c --- /dev/null +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/application.ex @@ -0,0 +1,16 @@ +defmodule EthereumJSONRPC.Application do + @moduledoc """ + Starts `:hackney_pool` `:ethereum_jsonrpc`. + """ + + use Application + + @impl Application + def start(_type, _args) do + children = [ + :hackney_pool.child_spec(:ethereum_jsonrpc, recv_timeout: 60_000, timeout: 60_000, max_connections: 1000) + ] + + Supervisor.start_link(children, strategy: :one_for_one, name: EthereumJSONRPC.Supervisor) + end +end diff --git a/apps/explorer/lib/explorer/jsonrpc/block.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/block.ex similarity index 90% rename from apps/explorer/lib/explorer/jsonrpc/block.ex rename to apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/block.ex index e26a2608f0..1fc387cbf1 100644 --- a/apps/explorer/lib/explorer/jsonrpc/block.ex +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/block.ex @@ -1,55 +1,55 @@ -defmodule Explorer.JSONRPC.Block do +defmodule EthereumJSONRPC.Block do @moduledoc """ Block format as returned by [`eth_getBlockByHash`](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getblockbyhash) and [`eth_getBlockByNumber`](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getblockbynumber). """ - import Explorer.JSONRPC, only: [nonce_to_integer: 1, quantity_to_integer: 1, timestamp_to_datetime: 1] + import EthereumJSONRPC, only: [nonce_to_integer: 1, quantity_to_integer: 1, timestamp_to_datetime: 1] - alias Explorer.JSONRPC - alias Explorer.JSONRPC.Transactions + alias EthereumJSONRPC + alias EthereumJSONRPC.Transactions @type elixir :: %{String.t() => non_neg_integer | DateTime.t() | String.t() | nil} @typedoc """ - * `"author"` - `t:Explorer.JSONRPC.address/0` that created the block. Aliased by `"miner"`. - * `"difficulty"` - `t:Explorer.JSONRPC.quantity/0`` of the difficulty for this block. - * `"extraData"` - the extra `t:Explorer.JSONRPC.data/0`` field of this block. - * `"gasLimit" - maximum gas `t:Explorer.JSONRPC.quantity/0`` in this block. - * `"gasUsed" - the total `t:Explorer.JSONRPC.quantity/0`` of gas used by all transactions in this block. - * `"hash"` - the `t:Explorer.JSONRPC.hash/0` of the block. - * `"logsBloom"` - `t:Explorer.JSONRPC.data/0`` for the [Bloom filter](https://en.wikipedia.org/wiki/Bloom_filter) + * `"author"` - `t:EthereumJSONRPC.address/0` that created the block. Aliased by `"miner"`. + * `"difficulty"` - `t:EthereumJSONRPC.quantity/0`` of the difficulty for this block. + * `"extraData"` - the extra `t:EthereumJSONRPC.data/0`` field of this block. + * `"gasLimit" - maximum gas `t:EthereumJSONRPC.quantity/0`` in this block. + * `"gasUsed" - the total `t:EthereumJSONRPC.quantity/0`` of gas used by all transactions in this block. + * `"hash"` - the `t:EthereumJSONRPC.hash/0` of the block. + * `"logsBloom"` - `t:EthereumJSONRPC.data/0`` for the [Bloom filter](https://en.wikipedia.org/wiki/Bloom_filter) for the logs of the block. `nil` when block is pending. - * `"miner"` - `t:Explorer.JSONRPC.address/0` of the beneficiary to whom the mining rewards were given. Aliased by + * `"miner"` - `t:EthereumJSONRPC.address/0` of the beneficiary to whom the mining rewards were given. Aliased by `"author"`. - * `"nonce"` - `t:Explorer.JSONRPC.nonce/0`. `nil` when its pending block. - * `"number"` - the block number `t:Explorer.JSONRPC.quantity/0`. `nil` when block is pending. - * `"parentHash" - the `t:Explorer.JSONRPC.hash/0` of the parent block. - * `"receiptsRoot"` - `t:Explorer.JSONRPC.hash/0` of the root of the receipts. + * `"nonce"` - `t:EthereumJSONRPC.nonce/0`. `nil` when its pending block. + * `"number"` - the block number `t:EthereumJSONRPC.quantity/0`. `nil` when block is pending. + * `"parentHash" - the `t:EthereumJSONRPC.hash/0` of the parent block. + * `"receiptsRoot"` - `t:EthereumJSONRPC.hash/0` of the root of the receipts. [trie](https://github.com/ethereum/wiki/wiki/Patricia-Tree) of the block. * `"sealFields"` - UNKNOWN - * `"sha3Uncles"` - `t:Explorer.JSONRPC.hash/0` of the + * `"sha3Uncles"` - `t:EthereumJSONRPC.hash/0` of the [uncles](https://bitcoin.stackexchange.com/questions/39329/in-ethereum-what-is-an-uncle-block) data in the block. * `"signature"` - UNKNOWN - * `"size"` - `t:Explorer.JSONRPC.quantity/0`` of bytes in this block - * `"stateRoot" - `t:Explorer.JSONRPC.hash/0` of the root of the final state + * `"size"` - `t:EthereumJSONRPC.quantity/0`` of bytes in this block + * `"stateRoot" - `t:EthereumJSONRPC.hash/0` of the root of the final state [trie](https://github.com/ethereum/wiki/wiki/Patricia-Tree) of the block. * `"step"` - UNKNOWN - * `"timestamp"`: the unix timestamp as a `t:Explorer.JSONRPC.quantity/0`` for when the block was collated. - * `"totalDifficulty" - `t:Explorer.JSONRPC.quantity/0`` of the total difficulty of the chain until this block. - * `"transactions"` - `t:list/0` of `t:Explorer.JSONRPC.Transaction.t/0`. - * `"transactionsRoot" - `t:Explorer.JSONRPC.hash/0` of the root of the transaction + * `"timestamp"`: the unix timestamp as a `t:EthereumJSONRPC.quantity/0`` for when the block was collated. + * `"totalDifficulty" - `t:EthereumJSONRPC.quantity/0`` of the total difficulty of the chain until this block. + * `"transactions"` - `t:list/0` of `t:EthereumJSONRPC.Transaction.t/0`. + * `"transactionsRoot" - `t:EthereumJSONRPC.hash/0` of the root of the transaction [trie](https://github.com/ethereum/wiki/wiki/Patricia-Tree) of the block. * `uncles`: `t:list/0` of [uncles](https://bitcoin.stackexchange.com/questions/39329/in-ethereum-what-is-an-uncle-block) - `t:Explorer.JSONRPC.hash/0`. + `t:EthereumJSONRPC.hash/0`. """ - @type t :: %{String.t() => JSONRPC.data() | JSONRPC.hash() | JSONRPC.quantity() | nil} + @type t :: %{String.t() => EthereumJSONRPC.data() | EthereumJSONRPC.hash() | EthereumJSONRPC.quantity() | nil} @doc """ Converts `t:elixir/0` format to params used in `Explorer.Chain`. - iex> Explorer.JSONRPC.Block.elixir_to_params( + iex> EthereumJSONRPC.Block.elixir_to_params( ...> %{ ...> "author" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", ...> "difficulty" => 340282366920938463463374607431465537093, @@ -125,9 +125,9 @@ defmodule Explorer.JSONRPC.Block do end @doc """ - Get `t:Explorer.JSONRPC.Transactions.elixir/0` from `t:elixir/0` + Get `t:EthereumJSONRPC.Transactions.elixir/0` from `t:elixir/0` - iex> Explorer.JSONRPC.Block.elixir_to_transactions( + iex> EthereumJSONRPC.Block.elixir_to_transactions( ...> %{ ...> "author" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", ...> "difficulty" => 340282366920938463463374607431768211454, @@ -211,7 +211,7 @@ defmodule Explorer.JSONRPC.Block do @doc """ Decodes the stringly typed numerical fields to `t:non_neg_integer/0` and the timestamps to `t:DateTime.t/0` - iex> Explorer.JSONRPC.Block.to_elixir( + iex> EthereumJSONRPC.Block.to_elixir( ...> %{ ...> "author" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", ...> "difficulty" => "0xfffffffffffffffffffffffffffffffe", @@ -278,7 +278,7 @@ defmodule Explorer.JSONRPC.Block do end # double check that no new keys are being missed by requiring explicit match for passthrough - # `t:Explorer.JSONRPC.address/0` and `t:Explorer.JSONRPC.hash/0` pass through as `Explorer.Chain` can verify correct + # `t:EthereumJSONRPC.address/0` and `t:EthereumJSONRPC.hash/0` pass through as `Explorer.Chain` can verify correct # hash format defp entry_to_elixir({key, _} = entry) when key in ~w(author extraData hash logsBloom miner parentHash receiptsRoot sealFields sha3Uncles signature diff --git a/apps/explorer/lib/explorer/jsonrpc/blocks.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/blocks.ex similarity index 98% rename from apps/explorer/lib/explorer/jsonrpc/blocks.ex rename to apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/blocks.ex index c0bcb09ed7..74f9bc5bd0 100644 --- a/apps/explorer/lib/explorer/jsonrpc/blocks.ex +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/blocks.ex @@ -1,10 +1,10 @@ -defmodule Explorer.JSONRPC.Blocks do +defmodule EthereumJSONRPC.Blocks do @moduledoc """ Blocks format as returned by [`eth_getBlockByHash`](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getblockbyhash) and [`eth_getBlockByNumber`](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getblockbynumber) from batch requests. """ - alias Explorer.JSONRPC.{Block, Transactions} + alias EthereumJSONRPC.{Block, Transactions} @type elixir :: [Block.elixir()] @type t :: [Block.t()] @@ -12,7 +12,7 @@ defmodule Explorer.JSONRPC.Blocks do @doc """ Converts `t:elixir/0` elements to params used by `Explorer.Chain.Block.changeset/2`. - iex> Explorer.JSONRPC.Blocks.elixir_to_params( + iex> EthereumJSONRPC.Blocks.elixir_to_params( ...> [ ...> %{ ...> "author" => "0x0000000000000000000000000000000000000000", @@ -64,9 +64,9 @@ defmodule Explorer.JSONRPC.Blocks do end @doc """ - Extracts the `t:Explorer.JSONRPC.Transactions.elixir/0` from the `t:elixir/0`. + Extracts the `t:EthereumJSONRPC.Transactions.elixir/0` from the `t:elixir/0`. - iex> Explorer.JSONRPC.Blocks.elixir_to_transactions([ + iex> EthereumJSONRPC.Blocks.elixir_to_transactions([ ...> %{ ...> "author" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", ...> "difficulty" => 340282366920938463463374607431768211454, @@ -150,7 +150,7 @@ defmodule Explorer.JSONRPC.Blocks do @doc """ Decodes the stringly typed numerical fields to `t:non_neg_integer/0` and the timestamps to `t:DateTime.t/0` - iex> Explorer.JSONRPC.Blocks.to_elixir( + iex> EthereumJSONRPC.Blocks.to_elixir( ...> [ ...> %{ ...> "author" => "0x0000000000000000000000000000000000000000", diff --git a/apps/explorer/lib/explorer/jsonrpc/log.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/log.ex similarity index 85% rename from apps/explorer/lib/explorer/jsonrpc/log.ex rename to apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/log.ex index c06a1f3c7d..34da3af457 100644 --- a/apps/explorer/lib/explorer/jsonrpc/log.ex +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/log.ex @@ -1,29 +1,29 @@ -defmodule Explorer.JSONRPC.Log do +defmodule EthereumJSONRPC.Log do @moduledoc """ Log included in return from [`eth_getTransactionReceipt`](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactionreceipt). """ - import Explorer.JSONRPC, only: [quantity_to_integer: 1] + import EthereumJSONRPC, only: [quantity_to_integer: 1] @type elixir :: %{String.t() => String.t() | [String.t()] | non_neg_integer()} @typedoc """ - * `"address"` - `t:Explorer.JSONRPC.address/0` from which event originated. - * `"blockHash"` - `t:Explorer.JSONRPC.hash/0` of the block this transaction is in. - * `"blockNumber"` - `t:Explorer.JSONRPC.quantity/0` for the block number this transaction is in. + * `"address"` - `t:EthereumJSONRPC.address/0` from which event originated. + * `"blockHash"` - `t:EthereumJSONRPC.hash/0` of the block this transaction is in. + * `"blockNumber"` - `t:EthereumJSONRPC.quantity/0` for the block number this transaction is in. * `"data"` - Data containing non-indexed log parameter - * `"logIndex"` - `t:Explorer.JSONRPC.quantity/0` of the event index positon in the block. + * `"logIndex"` - `t:EthereumJSONRPC.quantity/0` of the event index positon in the block. * `"topics"` - `t:list/0` of at most 4 32-byte topics. Topic 1-3 contains indexed parameters of the log. - * `"transactionHash"` - `t:Explorer.JSONRPC.hash/0` of the transaction - * `"transactionIndex"` - `t:Explorer.JSONRPC.quantity/0` for the index of the transaction in the block. + * `"transactionHash"` - `t:EthereumJSONRPC.hash/0` of the transaction + * `"transactionIndex"` - `t:EthereumJSONRPC.quantity/0` for the index of the transaction in the block. """ @type t :: %{String.t() => String.t() | [String.t()]} @doc """ Converts `t:elixir/0` format to params used in `Explorer.Chain`. - iex> Explorer.JSONRPC.Log.elixir_to_params( + iex> EthereumJSONRPC.Log.elixir_to_params( ...> %{ ...> "address" => "0x8bf38d4764929064f2d4d3a56520a76ab3df415b", ...> "blockHash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd", @@ -71,7 +71,7 @@ defmodule Explorer.JSONRPC.Log do @doc """ Decodes the stringly typed numerical fields to `t:non_neg_integer/0`. - iex> Explorer.JSONRPC.Log.to_elixir( + iex> EthereumJSONRPC.Log.to_elixir( ...> %{ ...> "address" => "0x8bf38d4764929064f2d4d3a56520a76ab3df415b", ...> "blockHash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd", diff --git a/apps/explorer/lib/explorer/jsonrpc/logs.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/logs.ex similarity index 88% rename from apps/explorer/lib/explorer/jsonrpc/logs.ex rename to apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/logs.ex index 591ee635aa..7c4720f79b 100644 --- a/apps/explorer/lib/explorer/jsonrpc/logs.ex +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/logs.ex @@ -1,10 +1,10 @@ -defmodule Explorer.JSONRPC.Logs do +defmodule EthereumJSONRPC.Logs do @moduledoc """ Collection of logs included in return from [`eth_getTransactionReceipt`](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactionreceipt). """ - alias Explorer.JSONRPC.Log + alias EthereumJSONRPC.Log @type elixir :: [Log.elixir()] @type t :: [Log.t()] diff --git a/apps/explorer/lib/explorer/jsonrpc/parity.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/parity.ex similarity index 97% rename from apps/explorer/lib/explorer/jsonrpc/parity.ex rename to apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/parity.ex index f5ecde2afd..7bebac6ba6 100644 --- a/apps/explorer/lib/explorer/jsonrpc/parity.ex +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/parity.ex @@ -1,16 +1,16 @@ -defmodule Explorer.JSONRPC.Parity do +defmodule EthereumJSONRPC.Parity do @moduledoc """ Ethereum JSONRPC methods that are only supported by [Parity](https://wiki.parity.io/). """ - import Explorer.JSONRPC, only: [config: 1, json_rpc: 2] + import EthereumJSONRPC, only: [config: 1, json_rpc: 2] - alias Explorer.JSONRPC.Parity.Traces + alias EthereumJSONRPC.Parity.Traces @doc """ Fetches the `t:Explorer.Chain.InternalTransaction.changeset/2` params from the Parity trace URL. - iex> Explorer.JSONRPC.Parity.fetch_internal_transactions([ + iex> EthereumJSONRPC.Parity.fetch_internal_transactions([ ...> "0x0fa6f723216dba694337f9bb37d8870725655bdf2573526a39454685659e39b1" ...> ]) {:ok, diff --git a/apps/explorer/lib/explorer/jsonrpc/parity/trace.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/parity/trace.ex similarity index 98% rename from apps/explorer/lib/explorer/jsonrpc/parity/trace.ex rename to apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/parity/trace.ex index 43922fcc76..42851cb28f 100644 --- a/apps/explorer/lib/explorer/jsonrpc/parity/trace.ex +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/parity/trace.ex @@ -1,16 +1,16 @@ -defmodule Explorer.JSONRPC.Parity.Trace do +defmodule EthereumJSONRPC.Parity.Trace do @moduledoc """ Trace returned by [`trace_replayTransaction`](https://wiki.parity.io/JSONRPC-trace-module.html#trace_replaytransaction), which is an extension to the Ethereum JSONRPC standard that is only supported by [Parity](https://wiki.parity.io/). """ - alias Explorer.JSONRPC.Parity.Trace.{Action, Result} + alias EthereumJSONRPC.Parity.Trace.{Action, Result} @doc """ Create type traces are generated when a contract is created. - iex> Explorer.JSONRPC.Parity.Trace.elixir_to_params( + iex> EthereumJSONRPC.Parity.Trace.elixir_to_params( ...> %{ ...> "action" => %{ ...> "from" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", @@ -46,7 +46,7 @@ defmodule Explorer.JSONRPC.Parity.Trace do A create can fail due to a Bad Instruction in the `init` that is meant to form the `code` of the contract - iex> Explorer.JSONRPC.Parity.Trace.elixir_to_params( + iex> EthereumJSONRPC.Parity.Trace.elixir_to_params( ...> %{ ...> "action" => %{ ...> "from" => "0x78a42d3705fb3c26a4b54737a784bf064f0815fb", @@ -76,7 +76,7 @@ defmodule Explorer.JSONRPC.Parity.Trace do Call type traces are generated when a method is called. Calls are further divided by call type. - iex> Explorer.JSONRPC.Parity.Trace.elixir_to_params( + iex> EthereumJSONRPC.Parity.Trace.elixir_to_params( ...> %{ ...> "action" => %{ ...> "callType" => "call", @@ -113,7 +113,7 @@ defmodule Explorer.JSONRPC.Parity.Trace do Calls can error and be reverted - iex> Explorer.JSONRPC.Parity.Trace.elixir_to_params( + iex> EthereumJSONRPC.Parity.Trace.elixir_to_params( ...> %{ ...> "action" => %{ ...> "callType" => "call", @@ -153,7 +153,7 @@ defmodule Explorer.JSONRPC.Parity.Trace do | `"balance"` | `:value` | | `"refundAddress"` | `:to_address_hash` | - iex> Explorer.JSONRPC.Parity.Trace.elixir_to_params( + iex> EthereumJSONRPC.Parity.Trace.elixir_to_params( ...> %{ ...> "action" => %{ ...> "address" => "0xa7542d78b9a0be6147536887e0065f16182d294b", @@ -251,7 +251,7 @@ defmodule Explorer.JSONRPC.Parity.Trace do @doc """ Decodes the stringly typed numerical fields to `t:non_neg_integer/0`. - iex> Explorer.JSONRPC.Parity.Trace.to_elixir( + iex> EthereumJSONRPC.Parity.Trace.to_elixir( ...> %{ ...> "action" => %{ ...> "from" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", @@ -293,7 +293,7 @@ defmodule Explorer.JSONRPC.Parity.Trace do The caller must put `"index"` and `"transactionHash"` into the incoming map, as Parity itself does not include that information, but it is needed to locate the trace in history fully. - iex> Explorer.JSONRPC.Parity.Trace.to_elixir( + iex> EthereumJSONRPC.Parity.Trace.to_elixir( ...> %{ ...> "action" => %{ ...> "from" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", @@ -316,7 +316,7 @@ defmodule Explorer.JSONRPC.Parity.Trace do `"suicide"` `"type"` traces are different in that they have a `nil` `"result"`. This is because the `"result"` key is used to indicate success from Parity. - iex> Explorer.JSONRPC.Parity.Trace.to_elixir( + iex> EthereumJSONRPC.Parity.Trace.to_elixir( ...> %{ ...> "action" => %{ ...> "address" => "0xa7542d78b9a0be6147536887e0065f16182d294b", @@ -347,7 +347,7 @@ defmodule Explorer.JSONRPC.Parity.Trace do A call type trace can error and be reverted. - iex> Explorer.JSONRPC.Parity.Trace.to_elixir( + iex> EthereumJSONRPC.Parity.Trace.to_elixir( ...> %{ ...> "action" => %{ ...> "callType" => "call", diff --git a/apps/explorer/lib/explorer/jsonrpc/parity/trace/action.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/parity/trace/action.ex similarity index 93% rename from apps/explorer/lib/explorer/jsonrpc/parity/trace/action.ex rename to apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/parity/trace/action.ex index 7fd26ccf4b..67b675c83b 100644 --- a/apps/explorer/lib/explorer/jsonrpc/parity/trace/action.ex +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/parity/trace/action.ex @@ -1,14 +1,14 @@ -defmodule Explorer.JSONRPC.Parity.Trace.Action do +defmodule EthereumJSONRPC.Parity.Trace.Action do @moduledoc """ - The action that was peformed in a `t:Explorer.JSONRPC.Parity.Trace.t/0` + The action that was peformed in a `t:EthereumJSONRPC.Parity.Trace.t/0` """ - import Explorer.JSONRPC, only: [quantity_to_integer: 1] + import EthereumJSONRPC, only: [quantity_to_integer: 1] @doc """ Decodes the stringly typed numerical fields to `t:non_neg_integer/0`. - iex> Explorer.JSONRPC.Parity.Trace.Action.to_elixir( + iex> EthereumJSONRPC.Parity.Trace.Action.to_elixir( ...> %{ ...> "from" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", ...> "gas" => "0x462534", @@ -24,9 +24,9 @@ defmodule Explorer.JSONRPC.Parity.Trace.Action do } For a suicide, the `"balance"` is converted to a `t:non_neg_integer/0` while the `"address"` and `"refundAddress"` - `t:Explorer.JSONRPC.hash/0` pass through. + `t:EthereumJSONRPC.hash/0` pass through. - iex> Explorer.JSONRPC.Parity.Trace.Action.to_elixir( + iex> EthereumJSONRPC.Parity.Trace.Action.to_elixir( ...> %{ ...> "address" => "0xa7542d78b9a0be6147536887e0065f16182d294b", ...> "balance" => "0x0", diff --git a/apps/explorer/lib/explorer/jsonrpc/parity/trace/result.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/parity/trace/result.ex similarity index 91% rename from apps/explorer/lib/explorer/jsonrpc/parity/trace/result.ex rename to apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/parity/trace/result.ex index bf505a24df..23abb45188 100644 --- a/apps/explorer/lib/explorer/jsonrpc/parity/trace/result.ex +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/parity/trace/result.ex @@ -1,14 +1,14 @@ -defmodule Explorer.JSONRPC.Parity.Trace.Result do +defmodule EthereumJSONRPC.Parity.Trace.Result do @moduledoc """ - The result of performing the `t:Explorer.JSONRPC.Parity.Action.t/0` in a `t:Explorer.JSONRPC.Parity.Trace.t/0`. + The result of performing the `t:EthereumJSONRPC.Parity.Action.t/0` in a `t:EthereumJSONRPC.Parity.Trace.t/0`. """ - import Explorer.JSONRPC, only: [quantity_to_integer: 1] + import EthereumJSONRPC, only: [quantity_to_integer: 1] @doc """ Decodes the stringly typed numerical fields to `t:non_neg_integer/0`. - iex> Explorer.JSONRPC.Parity.Trace.Result.to_elixir( + iex> EthereumJSONRPC.Parity.Trace.Result.to_elixir( ...> %{ ...> "address" => "0xffc87239eb0267bc3ca2cd51d12fbf278e02ccb4", ...> "code" => "0x606060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100a05780638da5cb5b146100c9578063fdacd5761461011e575b600080fd5b341561007257600080fd5b61009e600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610141565b005b34156100ab57600080fd5b6100b3610224565b6040518082815260200191505060405180910390f35b34156100d457600080fd5b6100dc61022a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561012957600080fd5b61013f600480803590602001909190505061024f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610220578190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b151561020b57600080fd5b6102c65a03f1151561021c57600080fd5b5050505b5050565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102ac57806001819055505b505600a165627a7a72305820a9c628775efbfbc17477a472413c01ee9b33881f550c59d21bee9928835c854b0029", @@ -23,7 +23,7 @@ defmodule Explorer.JSONRPC.Parity.Trace.Result do `nil` resultscan occur for suicide type traces. - iex> Explorer.JSONRPC.Parity.Trace.Result.to_elixir(nil) + iex> EthereumJSONRPC.Parity.Trace.Result.to_elixir(nil) nil """ diff --git a/apps/explorer/lib/explorer/jsonrpc/parity/traces.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/parity/traces.ex similarity index 85% rename from apps/explorer/lib/explorer/jsonrpc/parity/traces.ex rename to apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/parity/traces.ex index ccb7e4cce6..f18186fd25 100644 --- a/apps/explorer/lib/explorer/jsonrpc/parity/traces.ex +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/parity/traces.ex @@ -1,11 +1,11 @@ -defmodule Explorer.JSONRPC.Parity.Traces do +defmodule EthereumJSONRPC.Parity.Traces do @moduledoc """ Trace returned by [`trace_replayTransaction`](https://wiki.parity.io/JSONRPC-trace-module.html#trace_replaytransaction), which is an extension to the Ethereum JSONRPC standard that is only supported by [Parity](https://wiki.parity.io/). """ - alias Explorer.JSONRPC.Parity.Trace + alias EthereumJSONRPC.Parity.Trace def elixir_to_params(elixir) when is_list(elixir) do Enum.map(elixir, &Trace.elixir_to_params/1) diff --git a/apps/explorer/lib/explorer/jsonrpc/receipt.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/receipt.ex similarity index 78% rename from apps/explorer/lib/explorer/jsonrpc/receipt.ex rename to apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/receipt.ex index bd38d9f135..f1600184a4 100644 --- a/apps/explorer/lib/explorer/jsonrpc/receipt.ex +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/receipt.ex @@ -1,37 +1,45 @@ -defmodule Explorer.JSONRPC.Receipt do +defmodule EthereumJSONRPC.Receipt do @moduledoc """ Receipts format as returned by [`eth_getTransactionReceipt`](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactionreceipt). """ - import Explorer.JSONRPC, only: [quantity_to_integer: 1] + import EthereumJSONRPC, only: [quantity_to_integer: 1] alias Explorer.Chain.Receipt.Status - alias Explorer.JSONRPC - alias Explorer.JSONRPC.Logs + alias EthereumJSONRPC + alias EthereumJSONRPC.Logs @type elixir :: %{String.t() => String.t() | non_neg_integer} @typedoc """ - * `"contractAddress"` - The contract `t:Explorer.JSONRPC.address/0` created, if the transaction was a contract + * `"contractAddress"` - The contract `t:EthereumJSONRPC.address/0` created, if the transaction was a contract creation, otherwise `nil`. - * `"blockHash"` - `t:Explorer.JSONRPC.hash/0` of the block where `"transactionHash"` was in. - * `"blockNumber"` - The block number `t:Explorer.JSONRPC.quanity/0`. - * `"cumulativeGasUsed"` - `t:Explorer.JSONRPC.quantity/0` of gas used when this transaction was executed in the + * `"blockHash"` - `t:EthereumJSONRPC.hash/0` of the block where `"transactionHash"` was in. + * `"blockNumber"` - The block number `t:EthereumJSONRPC.quanity/0`. + * `"cumulativeGasUsed"` - `t:EthereumJSONRPC.quantity/0` of gas used when this transaction was executed in the block. - * `"gasUsed"` - `t:Explorer.JSONRPC.quantity/0` of gas used by this specific transaction alone. + * `"gasUsed"` - `t:EthereumJSONRPC.quantity/0` of gas used by this specific transaction alone. * `"logs"` - `t:list/0` of log objects, which this transaction generated. - * `"logsBloom"` - `t:Explorer.JSONRPC.data/0` of 256 Bytes for + * `"logsBloom"` - `t:EthereumJSONRPC.data/0` of 256 Bytes for [Bloom filter](https://en.wikipedia.org/wiki/Bloom_filter) for light clients to quickly retrieve related logs. - * `"root"` - `t:Explorer.JSONRPC.hash/0` of post-transaction stateroot (pre-Byzantium) - * `"status"` - `t:Explorer.JSONRPC.quantity/0` of either 1 (success) or 0 (failure) (post-Byzantium) - * `"transactionHash"` - `t:Explorer.JSONRPC.hash/0` the transaction. - * `"transactionIndex"` - `t:Explorer.JSONRPC.quantity/0` for the transaction index in the block. + * `"root"` - `t:EthereumJSONRPC.hash/0` of post-transaction stateroot (pre-Byzantium) + * `"status"` - `t:EthereumJSONRPC.quantity/0` of either 1 (success) or 0 (failure) (post-Byzantium) + * `"transactionHash"` - `t:EthereumJSONRPC.hash/0` the transaction. + * `"transactionIndex"` - `t:EthereumJSONRPC.quantity/0` for the transaction index in the block. """ - @type t :: %{String.t() => JSONRPC.address() | JSONRPC.data() | JSONRPC.hash() | JSONRPC.quantity() | list | nil} + @type t :: %{ + String.t() => + EthereumJSONRPC.address() + | EthereumJSONRPC.data() + | EthereumJSONRPC.hash() + | EthereumJSONRPC.quantity() + | list + | nil + } @doc """ - Get `t:Explorer.JSONRPC.Logs.elixir/0` from `t:elixir/0` + Get `t:EthereumJSONRPC.Logs.elixir/0` from `t:elixir/0` """ @spec elixir_to_logs(elixir) :: Logs.elixir() def elixir_to_logs(%{"logs" => logs}), do: logs @@ -39,7 +47,7 @@ defmodule Explorer.JSONRPC.Receipt do @doc """ Converts `t:elixir/0` format to params used in `Explorer.Chain`. - iex> Explorer.JSONRPC.Receipt.elixir_to_params( + iex> EthereumJSONRPC.Receipt.elixir_to_params( ...> %{ ...> "blockHash" => "0xe52d77084cab13a4e724162bcd8c6028e5ecfaa04d091ee476e96b9958ed6b47", ...> "blockNumber" => 34, @@ -89,7 +97,7 @@ defmodule Explorer.JSONRPC.Receipt do @doc """ Decodes the stringly typed numerical fields to `t:non_neg_integer/0`. - iex> Explorer.JSONRPC.Receipt.to_elixir( + iex> EthereumJSONRPC.Receipt.to_elixir( ...> %{ ...> "blockHash" => "0xe52d77084cab13a4e724162bcd8c6028e5ecfaa04d091ee476e96b9958ed6b47", ...> "blockNumber" => "0x22", @@ -125,7 +133,7 @@ defmodule Explorer.JSONRPC.Receipt do end # double check that no new keys are being missed by requiring explicit match for passthrough - # `t:Explorer.JSONRPC.address/0` and `t:Explorer.JSONRPC.hash/0` pass through as `Explorer.Chain` can verify correct + # `t:EthereumJSONRPC.address/0` and `t:EthereumJSONRPC.hash/0` pass through as `Explorer.Chain` can verify correct # hash format defp entry_to_elixir({key, _} = entry) when key in ~w(blockHash contractAddress logsBloom root transactionHash), do: entry diff --git a/apps/explorer/lib/explorer/jsonrpc/receipts.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/receipts.ex similarity index 97% rename from apps/explorer/lib/explorer/jsonrpc/receipts.ex rename to apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/receipts.ex index 53098ca4cc..83a704c36f 100644 --- a/apps/explorer/lib/explorer/jsonrpc/receipts.ex +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/receipts.ex @@ -1,13 +1,13 @@ -defmodule Explorer.JSONRPC.Receipts do +defmodule EthereumJSONRPC.Receipts do @moduledoc """ Receipts format as returned by [`eth_getTransactionReceipt`](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactionreceipt) from batch requests. """ - import Explorer.JSONRPC, only: [config: 1, json_rpc: 2] + import EthereumJSONRPC, only: [config: 1, json_rpc: 2] - alias Explorer.JSONRPC.{Logs, Receipt} + alias EthereumJSONRPC.{Logs, Receipt} @type elixir :: [Receipt.elixir()] @type t :: [Receipt.t()] @@ -15,7 +15,7 @@ defmodule Explorer.JSONRPC.Receipts do @doc """ Extracts logs from `t:elixir/0` - iex> Explorer.JSONRPC.Receipts.elixir_to_logs([ + iex> EthereumJSONRPC.Receipts.elixir_to_logs([ ...> %{ ...> "blockHash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd", ...> "blockNumber" => 37, @@ -67,7 +67,7 @@ defmodule Explorer.JSONRPC.Receipts do @doc """ Converts each element of `t:elixir/0` to params used by `Explorer.Chain.Receipt.changeset/2`. - iex> Explorer.JSONRPC.Receipts.elixir_to_params([ + iex> EthereumJSONRPC.Receipts.elixir_to_params([ ...> %{ ...> "blockHash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd", ...> "blockNumber" => 37, @@ -136,7 +136,7 @@ defmodule Explorer.JSONRPC.Receipts do @doc """ Converts stringly typed fields to native Elixir types. - iex> Explorer.JSONRPC.Receipts.to_elixir([ + iex> EthereumJSONRPC.Receipts.to_elixir([ ...> %{ ...> "blockHash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd", ...> "blockNumber" => "0x25", diff --git a/apps/explorer/lib/explorer/jsonrpc/transaction.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/transaction.ex similarity index 70% rename from apps/explorer/lib/explorer/jsonrpc/transaction.ex rename to apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/transaction.ex index fd7e589ee4..adb827d0ee 100644 --- a/apps/explorer/lib/explorer/jsonrpc/transaction.ex +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/transaction.ex @@ -1,4 +1,4 @@ -defmodule Explorer.JSONRPC.Transaction do +defmodule EthereumJSONRPC.Transaction do @moduledoc """ Transaction format included in the return of [`eth_getBlockByHash`](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getblockbyhash) @@ -8,45 +8,50 @@ defmodule Explorer.JSONRPC.Transaction do and [`eth_getTransactionByBlockNumberAndIndex`](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactionbyblocknumberandindex) """ - import Explorer.JSONRPC, only: [quantity_to_integer: 1] + import EthereumJSONRPC, only: [quantity_to_integer: 1] - alias Explorer.JSONRPC + alias EthereumJSONRPC - @type elixir :: %{String.t() => JSONRPC.address() | JSONRPC.hash() | String.t() | non_neg_integer() | nil} + @type elixir :: %{ + String.t() => EthereumJSONRPC.address() | EthereumJSONRPC.hash() | String.t() | non_neg_integer() | nil + } @typedoc """ - * `"blockHash"` - `t:Explorer.JSONRPC.hash/0` of the block this transaction is in. `nil` when transaction is + * `"blockHash"` - `t:EthereumJSONRPC.hash/0` of the block this transaction is in. `nil` when transaction is pending. - * `"blockNumber"` - `t:Explorer.JSONRPC.quantity/0` for the block number this transaction is in. `nil` when + * `"blockNumber"` - `t:EthereumJSONRPC.quantity/0` for the block number this transaction is in. `nil` when transaction is pending. * `"chainId"` - the chain on which the transaction exists. * `"condition"` - UNKNOWN - * `"creates"` - `t:Explorer.JSONRPC.address/0` of the created contract, if the transaction creates a contract. - * `"from"` - `t:Explorer.JSONRPC.address/0` of the sender. - * `"gas"` - `t:Explorer.JSONRPC.quantity/0` of gas provided by the sender. This is the max gas that may be used. + * `"creates"` - `t:EthereumJSONRPC.address/0` of the created contract, if the transaction creates a contract. + * `"from"` - `t:EthereumJSONRPC.address/0` of the sender. + * `"gas"` - `t:EthereumJSONRPC.quantity/0` of gas provided by the sender. This is the max gas that may be used. `gas * gasPrice` is the max fee in wei that the sender is willing to pay for the transaction to be executed. - * `"gasPrice"` - `t:Explorer.JSONRPC.quantity/0` of wei to pay per unit of gas used. - * `"hash"` - `t:Explorer.JSONRPC.hash/0` of the transaction - * `"input"` - `t:Explorer.JSONRPC.data/0` sent along with the transaction, such as input to the contract. - * `"nonce"` - `t:Explorer.JSONRPC.quantity/0` of transactions made by the sender prior to this one. - * `"publicKey"` - `t:Explorer.JSONRPC.hash/0` of the public key of the signer. - * `"r"` - `t:Explorer.JSONRPC.quantity/0` for the R field of the signature. - * `"raw"` - Raw transaction `t:Explorer.JSONRPC.data/0` - * `"standardV"` - `t:Explorer.JSONRPC.quantity/0` for the standardized V (`0` or `1`) field of the signature. - * `"to"` - `t:Explorer.JSONRPC.address/0` of the receiver. `nil` when it is a contract creation transaction. - * `"transactionIndex"` - `t:Explorer.JSONRPC.quantity/0` for the index of the transaction in the block. `nil` when + * `"gasPrice"` - `t:EthereumJSONRPC.quantity/0` of wei to pay per unit of gas used. + * `"hash"` - `t:EthereumJSONRPC.hash/0` of the transaction + * `"input"` - `t:EthereumJSONRPC.data/0` sent along with the transaction, such as input to the contract. + * `"nonce"` - `t:EthereumJSONRPC.quantity/0` of transactions made by the sender prior to this one. + * `"publicKey"` - `t:EthereumJSONRPC.hash/0` of the public key of the signer. + * `"r"` - `t:EthereumJSONRPC.quantity/0` for the R field of the signature. + * `"raw"` - Raw transaction `t:EthereumJSONRPC.data/0` + * `"standardV"` - `t:EthereumJSONRPC.quantity/0` for the standardized V (`0` or `1`) field of the signature. + * `"to"` - `t:EthereumJSONRPC.address/0` of the receiver. `nil` when it is a contract creation transaction. + * `"transactionIndex"` - `t:EthereumJSONRPC.quantity/0` for the index of the transaction in the block. `nil` when transaction is pending. - * `"v"` - `t:Explorer.JSONRPC.quantity/0` for the V field of the signature. - * `"value"` - `t:Explorer.JSONRPC.quantity/0` of wei transfered + * `"v"` - `t:EthereumJSONRPC.quantity/0` for the V field of the signature. + * `"value"` - `t:EthereumJSONRPC.quantity/0` of wei transfered """ - @type t :: %{String.t() => JSONRPC.address() | JSONRPC.hash() | JSONRPC.quantity() | String.t() | nil} + @type t :: %{ + String.t() => + EthereumJSONRPC.address() | EthereumJSONRPC.hash() | EthereumJSONRPC.quantity() | String.t() | nil + } @type params :: %{ - block_hash: JSONRPC.hash(), - from_address_hash: JSONRPC.address(), + block_hash: EthereumJSONRPC.hash(), + from_address_hash: EthereumJSONRPC.address(), gas: non_neg_integer(), gas_price: non_neg_integer(), - hash: JSONRPC.hash(), + hash: EthereumJSONRPC.hash(), index: non_neg_integer(), input: String.t(), nonce: non_neg_integer(), @@ -54,7 +59,7 @@ defmodule Explorer.JSONRPC.Transaction do r: non_neg_integer(), s: non_neg_integer(), standard_v: 0 | 1, - to_address_hash: JSONRPC.address(), + to_address_hash: EthereumJSONRPC.address(), v: non_neg_integer(), value: non_neg_integer() } @@ -97,9 +102,9 @@ defmodule Explorer.JSONRPC.Transaction do end @doc """ - Extracts `t:Explorer.JSONRPC.hash/0` from transaction `params` + Extracts `t:EthereumJSONRPC.hash/0` from transaction `params` - iex> Explorer.JSONRPC.Transaction.params_to_hash( + iex> EthereumJSONRPC.Transaction.params_to_hash( ...> %{ ...> block_hash: "0xe52d77084cab13a4e724162bcd8c6028e5ecfaa04d091ee476e96b9958ed6b47", ...> gas: 4700000, @@ -129,7 +134,7 @@ defmodule Explorer.JSONRPC.Transaction do end # double check that no new keys are being missed by requiring explicit match for passthrough - # `t:Explorer.JSONRPC.address/0` and `t:Explorer.JSONRPC.hash/0` pass through as `Explorer.Chain` can verify correct + # `t:EthereumJSONRPC.address/0` and `t:EthereumJSONRPC.hash/0` pass through as `Explorer.Chain` can verify correct # hash format # r s standardV and v pass through because they exceed postgres integer limits defp entry_to_elixir({key, value}) diff --git a/apps/explorer/lib/explorer/jsonrpc/transactions.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/transactions.ex similarity index 98% rename from apps/explorer/lib/explorer/jsonrpc/transactions.ex rename to apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/transactions.ex index 9551a537f3..9eb00c3ba4 100644 --- a/apps/explorer/lib/explorer/jsonrpc/transactions.ex +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/transactions.ex @@ -1,11 +1,11 @@ -defmodule Explorer.JSONRPC.Transactions do +defmodule EthereumJSONRPC.Transactions do @moduledoc """ List of transactions format as included in return from [`eth_getBlockByHash`](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getblockbyhash) and [`eth_getBlockByNumber`](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getblockbynumber). """ - alias Explorer.JSONRPC.Transaction + alias EthereumJSONRPC.Transaction @type elixir :: [Transaction.elixir()] @type t :: [Transaction.t()] @@ -13,7 +13,7 @@ defmodule Explorer.JSONRPC.Transactions do @doc """ Converts each entry in `elixir` to params used in `Explorer.Chain.Transaction.changeset/2`. - iex> Explorer.JSONRPC.Transactions.elixir_to_params( + iex> EthereumJSONRPC.Transactions.elixir_to_params( ...> [ ...> %{ ...> "blockHash" => "0xe52d77084cab13a4e724162bcd8c6028e5ecfaa04d091ee476e96b9958ed6b47", @@ -67,7 +67,7 @@ defmodule Explorer.JSONRPC.Transactions do @doc """ Extract just the `t:Explorer.Chain.Transaction.t/0` `hash` from `params` list elements. - iex> Explorer.JSONRPC.Transactions.params_to_hashes( + iex> EthereumJSONRPC.Transactions.params_to_hashes( ...> [ ...> %{ ...> block_hash: "0xe52d77084cab13a4e724162bcd8c6028e5ecfaa04d091ee476e96b9958ed6b47", @@ -98,7 +98,7 @@ defmodule Explorer.JSONRPC.Transactions do @doc """ Decodes stringly typed fields in entries in `transactions` - iex> Explorer.JSONRPC.Transactions.to_elixir([ + iex> EthereumJSONRPC.Transactions.to_elixir([ ...> %{ ...> "blockHash" => "0xe52d77084cab13a4e724162bcd8c6028e5ecfaa04d091ee476e96b9958ed6b47", ...> "blockNumber" => "0x22", diff --git a/apps/ethereum_jsonrpc/mix.exs b/apps/ethereum_jsonrpc/mix.exs index 0dc672b64b..975fd08b05 100644 --- a/apps/ethereum_jsonrpc/mix.exs +++ b/apps/ethereum_jsonrpc/mix.exs @@ -3,31 +3,63 @@ defmodule EthereumJsonrpc.MixProject do def project do [ + aliases: aliases(Mix.env()), app: :ethereum_jsonrpc, - version: "0.1.0", build_path: "../../_build", config_path: "../../config/config.exs", + deps: deps(), deps_path: "../../deps", - lockfile: "../../mix.lock", + dialyzer: [ + plt_add_deps: :transitive, + plt_add_apps: [:mix], + ignore_warnings: "../../.dialyzer-ignore" + ], elixir: "~> 1.6", + lockfile: "../../mix.lock", + preferred_cli_env: [ + coveralls: :test, + "coveralls.detail": :test, + "coveralls.post": :test, + "coveralls.html": :test, + dialyzer: :test + ], start_permanent: Mix.env() == :prod, - deps: deps() + test_coverage: [tool: ExCoveralls], + version: "0.1.0" ] end # Run "mix help compile.app" to learn about applications. def application do [ + mod: {EthereumJSONRPC.Application, []}, extra_applications: [:logger] ] end + defp aliases(env) do + env_aliases(env) + end + + defp env_aliases(:dev), do: [] + + defp env_aliases(_env), do: [compile: "compile --warnings-as-errors"] + # Run "mix help deps" to learn about dependencies. defp deps do [ - # {:dep_from_hexpm, "~> 0.3.0"}, - # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}, - # {:sibling_app_in_umbrella, in_umbrella: true}, + # Style Checking + {:credo, "0.9.2", only: [:dev, :test], runtime: false}, + # Static Type Checking + {:dialyxir, "~> 0.5", only: [:dev, :test], runtime: false}, + # Code coverage + {:excoveralls, "~> 0.8.1", only: [:test]}, + # JSONRPC HTTP Post calls + {:httpoison, "~> 1.0", override: true}, + # Decode/Encode JSON for JSONRPC + {:jason, "~> 1.0"}, + # Convert unix timestamps in JSONRPC to DateTimes + {:timex, "~> 3.1.24"} ] end end diff --git a/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/block_test.exs b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/block_test.exs new file mode 100644 index 0000000000..3075dd4b74 --- /dev/null +++ b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/block_test.exs @@ -0,0 +1,5 @@ +defmodule EthereumJSONRPC.BlockTest do + use ExUnit.Case, async: true + + doctest EthereumJSONRPC.Block +end diff --git a/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/blocks_test.exs b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/blocks_test.exs new file mode 100644 index 0000000000..37626d801d --- /dev/null +++ b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/blocks_test.exs @@ -0,0 +1,5 @@ +defmodule EthereumJSONRPC.BlocksTest do + use ExUnit.Case, async: true + + doctest EthereumJSONRPC.Blocks +end diff --git a/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/log_test.exs b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/log_test.exs new file mode 100644 index 0000000000..a2c43064cf --- /dev/null +++ b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/log_test.exs @@ -0,0 +1,5 @@ +defmodule EthereumJSONRPC.LogTest do + use ExUnit.Case, async: true + + doctest EthereumJSONRPC.Log +end diff --git a/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/parity/trace/action_test.exs b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/parity/trace/action_test.exs new file mode 100644 index 0000000000..78597b57f1 --- /dev/null +++ b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/parity/trace/action_test.exs @@ -0,0 +1,5 @@ +defmodule EthereumJSONRPC.Parity.Trace.ActionTest do + use ExUnit.Case, async: true + + doctest EthereumJSONRPC.Parity.Trace.Action +end diff --git a/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/parity/trace/result_test.exs b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/parity/trace/result_test.exs new file mode 100644 index 0000000000..f419f5045b --- /dev/null +++ b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/parity/trace/result_test.exs @@ -0,0 +1,5 @@ +defmodule EthereumJSONRPC.Parity.Trace.ResultTest do + use ExUnit.Case, async: true + + doctest EthereumJSONRPC.Parity.Trace.Result +end diff --git a/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/parity/trace_test.exs b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/parity/trace_test.exs new file mode 100644 index 0000000000..75daf2eb04 --- /dev/null +++ b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/parity/trace_test.exs @@ -0,0 +1,5 @@ +defmodule EthereumJSONRPC.Parity.TraceTest do + use ExUnit.Case, async: true + + doctest EthereumJSONRPC.Parity.Trace +end diff --git a/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/parity_test.exs b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/parity_test.exs new file mode 100644 index 0000000000..e953ad0146 --- /dev/null +++ b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/parity_test.exs @@ -0,0 +1,5 @@ +defmodule EthereumJSONRPC.ParityTest do + use ExUnit.Case, async: true + + doctest EthereumJSONRPC.Parity +end diff --git a/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/receipt_test.exs b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/receipt_test.exs new file mode 100644 index 0000000000..95b9a3abf4 --- /dev/null +++ b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/receipt_test.exs @@ -0,0 +1,5 @@ +defmodule EthereumJSONRPC.ReceiptTest do + use ExUnit.Case, async: true + + doctest EthereumJSONRPC.Receipt +end diff --git a/apps/explorer/test/explorer/jsonrpc/receipts_test.exs b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/receipts_test.exs similarity index 92% rename from apps/explorer/test/explorer/jsonrpc/receipts_test.exs rename to apps/ethereum_jsonrpc/test/ethereum_jsonrpc/receipts_test.exs index 46b887152c..fab742b008 100644 --- a/apps/explorer/test/explorer/jsonrpc/receipts_test.exs +++ b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/receipts_test.exs @@ -1,13 +1,13 @@ -defmodule Explorer.JSONRPC.ReceiptsTest do +defmodule EthereumJSONRPC.ReceiptsTest do use ExUnit.Case, async: true - alias Explorer.JSONRPC.Receipts + alias EthereumJSONRPC.Receipts doctest Receipts # These are integration tests that depend on the sokol chain being used. sokol can be used with the following config # - # config :explorer, Explorer.JSONRPC, + # config :explorer, EthereumJSONRPC, # trace_url: "https://sokol-trace.poa.network", # url: "https://sokol.poa.network" # diff --git a/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/transaction_test.exs b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/transaction_test.exs new file mode 100644 index 0000000000..ad7780181d --- /dev/null +++ b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/transaction_test.exs @@ -0,0 +1,5 @@ +defmodule EthereumJSONRPC.TransactionTest do + use ExUnit.Case, async: true + + doctest EthereumJSONRPC.Transaction +end diff --git a/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/transactions_test.exs b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/transactions_test.exs new file mode 100644 index 0000000000..765130a88a --- /dev/null +++ b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/transactions_test.exs @@ -0,0 +1,5 @@ +defmodule EthereumJSONRPC.TransactionsTest do + use ExUnit.Case, async: true + + doctest EthereumJSONRPC.Transactions +end diff --git a/apps/ethereum_jsonrpc/test/ethereum_jsonrpc_test.exs b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc_test.exs deleted file mode 100644 index e681240eb4..0000000000 --- a/apps/ethereum_jsonrpc/test/ethereum_jsonrpc_test.exs +++ /dev/null @@ -1,8 +0,0 @@ -defmodule EthereumJsonrpcTest do - use ExUnit.Case - doctest EthereumJsonrpc - - test "greets the world" do - assert EthereumJsonrpc.hello() == :world - end -end diff --git a/apps/ethereum_jsonrpc/test/test_helper.exs b/apps/ethereum_jsonrpc/test/test_helper.exs index 869559e709..9fbe8ddc4c 100644 --- a/apps/ethereum_jsonrpc/test/test_helper.exs +++ b/apps/ethereum_jsonrpc/test/test_helper.exs @@ -1 +1,7 @@ +# https://github.com/CircleCI-Public/circleci-demo-elixir-phoenix/blob/a89de33a01df67b6773ac90adc74c34367a4a2d6/test/test_helper.exs#L1-L3 +junit_folder = Mix.Project.build_path() <> "/junit/#{Mix.Project.config()[:app]}" +File.mkdir_p!(junit_folder) +:ok = Application.put_env(:junit_formatter, :report_dir, junit_folder) + +ExUnit.configure(formatters: [JUnitFormatter, ExUnit.CLIFormatter]) ExUnit.start() diff --git a/apps/explorer/config/config.exs b/apps/explorer/config/config.exs index c281af164d..4f4b8ce0d2 100644 --- a/apps/explorer/config/config.exs +++ b/apps/explorer/config/config.exs @@ -14,11 +14,6 @@ config :explorer, ecto_repos: [Explorer.Repo], coin: "POA" -config :explorer, Explorer.JSONRPC, - http: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :eth]], - trace_url: "https://sokol-trace.poa.network", - url: "https://sokol.poa.network" - config :explorer, Explorer.Integrations.EctoLogger, query_time_ms_threshold: 2_000 config :explorer, Explorer.Repo, migration_timestamps: [type: :utc_datetime] diff --git a/apps/explorer/lib/explorer/application.ex b/apps/explorer/lib/explorer/application.ex index bf6dbe652d..2f5dc033c9 100644 --- a/apps/explorer/lib/explorer/application.ex +++ b/apps/explorer/lib/explorer/application.ex @@ -25,7 +25,6 @@ defmodule Explorer.Application do # Children to start when not testing defp secondary_children(_) do [ - Explorer.JSONRPC, Supervisor.child_spec({Task.Supervisor, name: Explorer.TaskSupervisor}, id: Explorer.TaskSupervisor), Explorer.Indexer.Supervisor, Explorer.Chain.Statistics.Server, diff --git a/apps/explorer/lib/explorer/indexer/address_fetcher.ex b/apps/explorer/lib/explorer/indexer/address_fetcher.ex index 91f69cd9b6..dd403decaa 100644 --- a/apps/explorer/lib/explorer/indexer/address_fetcher.ex +++ b/apps/explorer/lib/explorer/indexer/address_fetcher.ex @@ -5,12 +5,9 @@ defmodule Explorer.Indexer.AddressFetcher do use GenServer require Logger - alias Explorer.{Chain, JSONRPC} - - alias Explorer.Chain.{ - Address, - Hash - } + alias EthereumJSONRPC + alias Explorer.Chain + alias Explorer.Chain.{Address, Hash} @fetch_interval :timer.seconds(3) @max_batch_size 100 @@ -112,7 +109,7 @@ defmodule Explorer.Indexer.AddressFetcher do end defp do_fetch_addresses(address_hashes) do - JSONRPC.fetch_balances_by_hash(address_hashes) + EthereumJSONRPC.fetch_balances_by_hash(address_hashes) end defp take_batch(queue) do diff --git a/apps/explorer/lib/explorer/indexer/block_fetcher.ex b/apps/explorer/lib/explorer/indexer/block_fetcher.ex index 3af605b174..a32d8a11ac 100644 --- a/apps/explorer/lib/explorer/indexer/block_fetcher.ex +++ b/apps/explorer/lib/explorer/indexer/block_fetcher.ex @@ -7,9 +7,10 @@ defmodule Explorer.Indexer.BlockFetcher do require Logger - alias Explorer.{Chain, Indexer, JSONRPC} + alias EthereumJSONRPC + alias EthereumJSONRPC.Transactions + alias Explorer.{Chain, Indexer} alias Explorer.Indexer.{AddressFetcher, Sequence} - alias Explorer.JSONRPC.Transactions # dialyzer thinks that Logger.debug functions always have no_local_return @dialyzer {:nowarn_function, import_range: 3} @@ -161,7 +162,7 @@ defmodule Explorer.Indexer.BlockFetcher do hashes |> Enum.chunk_every(state.internal_transactions_batch_size) - |> Task.async_stream(&JSONRPC.fetch_internal_transactions(&1), stream_opts) + |> Task.async_stream(&EthereumJSONRPC.fetch_internal_transactions(&1), stream_opts) |> Enum.reduce_while({:ok, []}, fn {:ok, {:ok, internal_transactions}}, {:ok, acc} -> {:cont, {:ok, acc ++ internal_transactions}} {:ok, {:error, reason}}, {:ok, _acc} -> {:halt, {:error, reason}} @@ -177,7 +178,7 @@ defmodule Explorer.Indexer.BlockFetcher do hashes |> Enum.chunk_every(state.receipts_batch_size) - |> Task.async_stream(&JSONRPC.fetch_transaction_receipts(&1), stream_opts) + |> Task.async_stream(&EthereumJSONRPC.fetch_transaction_receipts(&1), stream_opts) |> Enum.reduce_while({:ok, %{logs: [], receipts: []}}, fn {:ok, {:ok, %{logs: logs, receipts: receipts}}}, {:ok, %{logs: acc_logs, receipts: acc_receipts}} -> {:cont, {:ok, %{logs: acc_logs ++ logs, receipts: acc_receipts ++ receipts}}} @@ -256,7 +257,7 @@ defmodule Explorer.Indexer.BlockFetcher do # Only public for testing @doc false def import_range({block_start, block_end} = range, %{} = state, seq) do - with {:blocks, {:ok, next, result}} <- {:blocks, JSONRPC.fetch_blocks_by_range(block_start, block_end)}, + with {:blocks, {:ok, next, result}} <- {:blocks, EthereumJSONRPC.fetch_blocks_by_range(block_start, block_end)}, %{blocks: blocks, transactions: transactions} = result, cap_seq(seq, next, range, state), transaction_hashes = Transactions.params_to_hashes(transactions), diff --git a/apps/explorer/lib/explorer/jsonrpc.ex b/apps/explorer/lib/explorer/jsonrpc.ex deleted file mode 100644 index c270a4993a..0000000000 --- a/apps/explorer/lib/explorer/jsonrpc.ex +++ /dev/null @@ -1,309 +0,0 @@ -defmodule Explorer.JSONRPC do - @moduledoc """ - Ethereum JSONRPC client. - - ## Configuration - - Configuration for parity URLs can be provided with the following mix config: - - config :explorer, Explorer.JSONRPC, - url: "https://sokol.poa.network", - trace_url: "https://sokol-trace.poa.network", - http: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :eth]] - - Note: the tracing node URL is provided separately from `:url`, via `:trace_url`. The trace URL and is used for - `fetch_internal_transactions`, which is only a supported method on tracing nodes. The `:http` option is passed - directly to the HTTP library (`HTTPoison`), which forwards the options down to `:hackney`. - """ - - require Logger - - alias Explorer.JSONRPC.{Blocks, Parity, Receipts, Transactions} - - @typedoc """ - Truncated 20-byte [KECCAK-256](https://en.wikipedia.org/wiki/SHA-3) hash encoded as a hexadecimal number in a - `String.t`. - """ - @type address :: String.t() - - @typedoc """ - Binary data encoded as a single hexadecimal number in a `String.t` - """ - @type data :: String.t() - - @typedoc """ - A full 32-byte [KECCAK-256](https://en.wikipedia.org/wiki/SHA-3) hash encoded as a hexadecimal number in a `String.t` - - ## Example - - "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" - - """ - @type hash :: String.t() - - @typedoc """ - 8 byte [KECCAK-256](https://en.wikipedia.org/wiki/SHA-3) hash of the proof-of-work. - """ - @type nonce :: String.t() - - @typedoc """ - A number encoded as a hexadecimal number in a `String.t` - - ## Example - - "0x1b4" - - """ - @type quantity :: String.t() - - @typedoc """ - Unix timestamp encoded as a hexadecimal number in a `String.t` - """ - @type timestamp :: String.t() - - def child_spec(_opts) do - :hackney_pool.child_spec(:eth, recv_timeout: 60_000, timeout: 60_000, max_connections: 1000) - end - - @doc """ - Lists changes for a given filter subscription. - """ - def check_for_updates(filter_id) do - request = %{ - "id" => filter_id, - "jsonrpc" => "2.0", - "method" => "eth_getFilterChanges", - "params" => [filter_id] - } - - json_rpc(request, config(:url)) - end - - @doc """ - Fetches configuration for this module under `key` - - Configuration can be set a compile time using `config` - - config :explorer, Explorer.JSONRRPC, key: value - - Configuration can be set a runtime using `Application.put_env/3` - - Application.put_env(:explorer, Explorer.JSONRPC, key: value) - - """ - def config(key) do - :explorer - |> Application.fetch_env!(__MODULE__) - |> Keyword.fetch!(key) - end - - @doc """ - Fetches address balances by address hashes. - """ - def fetch_balances_by_hash(address_hashes) do - batched_requests = - for hash <- address_hashes do - %{ - "id" => hash, - "jsonrpc" => "2.0", - "method" => "eth_getBalance", - "params" => [hash, "latest"] - } - end - - batched_requests - |> json_rpc(config(:url)) - |> handle_balances() - end - - defp handle_balances({:ok, results}) do - native_results = - for response <- results, into: %{} do - {response["id"], hexadecimal_to_integer(response["result"])} - end - - {:ok, native_results} - end - - defp handle_balances({:error, _reason} = err), do: err - - @doc """ - Fetches blocks by block hashes. - - Transaction data is included for each block. - """ - def fetch_blocks_by_hash(block_hashes) do - batched_requests = - for block_hash <- block_hashes do - %{ - "id" => block_hash, - "jsonrpc" => "2.0", - "method" => "eth_getBlockByHash", - "params" => [block_hash, true] - } - end - - batched_requests - |> json_rpc(config(:url)) - |> handle_get_block_by_number() - |> case do - {:ok, _next, results} -> {:ok, results} - {:error, reason} -> {:error, reason} - end - end - - @doc """ - Fetches blocks by block number range. - """ - def fetch_blocks_by_range(block_start, block_end) do - block_start - |> build_batch_get_block_by_number(block_end) - |> json_rpc(config(:url)) - |> handle_get_block_by_number() - end - - @doc """ - Fetches internal transactions from client-specific API. - """ - def fetch_internal_transactions(hashes) when is_list(hashes) do - Parity.fetch_internal_transactions(hashes) - end - - def fetch_transaction_receipts(hashes) when is_list(hashes) do - Receipts.fetch(hashes) - end - - @doc """ - 1. POSTs JSON `payload` to `url` - 2. Decodes the response - 3. Handles the response - - ## Returns - - * Handled response - * `{:error, reason}` if POST failes - """ - def json_rpc(payload, url) do - json = encode_json(payload) - headers = [{"Content-Type", "application/json"}] - - case HTTPoison.post(url, json, headers, config(:http)) do - {:ok, %HTTPoison.Response{body: body, status_code: code}} -> - body |> decode_json(payload, url) |> handle_response(code) - - {:error, %HTTPoison.Error{reason: reason}} -> - {:error, reason} - end - end - - @doc """ - Creates a filter subscription that can be polled for retreiving new blocks. - """ - def listen_for_new_blocks do - id = DateTime.utc_now() |> DateTime.to_unix() - - request = %{ - "id" => id, - "jsonrpc" => "2.0", - "method" => "eth_newBlockFilter", - "params" => [] - } - - json_rpc(request, config(:url)) - end - - @doc """ - Converts `t:nonce/0` to `t:non_neg_integer/0` - """ - def nonce_to_integer(nonce) do - hexadecimal_to_integer(nonce) - end - - @doc """ - Converts `t:quantity/0` to `t:non_neg_integer/0`. - """ - def quantity_to_integer(quantity) do - hexadecimal_to_integer(quantity) - end - - @doc """ - Converts `t:timestamp/0` to `t:DateTime.t/0` - """ - def timestamp_to_datetime(timestamp) do - timestamp - |> hexadecimal_to_integer() - |> Timex.from_unix() - end - - defp build_batch_get_block_by_number(block_start, block_end) do - for current <- block_start..block_end do - %{ - "id" => current, - "jsonrpc" => "2.0", - "method" => "eth_getBlockByNumber", - "params" => [int_to_hash_string(current), true] - } - end - end - - defp encode_json(data), do: Jason.encode_to_iodata!(data) - - defp decode_json(body, posted_payload, url) do - Jason.decode!(body) - rescue - Jason.DecodeError -> - Logger.error(""" - failed to decode json payload: - - url: #{inspect(url)} - - body: #{inspect(body)} - - posted payload: #{inspect(posted_payload)} - - """) - - raise("bad jason") - end - - defp handle_get_block_by_number({:ok, results}) do - {blocks, next} = - Enum.reduce(results, {[], :more}, fn - %{"result" => nil}, {blocks, _} -> {blocks, :end_of_chain} - %{"result" => %{} = block}, {blocks, next} -> {[block | blocks], next} - end) - - elixir_blocks = Blocks.to_elixir(blocks) - elixir_transactions = Blocks.elixir_to_transactions(elixir_blocks) - blocks_params = Blocks.elixir_to_params(elixir_blocks) - transactions_params = Transactions.elixir_to_params(elixir_transactions) - - {:ok, next, - %{ - blocks: blocks_params, - transactions: transactions_params - }} - end - - defp handle_get_block_by_number({:error, reason}) do - {:error, reason} - end - - defp handle_response(resp, 200) do - case resp do - [%{} | _] = batch_resp -> {:ok, batch_resp} - %{"error" => error} -> {:error, error} - %{"result" => result} -> {:ok, result} - end - end - - defp handle_response(resp, _status) do - {:error, resp} - end - - defp hexadecimal_to_integer("0x" <> hexadecimal_digits) do - String.to_integer(hexadecimal_digits, 16) - end - - defp int_to_hash_string(number), do: "0x" <> Integer.to_string(number, 16) -end diff --git a/apps/explorer/mix.exs b/apps/explorer/mix.exs index 10117aa737..f35a39f30a 100644 --- a/apps/explorer/mix.exs +++ b/apps/explorer/mix.exs @@ -70,6 +70,8 @@ defmodule Explorer.Mixfile do # Code coverage {:excoveralls, "~> 0.8.1", only: [:test]}, {:exvcr, "~> 0.10", only: :test}, + # JSONRPC access to Parity for `Explorer.Indexer` + {:ethereum_jsonrpc, in_umbrella: true}, {:httpoison, "~> 1.0", override: true}, {:jason, "~> 1.0"}, {:junit_formatter, ">= 0.0.0", only: [:test], runtime: false}, diff --git a/apps/explorer/test/explorer/indexer/address_fetcher_test.exs b/apps/explorer/test/explorer/indexer/address_fetcher_test.exs index 7fafffc6fa..bdd4e6fb7e 100644 --- a/apps/explorer/test/explorer/indexer/address_fetcher_test.exs +++ b/apps/explorer/test/explorer/indexer/address_fetcher_test.exs @@ -4,7 +4,6 @@ defmodule Explorer.Indexer.AddressFetcherTest do use Explorer.DataCase, async: false alias Explorer.Chain.Address - alias Explorer.JSONRPC alias Explorer.Indexer.AddressFetcher @hash %Explorer.Chain.Hash{ @@ -13,7 +12,6 @@ defmodule Explorer.Indexer.AddressFetcherTest do } setup do - start_supervised!({JSONRPC, []}) start_supervised!({Task.Supervisor, name: Explorer.Indexer.TaskSupervisor}) :ok diff --git a/apps/explorer/test/explorer/indexer/block_fetcher_test.exs b/apps/explorer/test/explorer/indexer/block_fetcher_test.exs index 04c140e6c0..39f1e74eab 100644 --- a/apps/explorer/test/explorer/indexer/block_fetcher_test.exs +++ b/apps/explorer/test/explorer/indexer/block_fetcher_test.exs @@ -5,7 +5,6 @@ defmodule Explorer.Indexer.BlockFetcherTest do import ExUnit.CaptureLog alias Explorer.Chain.{Address, Block, InternalTransaction, Log, Receipt, Transaction} - alias Explorer.JSONRPC alias Explorer.Indexer.{BlockFetcher, Sequence} @tag capture_log: true @@ -32,7 +31,6 @@ defmodule Explorer.Indexer.BlockFetcherTest do test "starts fetching blocks from Genesis" do assert Repo.aggregate(Block, :count, :hash) == 0 - start_supervised!({JSONRPC, []}) start_supervised!({Task.Supervisor, name: Explorer.Indexer.TaskSupervisor}) start_supervised!(BlockFetcher) @@ -84,7 +82,6 @@ defmodule Explorer.Indexer.BlockFetcherTest do setup :state setup do - start_supervised!({JSONRPC, []}) start_supervised!({Task.Supervisor, name: Explorer.Indexer.TaskSupervisor}) {:ok, state} = BlockFetcher.init(debug_logs: false) diff --git a/apps/explorer/test/explorer/jsonrpc/block_test.exs b/apps/explorer/test/explorer/jsonrpc/block_test.exs deleted file mode 100644 index c36299629e..0000000000 --- a/apps/explorer/test/explorer/jsonrpc/block_test.exs +++ /dev/null @@ -1,5 +0,0 @@ -defmodule Explorer.JSONRPC.BlockTest do - use ExUnit.Case, async: true - - doctest Explorer.JSONRPC.Block -end diff --git a/apps/explorer/test/explorer/jsonrpc/blocks_test.exs b/apps/explorer/test/explorer/jsonrpc/blocks_test.exs deleted file mode 100644 index 87a2ba6e48..0000000000 --- a/apps/explorer/test/explorer/jsonrpc/blocks_test.exs +++ /dev/null @@ -1,5 +0,0 @@ -defmodule Explorer.JSONRPC.BlocksTest do - use ExUnit.Case, async: true - - doctest Explorer.JSONRPC.Blocks -end diff --git a/apps/explorer/test/explorer/jsonrpc/log_test.exs b/apps/explorer/test/explorer/jsonrpc/log_test.exs deleted file mode 100644 index f1d2a81704..0000000000 --- a/apps/explorer/test/explorer/jsonrpc/log_test.exs +++ /dev/null @@ -1,5 +0,0 @@ -defmodule Explorer.JSONRPC.LogTest do - use ExUnit.Case, async: true - - doctest Explorer.JSONRPC.Log -end diff --git a/apps/explorer/test/explorer/jsonrpc/parity/trace/action_test.exs b/apps/explorer/test/explorer/jsonrpc/parity/trace/action_test.exs deleted file mode 100644 index 1097bf0faa..0000000000 --- a/apps/explorer/test/explorer/jsonrpc/parity/trace/action_test.exs +++ /dev/null @@ -1,5 +0,0 @@ -defmodule Explorer.JSONRPC.Parity.Trace.ActionTest do - use ExUnit.Case, async: true - - doctest Explorer.JSONRPC.Parity.Trace.Action -end diff --git a/apps/explorer/test/explorer/jsonrpc/parity/trace/result_test.exs b/apps/explorer/test/explorer/jsonrpc/parity/trace/result_test.exs deleted file mode 100644 index 9df848f26f..0000000000 --- a/apps/explorer/test/explorer/jsonrpc/parity/trace/result_test.exs +++ /dev/null @@ -1,5 +0,0 @@ -defmodule Explorer.JSONRPC.Parity.Trace.ResultTest do - use ExUnit.Case, async: true - - doctest Explorer.JSONRPC.Parity.Trace.Result -end diff --git a/apps/explorer/test/explorer/jsonrpc/parity/trace_test.exs b/apps/explorer/test/explorer/jsonrpc/parity/trace_test.exs deleted file mode 100644 index c85e520239..0000000000 --- a/apps/explorer/test/explorer/jsonrpc/parity/trace_test.exs +++ /dev/null @@ -1,5 +0,0 @@ -defmodule Explorer.JSONRPC.Parity.TraceTest do - use ExUnit.Case, async: true - - doctest Explorer.JSONRPC.Parity.Trace -end diff --git a/apps/explorer/test/explorer/jsonrpc/parity_test.exs b/apps/explorer/test/explorer/jsonrpc/parity_test.exs deleted file mode 100644 index a13a32f946..0000000000 --- a/apps/explorer/test/explorer/jsonrpc/parity_test.exs +++ /dev/null @@ -1,5 +0,0 @@ -defmodule Explorer.JSONRPC.ParityTest do - use ExUnit.Case, async: true - - doctest Explorer.JSONRPC.Parity -end diff --git a/apps/explorer/test/explorer/jsonrpc/receipt_test.exs b/apps/explorer/test/explorer/jsonrpc/receipt_test.exs deleted file mode 100644 index 3316dc2c50..0000000000 --- a/apps/explorer/test/explorer/jsonrpc/receipt_test.exs +++ /dev/null @@ -1,5 +0,0 @@ -defmodule Explorer.JSONRPC.ReceiptTest do - use ExUnit.Case, async: true - - doctest Explorer.JSONRPC.Receipt -end diff --git a/apps/explorer/test/explorer/jsonrpc/transaction_test.exs b/apps/explorer/test/explorer/jsonrpc/transaction_test.exs deleted file mode 100644 index bb69efbfdd..0000000000 --- a/apps/explorer/test/explorer/jsonrpc/transaction_test.exs +++ /dev/null @@ -1,5 +0,0 @@ -defmodule Explorer.JSONRPC.TransactionTest do - use ExUnit.Case, async: true - - doctest Explorer.JSONRPC.Transaction -end diff --git a/apps/explorer/test/explorer/jsonrpc/transactions_test.exs b/apps/explorer/test/explorer/jsonrpc/transactions_test.exs deleted file mode 100644 index 5243096457..0000000000 --- a/apps/explorer/test/explorer/jsonrpc/transactions_test.exs +++ /dev/null @@ -1,5 +0,0 @@ -defmodule Explorer.JSONRPC.TransactionsTest do - use ExUnit.Case, async: true - - doctest Explorer.JSONRPC.Transactions -end diff --git a/coveralls.json b/coveralls.json index bc08a0ff35..1bb60fd89d 100644 --- a/coveralls.json +++ b/coveralls.json @@ -1,7 +1,7 @@ { "coverage_options": { "treat_no_relevant_lines_as_covered": true, - "minimum_coverage": 94.0 + "minimum_coverage": 91.2 }, "terminal_options": { "file_column_width": 120