Merge remote-tracking branch 'origin/master' into vb-besu-support

vb-besu-support
Victor Baranov 5 years ago
commit e0ec581557
  1. 24
      .circleci/config.yml
  2. 2
      .tool-versions
  3. 18
      CHANGELOG.md
  4. 7405
      apps/block_scout_web/assets/package-lock.json
  5. 2
      apps/block_scout_web/assets/package.json
  6. 3
      apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex
  7. 10
      apps/block_scout_web/lib/block_scout_web/notifier.ex
  8. 2
      apps/block_scout_web/lib/block_scout_web/templates/block/overview.html.eex
  9. 19
      apps/block_scout_web/lib/block_scout_web/views/address_contract_view.ex
  10. 18
      apps/block_scout_web/lib/block_scout_web/views/block_view.ex
  11. 2
      apps/block_scout_web/mix.exs
  12. 14
      apps/block_scout_web/priv/gettext/default.pot
  13. 14
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  14. 1
      apps/block_scout_web/test/block_scout_web/controllers/api/v1/verified_smart_contract_controller_test.exs
  15. 2
      apps/block_scout_web/test/support/conn_case.ex
  16. 2
      apps/block_scout_web/test/support/feature_case.ex
  17. 2
      apps/ethereum_jsonrpc/mix.exs
  18. 5
      apps/explorer/config/config.exs
  19. 2
      apps/explorer/lib/explorer/application.ex
  20. 147
      apps/explorer/lib/explorer/chain.ex
  21. 2
      apps/explorer/lib/explorer/chain/address_token_transfer_csv_exporter.ex
  22. 101
      apps/explorer/lib/explorer/chain/block/reward.ex
  23. 4
      apps/explorer/lib/explorer/chain/transaction.ex
  24. 9
      apps/explorer/lib/explorer/exchange_rates/source/coin_gecko.ex
  25. 6
      apps/explorer/lib/explorer/smart_contract/reader.ex
  26. 79
      apps/explorer/lib/explorer/smart_contract/verifier/constructor_arguments.ex
  27. 2
      apps/explorer/mix.exs
  28. 11
      apps/explorer/priv/repo/migrations/20200424070607_drop_block_rewards_address_hash_address_type_block_hash_index.exs
  29. 17
      apps/explorer/test/explorer/chain/cache/pending_transactions_test.exs
  30. 201
      apps/explorer/test/explorer/chain_test.exs
  31. 1196
      apps/explorer/test/explorer/smart_contract/verifier/constructor_arguments_test.exs
  32. 2
      apps/explorer/test/support/data_case.ex
  33. 47
      apps/indexer/lib/indexer/block/fetcher.ex
  34. 3
      apps/indexer/lib/indexer/fetcher/pending_transaction.ex
  35. 4
      apps/indexer/lib/indexer/fetcher/uncle_block.ex
  36. 2
      apps/indexer/mix.exs
  37. 2
      docker/Dockerfile
  38. 24
      docker/Makefile
  39. 2
      mix.exs
  40. 224
      mix.lock

@ -3,7 +3,7 @@ jobs:
build:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.9.4-node-browsers
- image: circleci/elixir:1.10.2-node-browsers
environment:
MIX_ENV: test
# match POSTGRES_PASSWORD for postgres image below
@ -133,7 +133,7 @@ jobs:
check_formatted:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.9.4
- image: circleci/elixir:1.10.2
environment:
MIX_ENV: test
@ -147,7 +147,7 @@ jobs:
credo:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.9.4
- image: circleci/elixir:1.10.2
environment:
MIX_ENV: test
@ -181,7 +181,7 @@ jobs:
dialyzer:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.9.4
- image: circleci/elixir:1.10.2
environment:
MIX_ENV: test
@ -251,7 +251,7 @@ jobs:
gettext:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.9.4
- image: circleci/elixir:1.10.2
environment:
MIX_ENV: test
@ -290,7 +290,7 @@ jobs:
release:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.9.4
- image: circleci/elixir:1.10.2
environment:
MIX_ENV: prod
@ -316,7 +316,7 @@ jobs:
sobelow:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.9.4
- image: circleci/elixir:1.10.2
environment:
MIX_ENV: test
@ -340,7 +340,7 @@ jobs:
# test_geth_http_websocket:
# docker:
# # Ensure .tool-versions matches
# - image: circleci/elixir:1.9.4-node-browsers
# - image: circleci/elixir:1.10.2-node-browsers
# environment:
# MIX_ENV: test
# # match POSTGRES_PASSWORD for postgres image below
@ -394,7 +394,7 @@ jobs:
# test_geth_mox:
# docker:
# # Ensure .tool-versions matches
# - image: circleci/elixir:1.9.4-node-browsers
# - image: circleci/elixir:1.10.2-node-browsers
# environment:
# MIX_ENV: test
# # match POSTGRES_PASSWORD for postgres image below
@ -448,7 +448,7 @@ jobs:
# test_parity_http_websocket:
# docker:
# # Ensure .tool-versions matches
# - image: circleci/elixir:1.9.4-node-browsers
# - image: circleci/elixir:1.10.2-node-browsers
# environment:
# MIX_ENV: test
# # match POSTGRES_PASSWORD for postgres image below
@ -502,7 +502,7 @@ jobs:
test_parity_mox:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.9.4-node-browsers
- image: circleci/elixir:1.10.2-node-browsers
environment:
MIX_ENV: test
# match POSTGRES_PASSWORD for postgres image below
@ -556,7 +556,7 @@ jobs:
coveralls_merge:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.9.4
- image: circleci/elixir:1.10.2
environment:
MIX_ENV: test

@ -1,3 +1,3 @@
elixir 1.9.4
elixir 1.10.2
erlang 22.2
nodejs 12.14.1

@ -1,13 +1,27 @@
## Current
### Features
### Fixes
### Chore
## 3.1.2-beta
### Features
- [#3089](https://github.com/poanetwork/blockscout/pull/3089) - CoinGecko API coin id environment variable
- [#3069](https://github.com/poanetwork/blockscout/pull/3069) - Make a link to address page on decoded constructor argument of address type
- [#3067](https://github.com/poanetwork/blockscout/pull/3067) - Show proper title of the tile or container for token burnings/mintings instead of "Token Transfer"
- [#3066](https://github.com/poanetwork/blockscout/pull/3066) - ERC-721 token instance page: link to token added
- [#3065](https://github.com/poanetwork/blockscout/pull/3065) - Transactions history chart
### Fixes
- [#3097](https://github.com/poanetwork/blockscout/pull/3097) - Fix contract reader decoding
- [#3095](https://github.com/poanetwork/blockscout/pull/3095) - Fix constructor arguments decoding
- [#3092](https://github.com/poanetwork/blockscout/pull/3092) - Contract verification: constructor arguments search search refinement
- [#3077](https://github.com/poanetwork/blockscout/pull/3077) - Finally speedup pending tx list
- [#3076](https://github.com/poanetwork/blockscout/pull/3076) - Speedup tx list query on address page: check if an address has a reward, check if this is actual payout key of the validator - beneficiary, return only mined txs in tx list query
- [#3071](https://github.com/poanetwork/blockscout/pull/3071) - Speedup list of token transfers per token query
- [#3070](https://github.com/poanetwork/blockscout/pull/3070) - Index creation to blazingly speedup token holders query
- [#3064](https://github.com/poanetwork/blockscout/pull/3064) - Automatically define Block reward contract address in TokenBridge supply module
@ -15,6 +29,10 @@
- [#2756](https://github.com/poanetwork/blockscout/pull/2756) - Improve subquery joins
### Chore
- [#3100](https://github.com/poanetwork/blockscout/pull/3100) - Update npm packages
- [#3099](https://github.com/poanetwork/blockscout/pull/3099) - Remove pending txs cache
- [#3093](https://github.com/poanetwork/blockscout/pull/3093) - Extend list of env vars for Docker setup
- [#3084](https://github.com/poanetwork/blockscout/pull/3084) - Bump Elixir version 1.10.2
- [#3079](https://github.com/poanetwork/blockscout/pull/3079) - Extend optionality of websockets to Geth

File diff suppressed because it is too large Load Diff

@ -19,7 +19,7 @@
"eslint": "eslint js/**"
},
"dependencies": {
"@fortawesome/fontawesome-free": "^5.1.0-4",
"@fortawesome/fontawesome-free": "5.1.0-4",
"awesomplete": "^1.1.5",
"bignumber.js": "^9.0.0",
"bootstrap": "^4.3.1",

@ -36,7 +36,7 @@ defmodule BlockScoutWeb.AddressTransactionController do
|> Keyword.merge(paging_options(params))
|> Keyword.merge(current_filter(params))
results_plus_one = Chain.address_to_transactions_with_rewards(address_hash, options)
results_plus_one = Chain.address_to_mined_transactions_with_rewards(address_hash, options)
{results, next_page} = split_list_by_page(results_plus_one)
next_page_url =
@ -60,7 +60,6 @@ defmodule BlockScoutWeb.AddressTransactionController do
View.render_to_string(
TransactionView,
"_emission_reward_tile.html",
conn: conn,
current_address: address,
emission_funds: emission_reward,
validator: validator_reward

@ -190,11 +190,15 @@ defmodule BlockScoutWeb.Notifier do
defp broadcast_rewards(rewards) do
preloaded_rewards = Repo.preload(rewards, [:address, :block])
emission_reward = Enum.find(preloaded_rewards, fn reward -> reward.address_type == :emission_funds end)
Enum.each(preloaded_rewards, fn reward ->
preloaded_rewards_except_emission =
Enum.reject(preloaded_rewards, fn reward -> reward.address_type == :emission_funds end)
Enum.each(preloaded_rewards_except_emission, fn reward ->
Endpoint.broadcast("rewards:#{to_string(reward.address_hash)}", "new_reward", %{
emission_funds: Enum.at(preloaded_rewards, 1),
validator: Enum.at(preloaded_rewards, 0)
emission_funds: emission_reward,
validator: reward
})
end)
end

@ -146,7 +146,7 @@
<h2 class="card-title balance-card-title"><%= gettext "Block Rewards" %></h2>
<div class="text-right" style="margin-left: 50%;" data-toggle="tooltip" data-placement="top" title="" data-original-title="Amount of distributed reward. Miners receive a static block reward + Tx fees + uncle fees.">
<%= for block_reward <- @block.rewards do %>
<p class="address-current-balance"><%= block_reward_text(block_reward) %> <span class="text-muted"><%= format_wei_value(block_reward.reward, :ether) %></span></p>
<p class="address-current-balance"><%= block_reward_text(block_reward, @block.miner.hash) %> <span class="text-muted"><%= format_wei_value(block_reward.reward, :ether) %></span></p>
<% end %>
</div>
<% else %>

@ -33,17 +33,13 @@ defmodule BlockScoutWeb.AddressContractView do
|> decode_data(input_types)
|> Enum.zip(constructor_abi["inputs"])
|> Enum.reduce({0, "#{contract.constructor_arguments}\n\n"}, fn {val, %{"type" => type}}, {count, acc} ->
address_hash = "0x" <> Base.encode16(val, case: :lower)
address =
case Chain.string_to_address_hash(address_hash) do
{:ok, address} -> address
_ -> nil
end
formatted_val =
cond do
type =~ "address" ->
address_hash = "0x" <> Base.encode16(val, case: :lower)
address = get_address(address_hash)
get_formatted_address_data(address, address_hash, conn)
type =~ "bytes" ->
@ -61,6 +57,13 @@ defmodule BlockScoutWeb.AddressContractView do
_ -> contract.constructor_arguments
end
defp get_address(address_hash) do
case Chain.string_to_address_hash(address_hash) do
{:ok, address} -> address
_ -> nil
end
end
defp get_formatted_address_data(address, address_hash, conn) do
if address != nil do
"<a href=" <> address_path(conn, :show, address) <> ">" <> address_hash <> "</a>"

@ -52,15 +52,25 @@ defmodule BlockScoutWeb.BlockView do
def show_reward?([]), do: false
def show_reward?(_), do: true
def block_reward_text(%Reward{address_type: :validator}) do
gettext("Miner Reward")
def block_reward_text(%Reward{address_hash: beneficiary_address, address_type: :validator}, block_miner_address) do
if Application.get_env(:explorer, Explorer.Chain.Block.Reward, %{})[:keys_manager_contract_address] do
%{payout_key: block_miner_payout_address} = Reward.get_validator_payout_key_by_mining(block_miner_address)
if beneficiary_address == block_miner_payout_address do
gettext("Miner Reward")
else
gettext("Chore Reward")
end
else
gettext("Miner Reward")
end
end
def block_reward_text(%Reward{address_type: :emission_funds}) do
def block_reward_text(%Reward{address_type: :emission_funds}, _block_miner_address) do
gettext("Emission Reward")
end
def block_reward_text(%Reward{address_type: :uncle}) do
def block_reward_text(%Reward{address_type: :uncle}, _block_miner_address) do
gettext("Uncle Reward")
end

@ -15,7 +15,7 @@ defmodule BlockScoutWeb.Mixfile do
plt_add_deps: :transitive,
ignore_warnings: "../../.dialyzer-ignore"
],
elixir: "~> 1.9",
elixir: "~> 1.10",
elixirc_paths: elixirc_paths(Mix.env()),
lockfile: "../../mix.lock",
package: package(),

@ -594,7 +594,7 @@ msgid "Emission Contract"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/block_view.ex:60
#: lib/block_scout_web/views/block_view.ex:70
msgid "Emission Reward"
msgstr ""
@ -1042,13 +1042,11 @@ msgstr ""
#: lib/block_scout_web/templates/chain/show.html.eex:52
#: lib/block_scout_web/templates/layout/app.html.eex:30
#: lib/block_scout_web/views/address_view.ex:127
#: lib/block_scout_web/views/address_view.ex:127
msgid "Market Cap"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:221
#: lib/block_scout_web/views/transaction_view.ex:221
msgid "Max of"
msgstr ""
@ -1058,7 +1056,8 @@ msgid "Method Id"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/block_view.ex:56
#: lib/block_scout_web/views/block_view.ex:60
#: lib/block_scout_web/views/block_view.ex:65
msgid "Miner Reward"
msgstr ""
@ -1524,7 +1523,7 @@ msgid "UTF-8"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/block_view.ex:64
#: lib/block_scout_web/views/block_view.ex:74
msgid "Uncle Reward"
msgstr ""
@ -1904,3 +1903,8 @@ msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:316
msgid "Token Minting"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/block_view.ex:62
msgid "Chore Reward"
msgstr ""

@ -594,7 +594,7 @@ msgid "Emission Contract"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/block_view.ex:60
#: lib/block_scout_web/views/block_view.ex:70
msgid "Emission Reward"
msgstr ""
@ -1042,13 +1042,11 @@ msgstr ""
#: lib/block_scout_web/templates/chain/show.html.eex:52
#: lib/block_scout_web/templates/layout/app.html.eex:30
#: lib/block_scout_web/views/address_view.ex:127
#: lib/block_scout_web/views/address_view.ex:127
msgid "Market Cap"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:221
#: lib/block_scout_web/views/transaction_view.ex:221
msgid "Max of"
msgstr ""
@ -1058,7 +1056,8 @@ msgid "Method Id"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/block_view.ex:56
#: lib/block_scout_web/views/block_view.ex:60
#: lib/block_scout_web/views/block_view.ex:65
msgid "Miner Reward"
msgstr ""
@ -1524,7 +1523,7 @@ msgid "UTF-8"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/block_view.ex:64
#: lib/block_scout_web/views/block_view.ex:74
msgid "Uncle Reward"
msgstr ""
@ -1904,3 +1903,8 @@ msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:316
msgid "Token Minting"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/block_view.ex:62
msgid "Chore Reward"
msgstr ""

@ -2,6 +2,7 @@ defmodule BlockScoutWeb.API.V1.VerifiedControllerTest do
use BlockScoutWeb.ConnCase
alias Explorer.Factory
# alias Explorer.Chain.DecompiledSmartContract
# import Ecto.Query,

@ -44,8 +44,6 @@ defmodule BlockScoutWeb.ConnCase do
Supervisor.restart_child(Explorer.Supervisor, Explorer.Chain.Cache.Transactions.child_id())
Supervisor.terminate_child(Explorer.Supervisor, Explorer.Chain.Cache.Accounts.child_id())
Supervisor.restart_child(Explorer.Supervisor, Explorer.Chain.Cache.Accounts.child_id())
Supervisor.terminate_child(Explorer.Supervisor, Explorer.Chain.Cache.PendingTransactions.child_id())
Supervisor.restart_child(Explorer.Supervisor, Explorer.Chain.Cache.PendingTransactions.child_id())
{:ok, conn: Phoenix.ConnTest.build_conn()}
end

@ -31,8 +31,6 @@ defmodule BlockScoutWeb.FeatureCase do
Supervisor.restart_child(Explorer.Supervisor, Explorer.Chain.Cache.Transactions.child_id())
Supervisor.terminate_child(Explorer.Supervisor, Explorer.Chain.Cache.Accounts.child_id())
Supervisor.restart_child(Explorer.Supervisor, Explorer.Chain.Cache.Accounts.child_id())
Supervisor.terminate_child(Explorer.Supervisor, Explorer.Chain.Cache.PendingTransactions.child_id())
Supervisor.restart_child(Explorer.Supervisor, Explorer.Chain.Cache.PendingTransactions.child_id())
metadata = Phoenix.Ecto.SQL.Sandbox.metadata_for(Explorer.Repo, self())
{:ok, session} = Wallaby.start_session(metadata: metadata)

@ -15,7 +15,7 @@ defmodule EthereumJsonrpc.MixProject do
plt_add_apps: [:mix],
ignore_warnings: "../../.dialyzer-ignore"
],
elixir: "~> 1.9",
elixir: "~> 1.10",
elixirc_paths: elixirc_paths(Mix.env()),
lockfile: "../../mix.lock",
preferred_cli_env: [

@ -9,6 +9,7 @@ use Mix.Config
config :explorer,
ecto_repos: [Explorer.Repo],
coin: System.get_env("COIN") || "POA",
coingecko_coin_id: System.get_env("COINGECKO_COIN_ID"),
token_functions_reader_max_retries: 3,
allowed_evm_versions:
System.get_env("ALLOWED_EVM_VERSIONS") ||
@ -137,6 +138,10 @@ else
config :explorer, Explorer.Validator.MetadataProcessor, enabled: false
end
config :explorer, Explorer.Chain.Block.Reward,
validators_contract_address: System.get_env("VALIDATORS_CONTRACT"),
keys_manager_contract_address: System.get_env("KEYS_MANAGER_CONTRACT")
config :explorer, Explorer.Staking.PoolsReader,
validators_contract_address: System.get_env("POS_VALIDATORS_CONTRACT"),
staking_contract_address: System.get_env("POS_STAKING_CONTRACT")

@ -15,7 +15,6 @@ defmodule Explorer.Application do
BlockNumber,
Blocks,
NetVersion,
PendingTransactions,
TransactionCount,
Transactions,
Uncles
@ -59,7 +58,6 @@ defmodule Explorer.Application do
con_cache_child_spec(RSK.cache_name(), ttl_check_interval: :timer.minutes(1), global_ttl: :timer.minutes(30)),
Transactions,
Accounts,
PendingTransactions,
Uncles
]

@ -18,7 +18,8 @@ defmodule Explorer.Chain do
union: 2,
union_all: 2,
where: 2,
where: 3
where: 3,
select: 3
]
import EthereumJSONRPC, only: [integer_to_quantity: 1, fetch_block_internal_transactions: 2]
@ -58,7 +59,6 @@ defmodule Explorer.Chain do
BlockCount,
BlockNumber,
Blocks,
PendingTransactions,
TransactionCount,
Transactions,
Uncles
@ -314,44 +314,64 @@ defmodule Explorer.Chain do
the `block_number` and `index` that are passed.
"""
@spec address_to_transactions_with_rewards(Hash.Address.t(), [paging_options | necessity_by_association_option]) :: [
Transaction.t()
]
def address_to_transactions_with_rewards(address_hash, options \\ []) when is_list(options) do
@spec address_to_mined_transactions_with_rewards(Hash.Address.t(), [paging_options | necessity_by_association_option]) ::
[
Transaction.t()
]
def address_to_mined_transactions_with_rewards(address_hash, options \\ []) when is_list(options) do
paging_options = Keyword.get(options, :paging_options, @default_paging_options)
if Application.get_env(:block_scout_web, BlockScoutWeb.Chain)[:has_emission_funds] do
blocks_range = address_to_transactions_tasks_range_of_blocks(address_hash, options)
rewards_task =
Task.async(fn -> Reward.fetch_emission_rewards_tuples(address_hash, paging_options, blocks_range) end)
cond do
Keyword.get(options, :direction) == :from ->
address_to_mined_transactions_without_rewards(address_hash, options)
[rewards_task | address_to_transactions_tasks(address_hash, options)]
|> wait_for_address_transactions()
|> Enum.sort_by(fn item ->
case item do
{%Reward{} = emission_reward, _} ->
{-emission_reward.block.number, 1}
address_has_rewards?(address_hash) ->
%{payout_key: block_miner_payout_address} = Reward.get_validator_payout_key_by_mining(address_hash)
item ->
{-item.block_number, -item.index}
end
end)
|> Enum.dedup_by(fn item ->
case item do
{%Reward{} = emission_reward, _} ->
{emission_reward.block_hash, emission_reward.address_hash, emission_reward.address_type}
if block_miner_payout_address && address_hash == block_miner_payout_address do
transactions_with_rewards_results(address_hash, options, paging_options)
else
address_to_mined_transactions_without_rewards(address_hash, options)
end
transaction ->
transaction.hash
end
end)
|> Enum.take(paging_options.page_size)
true ->
address_to_mined_transactions_without_rewards(address_hash, options)
end
else
address_to_transactions_without_rewards(address_hash, options)
address_to_mined_transactions_without_rewards(address_hash, options)
end
end
defp transactions_with_rewards_results(address_hash, options, paging_options) do
blocks_range = address_to_transactions_tasks_range_of_blocks(address_hash, options)
rewards_task =
Task.async(fn -> Reward.fetch_emission_rewards_tuples(address_hash, paging_options, blocks_range) end)
[rewards_task | address_to_mined_transactions_tasks(address_hash, options)]
|> wait_for_address_transactions()
|> Enum.sort_by(fn item ->
case item do
{%Reward{} = emission_reward, _} ->
{-emission_reward.block.number, 1}
item ->
{-item.block_number, -item.index}
end
end)
|> Enum.dedup_by(fn item ->
case item do
{%Reward{} = emission_reward, _} ->
{emission_reward.block_hash, emission_reward.address_hash, emission_reward.address_type}
transaction ->
transaction.hash
end
end)
|> Enum.take(paging_options.page_size)
end
def address_to_transactions_without_rewards(address_hash, options) do
paging_options = Keyword.get(options, :paging_options, @default_paging_options)
@ -363,12 +383,33 @@ defmodule Explorer.Chain do
|> Enum.take(paging_options.page_size)
end
def address_to_mined_transactions_without_rewards(address_hash, options) do
paging_options = Keyword.get(options, :paging_options, @default_paging_options)
address_hash
|> address_to_mined_transactions_tasks(options)
|> wait_for_address_transactions()
|> Enum.sort_by(&{&1.block_number, &1.index}, &>=/2)
|> Enum.dedup_by(& &1.hash)
|> Enum.take(paging_options.page_size)
end
defp address_to_transactions_tasks_query(options) do
options
|> Keyword.get(:paging_options, @default_paging_options)
|> fetch_transactions()
end
defp transactions_block_numbers_at_address(address_hash, options) do
direction = Keyword.get(options, :direction)
options
|> address_to_transactions_tasks_query()
|> Transaction.not_pending_transactions()
|> select([t], t.block_number)
|> Transaction.matching_address_queries_list(direction, address_hash)
end
defp address_to_transactions_tasks(address_hash, options) do
direction = Keyword.get(options, :direction)
necessity_by_association = Keyword.get(options, :necessity_by_association, %{})
@ -380,21 +421,30 @@ defmodule Explorer.Chain do
|> Enum.map(fn query -> Task.async(fn -> Repo.all(query) end) end)
end
defp address_to_transactions_tasks_range_of_blocks(address_hash, options) do
defp address_to_mined_transactions_tasks(address_hash, options) do
direction = Keyword.get(options, :direction)
necessity_by_association = Keyword.get(options, :necessity_by_association, %{})
options
|> address_to_transactions_tasks_query()
|> Transaction.not_pending_transactions()
|> join_associations(necessity_by_association)
|> Transaction.matching_address_queries_list(direction, address_hash)
|> Enum.map(fn query -> Task.async(fn -> Repo.all(query) end) end)
end
def address_to_transactions_tasks_range_of_blocks(address_hash, options) do
extremums_list =
options
|> address_to_transactions_tasks_query()
|> Transaction.matching_address_queries_list(direction, address_hash)
address_hash
|> transactions_block_numbers_at_address(options)
|> Enum.map(fn query ->
max_query =
extremum_query =
from(
q in subquery(query),
select: %{min_block_number: min(q.block_number), max_block_number: max(q.block_number)}
)
max_query
extremum_query
|> Repo.one!()
end)
@ -2360,24 +2410,6 @@ defmodule Explorer.Chain do
necessity_by_association = Keyword.get(options, :necessity_by_association, %{})
paging_options = Keyword.get(options, :paging_options, @default_paging_options)
if is_nil(paging_options.key) do
paging_options.page_size
|> PendingTransactions.take_enough()
|> case do
nil ->
pending_transactions = fetch_recent_pending_transactions(paging_options, necessity_by_association)
PendingTransactions.update(pending_transactions)
pending_transactions
pending_transactions ->
pending_transactions
end
else
fetch_recent_pending_transactions(paging_options, necessity_by_association)
end
end
defp fetch_recent_pending_transactions(paging_options, necessity_by_association) do
Transaction
|> page_pending_transaction(paging_options)
|> limit(^paging_options.page_size)
@ -3216,6 +3248,13 @@ defmodule Explorer.Chain do
Repo.exists?(query)
end
@spec address_has_rewards?(Address.t()) :: boolean()
def address_has_rewards?(address_hash) do
query = from(r in Reward, where: r.address_hash == ^address_hash)
Repo.exists?(query)
end
@spec address_tokens_with_balance(Hash.Address.t(), [any()]) :: []
def address_tokens_with_balance(address_hash, paging_options \\ []) do
address_hash

@ -36,7 +36,7 @@ defmodule Explorer.Chain.AddressTokenTransferCsvExporter do
transactions =
address_hash
|> Chain.address_to_transactions_with_rewards(options)
|> Chain.address_to_mined_transactions_with_rewards(options)
|> Enum.filter(fn transaction -> Enum.count(transaction.token_transfers) > 0 end)
new_acc = transactions ++ acc

@ -5,12 +5,36 @@ defmodule Explorer.Chain.Block.Reward do
use Explorer.Schema
alias Explorer.Chain
alias Explorer.Chain.Block.Reward.AddressType
alias Explorer.Chain.{Address, Block, Hash, Wei}
alias Explorer.{PagingOptions, Repo}
alias Explorer.SmartContract.Reader
@required_attrs ~w(address_hash address_type block_hash reward)a
@get_payout_by_mining_abi %{
"type" => "function",
"stateMutability" => "view",
"payable" => false,
"outputs" => [%{"type" => "address", "name" => ""}],
"name" => "getPayoutByMining",
"inputs" => [%{"type" => "address", "name" => ""}],
"constant" => true
}
@is_validator_abi %{
"type" => "function",
"stateMutability" => "view",
"payable" => false,
"outputs" => [%{"type" => "bool", "name" => ""}],
"name" => "isValidator",
"inputs" => [%{"type" => "address", "name" => ""}],
"constant" => true
}
@empty_address "0x0000000000000000000000000000000000000000"
@typedoc """
The validation reward given related to a block.
@ -114,6 +138,83 @@ defmodule Explorer.Chain.Block.Reward do
end
end
defp is_validator(mining_key) do
validators_contract_address =
Application.get_env(:explorer, Explorer.Chain.Block.Reward, %{})[:validators_contract_address]
if validators_contract_address do
is_validator_params = %{"isValidator" => [mining_key.bytes]}
call_contract(validators_contract_address, @is_validator_abi, is_validator_params)
else
nil
end
end
def get_validator_payout_key_by_mining(mining_key) do
is_validator = is_validator(mining_key)
if is_validator do
keys_manager_contract_address =
Application.get_env(:explorer, Explorer.Chain.Block.Reward, %{})[:keys_manager_contract_address]
if keys_manager_contract_address do
payout_key =
if keys_manager_contract_address do
get_payout_by_mining_params = %{"getPayoutByMining" => [mining_key.bytes]}
payout_key_hash =
call_contract(keys_manager_contract_address, @get_payout_by_mining_abi, get_payout_by_mining_params)
if payout_key_hash == @empty_address do
mining_key
else
{:ok, payout_key} = Chain.string_to_address_hash(payout_key_hash)
payout_key
end
else
mining_key
end
%{is_validator: is_validator, payout_key: payout_key}
else
%{is_validator: is_validator, payout_key: mining_key}
end
else
%{is_validator: is_validator, payout_key: mining_key}
end
end
defp call_contract(address, abi, params) do
abi = [abi]
method_name =
params
|> Enum.map(fn {key, _value} -> key end)
|> List.first()
value =
case Reader.query_contract(address, abi, params) do
%{^method_name => {:ok, [result]}} -> result
_ -> @empty_address
end
type =
abi
|> Enum.at(0)
|> Map.get("outputs", [])
|> Enum.at(0)
|> Map.get("type", "")
case type do
"address" ->
"0x" <> Base.encode16(value, case: :lower)
_ ->
value
end
end
defp join_associations(query) do
query
|> preload(:address)

@ -501,6 +501,10 @@ defmodule Explorer.Chain.Transaction do
]
end
def not_pending_transactions(query) do
where(query, [t], not is_nil(t.block_number))
end
@collated_fields ~w(block_number cumulative_gas_used gas_used index)a
@collated_message "can't be blank when the transaction is collated into a block"

@ -44,7 +44,14 @@ defmodule Explorer.ExchangeRates.Source.CoinGecko do
@impl Source
def source_url do
{:ok, id} = coin_id()
explicit_coin_id = Application.get_env(:explorer, :coingecko_coin_id)
{:ok, id} =
if explicit_coin_id do
{:ok, explicit_coin_id}
else
coin_id()
end
"#{base_url()}/coins/#{id}"
end

@ -292,6 +292,10 @@ defmodule Explorer.SmartContract.Reader do
@spec bytes_to_string(<<_::_*8>>) :: String.t()
defp bytes_to_string(value) do
Hash.to_string(%Hash{byte_count: byte_size(value), bytes: value})
if value do
Hash.to_string(%Hash{byte_count: byte_size(value), bytes: value})
else
"0x"
end
end
end

@ -74,12 +74,15 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArguments do
constructor_arguments =
remove_require_messages_from_constructor_arguments(contract_source_code, constructor_arguments, contract_name)
check_func_result = check_func.(constructor_arguments)
filtered_constructor_arguments =
remove_keccak256_strings_from_constructor_arguments(contract_source_code, constructor_arguments, contract_name)
check_func_result = check_func.(filtered_constructor_arguments)
if check_func_result do
check_func_result
else
extract_constructor_arguments(constructor_arguments, check_func, contract_source_code, contract_name)
extract_constructor_arguments(filtered_constructor_arguments, check_func, contract_source_code, contract_name)
end
end
@ -107,6 +110,26 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArguments do
end)
end
def remove_keccak256_strings_from_constructor_arguments(contract_source_code, constructor_arguments, contract_name) do
all_strings =
contract_source_code
|> extract_strings_from_constructor(contract_name)
strings_list =
all_strings
|> Enum.reverse()
Enum.reduce(strings_list, constructor_arguments, fn msg, pure_constructor_arguments ->
case String.split(pure_constructor_arguments, msg, parts: 2) do
[_, constructor_arguments_part] ->
constructor_arguments_part
[_] ->
pure_constructor_arguments
end
end)
end
def find_constructor_arguments(address_hash, abi, contract_source_code, contract_name) do
creation_code =
address_hash
@ -146,6 +169,18 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArguments do
if messages_list, do: messages_list, else: []
end
def extract_strings_from_constructor(contract_source_code, _contract_name) do
keccak256_contents = find_all_strings(contract_source_code)
strings_list =
Enum.reduce(keccak256_contents, [], fn keccak256_content, strs ->
str = get_keccak256_string_hex(keccak256_content)
if str, do: [str | strs], else: strs
end)
if strings_list, do: strings_list, else: []
end
def find_constructor_content(contract_source_code) do
case String.split(contract_source_code, "constructor", parts: 2) do
[_, right_from_contstructor] ->
@ -158,9 +193,9 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArguments do
end
end
def find_require_in_constructor(constructor) do
if constructor do
[_ | requires] = String.split(constructor, "require")
def find_all_requires(contract_source_code) do
if contract_source_code do
[_ | requires] = String.split(contract_source_code, "require")
Enum.reduce(requires, [], fn right_from_require, requires_list ->
[_ | [right_from_require_inside]] = String.split(right_from_require, "(", parts: 2)
@ -172,14 +207,20 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArguments do
end
end
def find_all_requires(contract_source_code) do
def find_all_strings(contract_source_code) do
if contract_source_code do
[_ | requires] = String.split(contract_source_code, "require")
Enum.reduce(requires, [], fn right_from_require, requires_list ->
[_ | [right_from_require_inside]] = String.split(right_from_require, "(", parts: 2)
[require_content | _] = String.split(right_from_require_inside, ");", parts: 2)
[require_content | requires_list]
[_ | keccak256s] = String.split(contract_source_code, "keccak256")
Enum.reduce(keccak256s, [], fn right_from_keccak256, keccak256s_list ->
parts = String.split(right_from_keccak256, "\"")
if Enum.count(parts) >= 3 do
[_ | [right_from_keccak256_inside]] = String.split(right_from_keccak256, "\"", parts: 2)
[keccak256_content | _] = String.split(right_from_keccak256_inside, "\"", parts: 2)
[keccak256_content | keccak256s_list]
else
keccak256s_list
end
end)
else
[]
@ -203,4 +244,18 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArguments do
nil
end
end
def get_keccak256_string_hex(keccak256_content) do
if keccak256_content !== "" do
keccak256_content
|> String.trim()
|> String.trim_leading("\"")
|> String.trim_trailing("\"")
|> String.trim_leading("'")
|> String.trim_trailing("'")
|> Base.encode16(case: :lower)
else
nil
end
end
end

@ -15,7 +15,7 @@ defmodule Explorer.Mixfile do
plt_add_apps: ~w(ex_unit mix)a,
ignore_warnings: "../../.dialyzer-ignore"
],
elixir: "~> 1.9",
elixir: "~> 1.10",
elixirc_paths: elixirc_paths(Mix.env()),
lockfile: "../../mix.lock",
package: package(),

@ -0,0 +1,11 @@
defmodule Explorer.Repo.Migrations.DropBlockRewardsAddressHashAddressTypeBlockHashIndex do
use Ecto.Migration
def change do
drop_if_exists(
index(:block_rewards, [:address_hash, :block_hash, :address_type],
name: "block_rewards_address_hash_address_type_block_hash_index"
)
)
end
end

@ -1,17 +0,0 @@
defmodule Explorer.Chain.Cache.PendingTransactionsTest do
use Explorer.DataCase
alias Explorer.Chain.Cache.PendingTransactions
describe "update_pending/1" do
test "adds a new pending transaction" do
transaction = insert(:transaction, block_hash: nil, error: nil)
PendingTransactions.update([transaction])
assert [%{hash: pending_transaction_hash}] = PendingTransactions.all()
assert transaction.hash == pending_transaction_hash
end
end
end

@ -383,13 +383,13 @@ defmodule Explorer.ChainTest do
end
end
describe "address_to_transactions_with_rewards/2" do
describe "address_to_mined_transactions_with_rewards/2" do
test "without transactions" do
%Address{hash: address_hash} = insert(:address)
assert Repo.aggregate(Transaction, :count, :hash) == 0
assert [] == Chain.address_to_transactions_with_rewards(address_hash)
assert [] == Chain.address_to_mined_transactions_with_rewards(address_hash)
end
test "with from transactions" do
@ -401,7 +401,7 @@ defmodule Explorer.ChainTest do
|> with_block()
assert [transaction] ==
Chain.address_to_transactions_with_rewards(address_hash, direction: :from)
Chain.address_to_mined_transactions_with_rewards(address_hash, direction: :from)
|> Repo.preload([:block, :to_address, :from_address])
end
@ -414,7 +414,7 @@ defmodule Explorer.ChainTest do
|> with_block()
assert [transaction] ==
Chain.address_to_transactions_with_rewards(address_hash, direction: :to)
Chain.address_to_mined_transactions_with_rewards(address_hash, direction: :to)
|> Repo.preload([:block, :to_address, :from_address])
end
@ -428,7 +428,7 @@ defmodule Explorer.ChainTest do
# only contains "from" transaction
assert [transaction] ==
Chain.address_to_transactions_with_rewards(address_hash, direction: :from)
Chain.address_to_mined_transactions_with_rewards(address_hash, direction: :from)
|> Repo.preload([:block, :to_address, :from_address])
end
@ -441,7 +441,7 @@ defmodule Explorer.ChainTest do
|> with_block()
assert [transaction] ==
Chain.address_to_transactions_with_rewards(address_hash, direction: :to)
Chain.address_to_mined_transactions_with_rewards(address_hash, direction: :to)
|> Repo.preload([:block, :to_address, :from_address])
end
@ -460,7 +460,7 @@ defmodule Explorer.ChainTest do
|> with_block(block)
assert [transaction2, transaction1] ==
Chain.address_to_transactions_with_rewards(address_hash)
Chain.address_to_mined_transactions_with_rewards(address_hash)
|> Repo.preload([:block, :to_address, :from_address])
end
@ -481,7 +481,7 @@ defmodule Explorer.ChainTest do
transaction_index: transaction.index
)
assert [] == Chain.address_to_transactions_with_rewards(address.hash)
assert [] == Chain.address_to_mined_transactions_with_rewards(address.hash)
end
test "returns transactions that have token transfers for the given to_address" do
@ -499,7 +499,7 @@ defmodule Explorer.ChainTest do
)
assert [transaction.hash] ==
Chain.address_to_transactions_with_rewards(address_hash)
Chain.address_to_mined_transactions_with_rewards(address_hash)
|> Enum.map(& &1.hash)
end
@ -519,7 +519,7 @@ defmodule Explorer.ChainTest do
assert second_page_hashes ==
address_hash
|> Chain.address_to_transactions_with_rewards(
|> Chain.address_to_mined_transactions_with_rewards(
paging_options: %PagingOptions{
key: {block_number, index},
page_size: 2
@ -568,7 +568,7 @@ defmodule Explorer.ChainTest do
result =
address_hash
|> Chain.address_to_transactions_with_rewards()
|> Chain.address_to_mined_transactions_with_rewards()
|> Enum.map(& &1.hash)
assert [fourth, third, second, first, sixth, fifth] == result
@ -577,8 +577,15 @@ defmodule Explorer.ChainTest do
test "with emission rewards" do
Application.put_env(:block_scout_web, BlockScoutWeb.Chain, has_emission_funds: true)
Application.put_env(:explorer, Explorer.Chain.Block.Reward,
validators_contract_address: "0x0000000000000000000000000000000000000005",
keys_manager_contract_address: "0x0000000000000000000000000000000000000006"
)
block = insert(:block)
block_miner_hash_string = Base.encode16(block.miner_hash.bytes, case: :lower)
insert(
:reward,
address_hash: block.miner_hash,
@ -593,16 +600,51 @@ defmodule Explorer.ChainTest do
address_type: :emission_funds
)
assert [{_, _}] = Chain.address_to_transactions_with_rewards(block.miner.hash)
# isValidator => true
expect(
EthereumJSONRPC.Mox,
:json_rpc,
fn [%{id: id, method: _, params: [%{data: _, to: _}, _]}], _options ->
{:ok,
[%{id: id, jsonrpc: "2.0", result: "0x0000000000000000000000000000000000000000000000000000000000000001"}]}
end
)
Application.put_env(:block_scout_web, BlockScoutWeb.Chain, has_emission_funds: false)
# getPayoutByMining => 0x0000000000000000000000000000000000000001
expect(
EthereumJSONRPC.Mox,
:json_rpc,
fn [%{id: id, method: _, params: [%{data: _, to: _}, _]}], _options ->
{:ok, [%{id: id, result: "0x000000000000000000000000" <> block_miner_hash_string}]}
end
)
res = Chain.address_to_mined_transactions_with_rewards(block.miner.hash)
assert [{_, _}] = res
on_exit(fn ->
Application.put_env(:block_scout_web, BlockScoutWeb.Chain, has_emission_funds: false)
Application.put_env(:explorer, Explorer.Chain.Block.Reward,
validators_contract_address: nil,
keys_manager_contract_address: nil
)
end)
end
test "with emission rewards and transactions" do
Application.put_env(:block_scout_web, BlockScoutWeb.Chain, has_emission_funds: true)
Application.put_env(:explorer, Explorer.Chain.Block.Reward,
validators_contract_address: "0x0000000000000000000000000000000000000005",
keys_manager_contract_address: "0x0000000000000000000000000000000000000006"
)
block = insert(:block)
block_miner_hash_string = Base.encode16(block.miner_hash.bytes, case: :lower)
insert(
:reward,
address_hash: block.miner_hash,
@ -618,13 +660,39 @@ defmodule Explorer.ChainTest do
)
:transaction
|> insert(from_address: block.miner)
|> insert(to_address: block.miner)
|> with_block(block)
|> Repo.preload(:token_transfers)
assert [_, {_, _}] = Chain.address_to_transactions_with_rewards(block.miner.hash, direction: :from)
# isValidator => true
expect(
EthereumJSONRPC.Mox,
:json_rpc,
fn [%{id: id, method: _, params: [%{data: _, to: _}, _]}], _options ->
{:ok,
[%{id: id, jsonrpc: "2.0", result: "0x0000000000000000000000000000000000000000000000000000000000000001"}]}
end
)
Application.put_env(:block_scout_web, BlockScoutWeb.Chain, has_emission_funds: false)
# getPayoutByMining => 0x0000000000000000000000000000000000000001
expect(
EthereumJSONRPC.Mox,
:json_rpc,
fn [%{id: id, method: _, params: [%{data: _, to: _}, _]}], _options ->
{:ok, [%{id: id, result: "0x000000000000000000000000" <> block_miner_hash_string}]}
end
)
assert [_, {_, _}] = Chain.address_to_mined_transactions_with_rewards(block.miner.hash, direction: :to)
on_exit(fn ->
Application.put_env(:block_scout_web, BlockScoutWeb.Chain, has_emission_funds: false)
Application.put_env(:explorer, Explorer.Chain.Block.Reward,
validators_contract_address: nil,
keys_manager_contract_address: nil
)
end)
end
test "with transactions if rewards are not in the range of blocks" do
@ -651,7 +719,7 @@ defmodule Explorer.ChainTest do
|> with_block()
|> Repo.preload(:token_transfers)
assert [_] = Chain.address_to_transactions_with_rewards(block.miner.hash, direction: :from)
assert [_] = Chain.address_to_mined_transactions_with_rewards(block.miner.hash, direction: :from)
Application.put_env(:block_scout_web, BlockScoutWeb.Chain, has_emission_funds: false)
end
@ -675,7 +743,104 @@ defmodule Explorer.ChainTest do
address_type: :emission_funds
)
assert [] == Chain.address_to_transactions_with_rewards(block.miner.hash)
assert [] == Chain.address_to_mined_transactions_with_rewards(block.miner.hash)
end
end
describe "address_to_transactions_tasks_range_of_blocks/2" do
test "returns empty extremums if no transactions" do
address = insert(:address)
extremums = Chain.address_to_transactions_tasks_range_of_blocks(address.hash, [])
assert extremums == %{
:min_block_number => nil,
:max_block_number => 0
}
end
test "returns correct extremums for from_address" do
address = insert(:address)
:transaction
|> insert(from_address: address)
|> with_block(insert(:block, number: 1000))
extremums = Chain.address_to_transactions_tasks_range_of_blocks(address.hash, [])
assert extremums == %{
:min_block_number => 1000,
:max_block_number => 1000
}
end
test "returns correct extremums for to_address" do
address = insert(:address)
:transaction
|> insert(to_address: address)
|> with_block(insert(:block, number: 1000))
extremums = Chain.address_to_transactions_tasks_range_of_blocks(address.hash, [])
assert extremums == %{
:min_block_number => 1000,
:max_block_number => 1000
}
end
test "returns correct extremums for created_contract_address" do
address = insert(:address)
:transaction
|> insert(created_contract_address: address)
|> with_block(insert(:block, number: 1000))
extremums = Chain.address_to_transactions_tasks_range_of_blocks(address.hash, [])
assert extremums == %{
:min_block_number => 1000,
:max_block_number => 1000
}
end
test "returns correct extremums for multiple number of transactions" do
address = insert(:address)
:transaction
|> insert(created_contract_address: address)
|> with_block(insert(:block, number: 1000))
:transaction
|> insert(created_contract_address: address)
|> with_block(insert(:block, number: 999))
:transaction
|> insert(created_contract_address: address)
|> with_block(insert(:block, number: 1003))
:transaction
|> insert(from_address: address)
|> with_block(insert(:block, number: 1001))
:transaction
|> insert(from_address: address)
|> with_block(insert(:block, number: 1004))
:transaction
|> insert(to_address: address)
|> with_block(insert(:block, number: 1002))
:transaction
|> insert(to_address: address)
|> with_block(insert(:block, number: 998))
extremums = Chain.address_to_transactions_tasks_range_of_blocks(address.hash, [])
assert extremums == %{
:min_block_number => 998,
:max_block_number => 1004
}
end
end

File diff suppressed because one or more lines are too long

@ -47,8 +47,6 @@ defmodule Explorer.DataCase do
Supervisor.restart_child(Explorer.Supervisor, Explorer.Chain.Cache.Transactions.child_id())
Supervisor.terminate_child(Explorer.Supervisor, Explorer.Chain.Cache.Accounts.child_id())
Supervisor.restart_child(Explorer.Supervisor, Explorer.Chain.Cache.Accounts.child_id())
Supervisor.terminate_child(Explorer.Supervisor, Explorer.Chain.Cache.PendingTransactions.child_id())
Supervisor.restart_child(Explorer.Supervisor, Explorer.Chain.Cache.PendingTransactions.child_id())
:ok
end

@ -10,9 +10,11 @@ defmodule Indexer.Block.Fetcher do
import EthereumJSONRPC, only: [quantity_to_integer: 1]
alias EthereumJSONRPC.{Blocks, FetchedBeneficiaries}
alias Explorer.Chain
alias Explorer.Chain.{Address, Block, Hash, Import, Transaction}
alias Explorer.Chain.Block.Reward
alias Explorer.Chain.Cache.Blocks, as: BlocksCache
alias Explorer.Chain.Cache.{Accounts, BlockNumber, PendingTransactions, Transactions, Uncles}
alias Explorer.Chain.Cache.{Accounts, BlockNumber, Transactions, Uncles}
alias Indexer.Block.Fetcher.Receipts
alias Indexer.Fetcher.{
@ -153,7 +155,7 @@ defmodule Indexer.Block.Fetcher do
|> AddressCoinBalances.params_set(),
beneficiaries_with_gas_payment <-
beneficiary_params_set
|> add_gas_payments(transactions_with_receipts)
|> add_gas_payments(transactions_with_receipts, blocks)
|> BlockReward.reduce_uncle_rewards(),
address_token_balances = AddressTokenBalances.params_set(%{token_transfers_params: token_transfers}),
{:ok, inserted} <-
@ -174,7 +176,7 @@ defmodule Indexer.Block.Fetcher do
) do
result = {:ok, %{inserted: inserted, errors: blocks_errors}}
update_block_cache(inserted[:blocks])
update_transactions_cache(inserted[:transactions], inserted[:fork_transactions])
update_transactions_cache(inserted[:transactions])
update_addresses_cache(inserted[:addresses])
update_uncles_cache(inserted[:block_second_degree_relations])
result
@ -196,10 +198,8 @@ defmodule Indexer.Block.Fetcher do
defp update_block_cache(_), do: :ok
defp update_transactions_cache(transactions, forked_transactions) do
defp update_transactions_cache(transactions) do
Transactions.update(transactions)
PendingTransactions.update_pending(transactions)
PendingTransactions.update_pending(forked_transactions)
end
defp update_addresses_cache(addresses), do: Accounts.drop(addresses)
@ -396,18 +396,22 @@ defmodule Indexer.Block.Fetcher do
|> Enum.into(MapSet.new())
end
defp add_gas_payments(beneficiaries, transactions) do
defp add_gas_payments(beneficiaries, transactions, blocks) do
transactions_by_block_number = Enum.group_by(transactions, & &1.block_number)
Enum.map(beneficiaries, fn beneficiary ->
case beneficiary.address_type do
:validator ->
gas_payment = gas_payment(beneficiary, transactions_by_block_number)
block_hash = beneficiary.block_hash
"0x" <> minted_hex = beneficiary.reward
{minted, _} = Integer.parse(minted_hex, 16)
block = find_block(blocks, block_hash)
%{beneficiary | reward: minted + gas_payment}
block_miner_hash = block.miner_hash
{:ok, block_miner} = Chain.string_to_address_hash(block_miner_hash)
%{payout_key: block_miner_payout_address} = Reward.get_validator_payout_key_by_mining(block_miner)
reward_with_gas(block_miner_payout_address, beneficiary, transactions_by_block_number)
_ ->
beneficiary
@ -415,6 +419,27 @@ defmodule Indexer.Block.Fetcher do
end)
end
defp reward_with_gas(block_miner_payout_address, beneficiary, transactions_by_block_number) do
{:ok, beneficiary_address} = Chain.string_to_address_hash(beneficiary.address_hash)
"0x" <> minted_hex = beneficiary.reward
{minted, _} = Integer.parse(minted_hex, 16)
if block_miner_payout_address && beneficiary_address.bytes == block_miner_payout_address.bytes do
gas_payment = gas_payment(beneficiary, transactions_by_block_number)
%{beneficiary | reward: minted + gas_payment}
else
%{beneficiary | reward: minted}
end
end
defp find_block(blocks, block_hash) do
blocks
|> Enum.filter(fn block -> block.hash == block_hash end)
|> Enum.at(0)
end
defp gas_payment(transactions) when is_list(transactions) do
transactions
|> Stream.map(&(&1.gas_used * &1.gas_price))

@ -14,7 +14,7 @@ defmodule Indexer.Fetcher.PendingTransaction do
alias Ecto.Changeset
alias Explorer.Chain
alias Explorer.Chain.Cache.{Accounts, PendingTransactions}
alias Explorer.Chain.Cache.{Accounts}
alias Indexer.Fetcher.PendingTransaction
alias Indexer.Transform.Addresses
@ -151,7 +151,6 @@ defmodule Indexer.Fetcher.PendingTransaction do
}) do
{:ok, imported} ->
Accounts.drop(imported[:addresses])
PendingTransactions.update_pending(imported[:transactions])
:ok
{:error, [%Changeset{} | _] = changesets} ->

@ -12,7 +12,7 @@ defmodule Indexer.Fetcher.UncleBlock do
alias Ecto.Changeset
alias EthereumJSONRPC.Blocks
alias Explorer.Chain
alias Explorer.Chain.Cache.{Accounts, PendingTransactions, Uncles}
alias Explorer.Chain.Cache.{Accounts, Uncles}
alias Explorer.Chain.Hash
alias Indexer.{Block, BufferedTask, Tracer}
alias Indexer.Fetcher.UncleBlock
@ -169,8 +169,6 @@ defmodule Indexer.Fetcher.UncleBlock do
# * TokenBalance.async_fetch is not called because it uses block numbers from consensus, not uncles
UncleBlock.async_fetch_blocks(block_second_degree_relations)
PendingTransactions.update_pending(imported[:transactions])
PendingTransactions.update_pending(imported[:fork_transactions])
{:ok, imported}
end

@ -10,7 +10,7 @@ defmodule Indexer.MixProject do
deps: deps(),
deps_path: "../../deps",
description: "Fetches block chain data from on-chain node for later reading with Explorer.",
elixir: "~> 1.9",
elixir: "~> 1.10",
elixirc_paths: elixirc_paths(Mix.env()),
lockfile: "../../mix.lock",
preferred_cli_env: [

@ -1,4 +1,4 @@
FROM bitwalker/alpine-elixir-phoenix:1.9.4
FROM bitwalker/alpine-elixir-phoenix:1.10.2
RUN apk --no-cache --update add alpine-sdk gmp-dev automake libtool inotify-tools autoconf python

@ -61,6 +61,9 @@ endif
ifdef VALIDATORS_CONTRACT
BLOCKSCOUT_CONTAINER_PARAMS += -e 'VALIDATORS_CONTRACT=$(VALIDATORS_CONTRACT)'
endif
ifdef KEYS_MANAGER_CONTRACT
BLOCKSCOUT_CONTAINER_PARAMS += -e 'KEYS_MANAGER_CONTRACT=$(KEYS_MANAGER_CONTRACT)'
endif
ifdef SUPPLY_MODULE
BLOCKSCOUT_CONTAINER_PARAMS += -e 'SUPPLY_MODULE=$(SUPPLY_MODULE)'
endif
@ -196,6 +199,27 @@ endif
ifdef CHECKSUM_FUNCTION
BLOCKSCOUT_CONTAINER_PARAMS += -e 'CHECKSUM_FUNCTION=$(CHECKSUM_FUNCTION)'
endif
ifdef COINGECKO_COIN_ID
BLOCKSCOUT_CONTAINER_PARAMS += -e 'COINGECKO_COIN_ID=$(COINGECKO_COIN_ID)'
endif
ifdef DISABLE_EXCHANGE_RATES
BLOCKSCOUT_CONTAINER_PARAMS += -e 'DISABLE_EXCHANGE_RATES=$(DISABLE_EXCHANGE_RATES)'
endif
ifdef SHOW_PRICE_CHART
BLOCKSCOUT_CONTAINER_PARAMS += -e 'SHOW_PRICE_CHART=$(SHOW_PRICE_CHART)'
endif
ifdef SHOW_TXS_CHART
BLOCKSCOUT_CONTAINER_PARAMS += -e 'SHOW_TXS_CHART=$(SHOW_TXS_CHART)'
endif
ifdef HISTORY_FETCH_INTERVAL
BLOCKSCOUT_CONTAINER_PARAMS += -e 'HISTORY_FETCH_INTERVAL=$(HISTORY_FETCH_INTERVAL)'
endif
ifdef TXS_HISTORIAN_INIT_LAG
BLOCKSCOUT_CONTAINER_PARAMS += -e 'TXS_HISTORIAN_INIT_LAG=$(TXS_HISTORIAN_INIT_LAG)'
endif
ifdef TXS_STATS_DAYS_TO_COMPILE_AT_INIT
BLOCKSCOUT_CONTAINER_PARAMS += -e 'TXS_STATS_DAYS_TO_COMPILE_AT_INIT=$(TXS_STATS_DAYS_TO_COMPILE_AT_INIT)'
endif
HAS_BLOCKSCOUT_IMAGE := $(shell docker images | grep ${DOCKER_IMAGE})
build:

@ -14,7 +14,7 @@ defmodule BlockScout.Mixfile do
plt_add_apps: ~w(ex_unit mix)a,
ignore_warnings: ".dialyzer-ignore"
],
elixir: "~> 1.9",
elixir: "~> 1.10",
preferred_cli_env: [
coveralls: :test,
"coveralls.detail": :test,

@ -1,118 +1,118 @@
%{
"absinthe": {:hex, :absinthe, "1.5.0-rc.2", "132ceb90783a39454cba1a043e833add5385036ed1e6fe8e889b85fc2b7cd89f", [:mix], [{:dataloader, "~> 1.0.0", [hex: :dataloader, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"},
"absinthe_phoenix": {:hex, :absinthe_phoenix, "1.5.0-rc.0", "63558295f77f09c9e412fa0a4ef92a66003eaf539821a810fd928c1c67a6005d", [:mix], [{:absinthe, "~> 1.5.0-rc.0", [hex: :absinthe, repo: "hexpm", optional: false]}, {:absinthe_plug, "~> 1.5.0-rc.0", [hex: :absinthe_plug, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.13", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}], "hexpm"},
"absinthe_plug": {:hex, :absinthe_plug, "1.5.0-rc.1", "f6d8a7a74c42cb1547f9d62cf728b8aab960c5246b8415deb0cb1f5aac1fb671", [:mix], [{:absinthe, "~> 1.5.0-rc.2", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.2 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"absinthe_relay": {:hex, :absinthe_relay, "1.5.0-rc.0", "99048f5a8239dbcecf6c600f6a2410e1b157832df01d3f4859bc804565ddf1bc", [:mix], [{:absinthe, "~> 1.5.0-rc.1", [hex: :absinthe, repo: "hexpm", optional: false]}, {:ecto, "~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
"accept": {:hex, :accept, "0.3.5", "b33b127abca7cc948bbe6caa4c263369abf1347cfa9d8e699c6d214660f10cd1", [:rebar3], [], "hexpm"},
"bcrypt_elixir": {:hex, :bcrypt_elixir, "1.1.1", "6b5560e47a02196ce5f0ab3f1d8265db79a23868c137e973b27afef928ed8006", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
"benchee": {:hex, :benchee, "0.13.2", "30cd4ff5f593fdd218a9b26f3c24d580274f297d88ad43383afe525b1543b165", [:mix], [{:deep_merge, "~> 0.1", [hex: :deep_merge, repo: "hexpm", optional: false]}], "hexpm"},
"benchee_csv": {:hex, :benchee_csv, "0.8.0", "0ca094677d6e2b2f601b7ee7864b754789ef9d24d079432e5e3d6f4fb83a4d80", [:mix], [{:benchee, "~> 0.12", [hex: :benchee, repo: "hexpm", optional: false]}, {:csv, "~> 2.0", [hex: :csv, repo: "hexpm", optional: false]}], "hexpm"},
"binary": {:hex, :binary, "0.0.5", "20d816f7274ea34f1b673b4cff2fdb9ebec9391a7a68c349070d515c66b1b2cf", [:mix], [], "hexpm"},
"absinthe": {:hex, :absinthe, "1.5.0-rc.2", "132ceb90783a39454cba1a043e833add5385036ed1e6fe8e889b85fc2b7cd89f", [:mix], [{:dataloader, "~> 1.0.0", [hex: :dataloader, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4703b70fe80143db7e713c0913b41dc575bf34565d4db57e8bbd261379cad7ad"},
"absinthe_phoenix": {:hex, :absinthe_phoenix, "1.5.0-rc.0", "63558295f77f09c9e412fa0a4ef92a66003eaf539821a810fd928c1c67a6005d", [:mix], [{:absinthe, "~> 1.5.0-rc.0", [hex: :absinthe, repo: "hexpm", optional: false]}, {:absinthe_plug, "~> 1.5.0-rc.0", [hex: :absinthe_plug, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.13", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}], "hexpm", "9a76cda02f19e25921796e5d9c3657bb2d8f5255efba51109272e83eed6073c6"},
"absinthe_plug": {:hex, :absinthe_plug, "1.5.0-rc.1", "f6d8a7a74c42cb1547f9d62cf728b8aab960c5246b8415deb0cb1f5aac1fb671", [:mix], [{:absinthe, "~> 1.5.0-rc.2", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.2 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "c06e06748381563dddf6ea501b3330eab3141eb050455d10b43260a77eaa1d60"},
"absinthe_relay": {:hex, :absinthe_relay, "1.5.0-rc.0", "99048f5a8239dbcecf6c600f6a2410e1b157832df01d3f4859bc804565ddf1bc", [:mix], [{:absinthe, "~> 1.5.0-rc.1", [hex: :absinthe, repo: "hexpm", optional: false]}, {:ecto, "~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "e0db315eb9cf735a257c70bac86838f14a747f1fe451226c210002abb48f4cf2"},
"accept": {:hex, :accept, "0.3.5", "b33b127abca7cc948bbe6caa4c263369abf1347cfa9d8e699c6d214660f10cd1", [:rebar3], [], "hexpm", "11b18c220bcc2eab63b5470c038ef10eb6783bcb1fcdb11aa4137defa5ac1bb8"},
"bcrypt_elixir": {:hex, :bcrypt_elixir, "1.1.1", "6b5560e47a02196ce5f0ab3f1d8265db79a23868c137e973b27afef928ed8006", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "10f658be786bd2daaadcd45cc5b598da01d5bbc313da4d0e3efb2d6a511d896d"},
"benchee": {:hex, :benchee, "0.13.2", "30cd4ff5f593fdd218a9b26f3c24d580274f297d88ad43383afe525b1543b165", [:mix], [{:deep_merge, "~> 0.1", [hex: :deep_merge, repo: "hexpm", optional: false]}], "hexpm", "d8b3f1720073413c36a21e56a1d1112a4d67a9ad0ec900437efed08b39e515b2"},
"benchee_csv": {:hex, :benchee_csv, "0.8.0", "0ca094677d6e2b2f601b7ee7864b754789ef9d24d079432e5e3d6f4fb83a4d80", [:mix], [{:benchee, "~> 0.12", [hex: :benchee, repo: "hexpm", optional: false]}, {:csv, "~> 2.0", [hex: :csv, repo: "hexpm", optional: false]}], "hexpm", "74f5f5b5fe50f05ee29023d35a4d7d543230d63fa15c67076a36ad46e2b040d8"},
"binary": {:hex, :binary, "0.0.5", "20d816f7274ea34f1b673b4cff2fdb9ebec9391a7a68c349070d515c66b1b2cf", [:mix], [], "hexpm", "ee1e9ebcab703a4e24db554957fbb540642fe9327eb9e295cb3f07dd7c11ddb2"},
"briefly": {:git, "https://github.com/CargoSense/briefly.git", "2526e9674a4e6996137e066a1295ea60962712b8", []},
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"},
"bypass": {:hex, :bypass, "1.0.0", "b78b3dcb832a71aca5259c1a704b2e14b55fd4e1327ff942598b4e7d1a7ad83d", [:mix], [{:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: false]}], "hexpm"},
"certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
"cldr_utils": {:hex, :cldr_utils, "2.3.0", "e7e8b5ad7494a929c1b620cc489c3aa3f6e7e5299584c1a934bbdb56d1a53c70", [:mix], [{:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"},
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm"},
"comeonin": {:hex, :comeonin, "4.1.2", "3eb5620fd8e35508991664b4c2b04dd41e52f1620b36957be837c1d7784b7592", [:mix], [{:argon2_elixir, "~> 1.2", [hex: :argon2_elixir, repo: "hexpm", optional: true]}, {:bcrypt_elixir, "~> 0.12.1 or ~> 1.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: true]}, {:pbkdf2_elixir, "~> 0.12", [hex: :pbkdf2_elixir, repo: "hexpm", optional: true]}], "hexpm"},
"con_cache": {:hex, :con_cache, "0.13.1", "047e097ab2a8c6876e12d0c29e29a86d487b592df97b98e3e2abedad574e215d", [:mix], [], "hexpm"},
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"},
"cors_plug": {:hex, :cors_plug, "2.0.0", "238ddb479f92b38f6dc1ae44b8d81f0387f9519101a6da442d543ab70ee0e482", [:mix], [{:plug, "~> 1.3 or ~> 1.4 or ~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"cowboy": {:hex, :cowboy, "2.6.3", "99aa50e94e685557cad82e704457336a453d4abcb77839ad22dbe71f311fcc06", [:rebar3], [{:cowlib, "~> 2.7.3", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
"cowlib": {:hex, :cowlib, "2.7.3", "a7ffcd0917e6d50b4d5fb28e9e2085a0ceb3c97dea310505f7460ff5ed764ce9", [:rebar3], [], "hexpm"},
"credo": {:hex, :credo, "1.1.2", "02b6422f3e659eb74b05aca3c20c1d8da0119a05ee82577a82e6c2938bf29f81", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
"csv": {:hex, :csv, "2.3.1", "9ce11eff5a74a07baf3787b2b19dd798724d29a9c3a492a41df39f6af686da0e", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm"},
"dataloader": {:hex, :dataloader, "1.0.7", "58351b335673cf40601429bfed6c11fece6ce7ad169b2ac0f0fe83e716587391", [:mix], [{:ecto, ">= 0.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
"db_connection": {:hex, :db_connection, "2.2.0", "e923e88887cd60f9891fd324ac5e0290954511d090553c415fbf54be4c57ee63", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm"},
"decimal": {:hex, :decimal, "1.8.1", "a4ef3f5f3428bdbc0d35374029ffcf4ede8533536fa79896dd450168d9acdf3c", [:mix], [], "hexpm"},
"decorator": {:hex, :decorator, "1.3.0", "6203dbd6e4e519a21a079e2a74e50fddaf03e80be22711b92eb4cd410173abea", [:mix], [], "hexpm"},
"deep_merge": {:hex, :deep_merge, "0.2.0", "c1050fa2edf4848b9f556fba1b75afc66608a4219659e3311d9c9427b5b680b3", [:mix], [], "hexpm"},
"dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm"},
"earmark": {:hex, :earmark, "1.3.5", "0db71c8290b5bc81cb0101a2a507a76dca659513984d683119ee722828b424f6", [:mix], [], "hexpm"},
"ecto": {:hex, :ecto, "3.3.1", "82ab74298065bf0c64ca299f6c6785e68ea5d6b980883ee80b044499df35aba1", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
"ecto_sql": {:hex, :ecto_sql, "3.3.2", "92804e0de69bb63e621273c3492252cb08a29475c05d40eeb6f41ad2d483cfd3", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.3.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"},
"elixir_make": {:hex, :elixir_make, "0.6.0", "38349f3e29aff4864352084fc736fa7fa0f2995a819a737554f7ebd28b85aaab", [:mix], [], "hexpm"},
"ex_abi": {:git, "https://github.com/poanetwork/ex_abi.git", "02539efc1a9f1c1e36f8df26e54617522482dc12", [branch: "master"]},
"ex_cldr": {:hex, :ex_cldr, "2.7.2", "d79a1af6ed12630a15175d2b88d4381b22db5d6f835c5da8de132f0cf712b233", [:mix], [{:cldr_utils, "~> 2.1", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm"},
"ex_cldr_currencies": {:hex, :ex_cldr_currencies, "2.3.0", "bffae489416b8b05d4683403263f5d62aae17de70c24ff915a533541fea514de", [:mix], [{:ex_cldr, "~> 2.6", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
"ex_cldr_lists": {:hex, :ex_cldr_lists, "2.2.0", "b99f8752d098fc6ba5f083bbd0b25d0d01e36b0042155cf6abd5f205306ba849", [:mix], [{:ex_cldr, "~> 2.6", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:ex_cldr_numbers, "~> 2.6", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
"ex_cldr_numbers": {:hex, :ex_cldr_numbers, "2.6.4", "5b1ac8451f889576bb29dee70412de1170974298727ab944aa4d17e91bdd3472", [:mix], [{:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:ex_cldr, "~> 2.6", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:ex_cldr_currencies, "~> 2.3", [hex: :ex_cldr_currencies, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
"ex_cldr_units": {:hex, :ex_cldr_units, "2.5.1", "0e65067a22a7c5146266c313d6333c2700868c32aa6d536f47c6c0d84aac3ac1", [:mix], [{:ex_cldr, "~> 2.6", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:ex_cldr_lists, "~> 2.2", [hex: :ex_cldr_lists, repo: "hexpm", optional: false]}, {:ex_cldr_numbers, "~> 2.6", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
"ex_doc": {:hex, :ex_doc, "0.19.3", "3c7b0f02851f5fc13b040e8e925051452e41248f685e40250d7e40b07b9f8c10", [:mix], [{:earmark, "~> 1.2", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
"ex_json_schema": {:hex, :ex_json_schema, "0.6.2", "de23d80478215987469c81688208fe0ff440ee0e0e6ae2268fcadbb2ff35df9d", [:mix], [], "hexpm"},
"ex_machina": {:hex, :ex_machina, "2.3.0", "92a5ad0a8b10ea6314b876a99c8c9e3f25f4dde71a2a835845b136b9adaf199a", [: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.5.2", "7f4ce7bd55e543c054ce6d49629b01e9833c3462e3d547952be89865f39f2c58", [:mix], [], "hexpm"},
"ex_utils": {:hex, :ex_utils, "0.1.7", "2c133e0bcdc49a858cf8dacf893308ebc05bc5fba501dc3d2935e65365ec0bf3", [:mix], [], "hexpm"},
"exactor": {:hex, :exactor, "2.2.4", "5efb4ddeb2c48d9a1d7c9b465a6fffdd82300eb9618ece5d34c3334d5d7245b1", [:mix], [], "hexpm"},
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
"bypass": {:hex, :bypass, "1.0.0", "b78b3dcb832a71aca5259c1a704b2e14b55fd4e1327ff942598b4e7d1a7ad83d", [:mix], [{:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: false]}], "hexpm", "5a1dc855dfcc86160458c7a70d25f65d498bd8012bd4c06a8d3baa368dda3c45"},
"certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "805abd97539caf89ec6d4732c91e62ba9da0cda51ac462380bbd28ee697a8c42"},
"cldr_utils": {:hex, :cldr_utils, "2.3.0", "e7e8b5ad7494a929c1b620cc489c3aa3f6e7e5299584c1a934bbdb56d1a53c70", [:mix], [{:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "a865f4bbf024028e84787398054aa080fc38a714e1ced853e2803e3b4e597e63"},
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
"comeonin": {:hex, :comeonin, "4.1.2", "3eb5620fd8e35508991664b4c2b04dd41e52f1620b36957be837c1d7784b7592", [:mix], [{:argon2_elixir, "~> 1.2", [hex: :argon2_elixir, repo: "hexpm", optional: true]}, {:bcrypt_elixir, "~> 0.12.1 or ~> 1.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: true]}, {:pbkdf2_elixir, "~> 0.12", [hex: :pbkdf2_elixir, repo: "hexpm", optional: true]}], "hexpm", "d8700a0ca4dbb616c22c9b3f6dd539d88deaafec3efe66869d6370c9a559b3e9"},
"con_cache": {:hex, :con_cache, "0.13.1", "047e097ab2a8c6876e12d0c29e29a86d487b592df97b98e3e2abedad574e215d", [:mix], [], "hexpm", "d3c19f04153b691d7bfdb15bcfc3b8fea503b0b51635115393809af7eabe2f37"},
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm", "4a0850c9be22a43af9920a71ab17c051f5f7d45c209e40269a1938832510e4d9"},
"cors_plug": {:hex, :cors_plug, "2.0.0", "238ddb479f92b38f6dc1ae44b8d81f0387f9519101a6da442d543ab70ee0e482", [:mix], [{:plug, "~> 1.3 or ~> 1.4 or ~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "118162367ef41448c9742ced8c8bc33ae2857d958d6b997e1db26402dd8c6f37"},
"cowboy": {:hex, :cowboy, "2.6.3", "99aa50e94e685557cad82e704457336a453d4abcb77839ad22dbe71f311fcc06", [:rebar3], [{:cowlib, "~> 2.7.3", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "e5580029080f3f1ad17436fb97b0d5ed2ed4e4815a96bac36b5a992e20f58db6"},
"cowlib": {:hex, :cowlib, "2.7.3", "a7ffcd0917e6d50b4d5fb28e9e2085a0ceb3c97dea310505f7460ff5ed764ce9", [:rebar3], [], "hexpm", "1e1a3d176d52daebbecbbcdfd27c27726076567905c2a9d7398c54da9d225761"},
"credo": {:hex, :credo, "1.1.2", "02b6422f3e659eb74b05aca3c20c1d8da0119a05ee82577a82e6c2938bf29f81", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "cd9322e9d391251ca3c4fac10ff0ce86ea4b99b3d9b34526ee2a7baa5928167d"},
"csv": {:hex, :csv, "2.3.1", "9ce11eff5a74a07baf3787b2b19dd798724d29a9c3a492a41df39f6af686da0e", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm", "86626e1c89a4ad9a96d0d9c638f9e88c2346b89b4ba1611988594ebe72b5d5ee"},
"dataloader": {:hex, :dataloader, "1.0.7", "58351b335673cf40601429bfed6c11fece6ce7ad169b2ac0f0fe83e716587391", [:mix], [{:ecto, ">= 0.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "12bf66478e4a5085d09dc96932d058c206ee8c219cc7691d12a40dc35c8cefaa"},
"db_connection": {:hex, :db_connection, "2.2.0", "e923e88887cd60f9891fd324ac5e0290954511d090553c415fbf54be4c57ee63", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm", "bdf196feedfa6b83071e808b2b086fb113f8a1c4c7761f6eff6fe4b96aba0086"},
"decimal": {:hex, :decimal, "1.8.1", "a4ef3f5f3428bdbc0d35374029ffcf4ede8533536fa79896dd450168d9acdf3c", [:mix], [], "hexpm", "3cb154b00225ac687f6cbd4acc4b7960027c757a5152b369923ead9ddbca7aec"},
"decorator": {:hex, :decorator, "1.3.0", "6203dbd6e4e519a21a079e2a74e50fddaf03e80be22711b92eb4cd410173abea", [:mix], [], "hexpm", "1fde31b23897e529b44d72d798489e1c6d45936f106812a8df80180779afafb4"},
"deep_merge": {:hex, :deep_merge, "0.2.0", "c1050fa2edf4848b9f556fba1b75afc66608a4219659e3311d9c9427b5b680b3", [:mix], [], "hexpm", "e3bf435a54ed27b0ba3a01eb117ae017988804e136edcbe8a6a14c310daa966e"},
"dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm", "6c32a70ed5d452c6650916555b1f96c79af5fc4bf286997f8b15f213de786f73"},
"earmark": {:hex, :earmark, "1.3.5", "0db71c8290b5bc81cb0101a2a507a76dca659513984d683119ee722828b424f6", [:mix], [], "hexpm", "762b999fd414fb41e297944228aa1de2cd4a3876a07f968c8b11d1e9a2190d07"},
"ecto": {:hex, :ecto, "3.3.1", "82ab74298065bf0c64ca299f6c6785e68ea5d6b980883ee80b044499df35aba1", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "e6c614dfe3bcff2d575ce16d815dbd43f4ee1844599a83de1eea81976a31c174"},
"ecto_sql": {:hex, :ecto_sql, "3.3.2", "92804e0de69bb63e621273c3492252cb08a29475c05d40eeb6f41ad2d483cfd3", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.3.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b82d89d4e6a9f7f7f04783b07e8b0af968e0be2f01ee4b39047fe727c5c07471"},
"elixir_make": {:hex, :elixir_make, "0.6.0", "38349f3e29aff4864352084fc736fa7fa0f2995a819a737554f7ebd28b85aaab", [:mix], [], "hexpm", "d522695b93b7f0b4c0fcb2dfe73a6b905b1c301226a5a55cb42e5b14d509e050"},
"ex_abi": {:git, "https://github.com/poanetwork/ex_abi.git", "ef450816ef4ca98648125577b675ab584251a883", [branch: "master"]},
"ex_cldr": {:hex, :ex_cldr, "2.7.2", "d79a1af6ed12630a15175d2b88d4381b22db5d6f835c5da8de132f0cf712b233", [:mix], [{:cldr_utils, "~> 2.1", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "52344684e4e0ff046e1929ae019c0b3c6b122c77c948a43be30684015f2036e2"},
"ex_cldr_currencies": {:hex, :ex_cldr_currencies, "2.3.0", "bffae489416b8b05d4683403263f5d62aae17de70c24ff915a533541fea514de", [:mix], [{:ex_cldr, "~> 2.6", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "7d8ba3738b24d9c7d31bc63b131785b444ed05388fd1cc0958216eb5992d79d6"},
"ex_cldr_lists": {:hex, :ex_cldr_lists, "2.2.0", "b99f8752d098fc6ba5f083bbd0b25d0d01e36b0042155cf6abd5f205306ba849", [:mix], [{:ex_cldr, "~> 2.6", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:ex_cldr_numbers, "~> 2.6", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "89e25d539a4126472560da2e28b6f1aeb859f5afc0778d6b594029c4226d1775"},
"ex_cldr_numbers": {:hex, :ex_cldr_numbers, "2.6.4", "5b1ac8451f889576bb29dee70412de1170974298727ab944aa4d17e91bdd3472", [:mix], [{:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:ex_cldr, "~> 2.6", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:ex_cldr_currencies, "~> 2.3", [hex: :ex_cldr_currencies, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "ebc768502db56782794dc51f4f12fe53c3a2338db148d380bdbcf631c7d691f5"},
"ex_cldr_units": {:hex, :ex_cldr_units, "2.5.1", "0e65067a22a7c5146266c313d6333c2700868c32aa6d536f47c6c0d84aac3ac1", [:mix], [{:ex_cldr, "~> 2.6", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:ex_cldr_lists, "~> 2.2", [hex: :ex_cldr_lists, repo: "hexpm", optional: false]}, {:ex_cldr_numbers, "~> 2.6", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "88f2f28a1c893e429943aaac87ea0e4d60e52852edc46420bc9f3c7aba2c8f9f"},
"ex_doc": {:hex, :ex_doc, "0.19.3", "3c7b0f02851f5fc13b040e8e925051452e41248f685e40250d7e40b07b9f8c10", [:mix], [{:earmark, "~> 1.2", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "0e11d67e662142fc3945b0ee410c73c8c956717fbeae4ad954b418747c734973"},
"ex_json_schema": {:hex, :ex_json_schema, "0.6.2", "de23d80478215987469c81688208fe0ff440ee0e0e6ae2268fcadbb2ff35df9d", [:mix], [], "hexpm", "2f25c57e919ffc5d6b02f2f130548284342dd6c3e99555ee0beeb9f2d2366a96"},
"ex_machina": {:hex, :ex_machina, "2.3.0", "92a5ad0a8b10ea6314b876a99c8c9e3f25f4dde71a2a835845b136b9adaf199a", [: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", "b84f6af156264530b312a8ab98ac6088f6b77ae5fe2058305c81434aa01fbaf9"},
"ex_rlp": {:hex, :ex_rlp, "0.5.2", "7f4ce7bd55e543c054ce6d49629b01e9833c3462e3d547952be89865f39f2c58", [:mix], [], "hexpm", "1b8b8f72f8399ace4e096b99c653cba8c52dc6db17b6b410771c0f088774db82"},
"ex_utils": {:hex, :ex_utils, "0.1.7", "2c133e0bcdc49a858cf8dacf893308ebc05bc5fba501dc3d2935e65365ec0bf3", [:mix], [], "hexpm", "66d4fe75285948f2d1e69c2a5ddd651c398c813574f8d36a9eef11dc20356ef6"},
"exactor": {:hex, :exactor, "2.2.4", "5efb4ddeb2c48d9a1d7c9b465a6fffdd82300eb9618ece5d34c3334d5d7245b1", [:mix], [], "hexpm", "1222419f706e01bfa1095aec9acf6421367dcfab798a6f67c54cf784733cd6b5"},
"excoveralls": {:git, "https://github.com/KronicDeth/excoveralls.git", "0a859b68851eeba9b43eba59fbc8f9098299cfe1", [branch: "circle-workflows"]},
"exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "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"},
"exvcr": {:hex, :exvcr, "0.10.1", "cb266e5cc0d4fef12572ce6673d13f97aa3c302911010d64d51cee0690f566d1", [:mix], [{:exactor, "~> 2.2", [hex: :exactor, repo: "hexpm", optional: false]}, {:exjsx, "~> 4.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: true]}, {:httpotion, "~> 3.1", [hex: :httpotion, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:meck, "~> 0.8", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"},
"file_system": {:hex, :file_system, "0.2.7", "e6f7f155970975789f26e77b8b8d8ab084c59844d8ecfaf58cbda31c494d14aa", [:mix], [], "hexpm"},
"floki": {:hex, :floki, "0.20.4", "be42ac911fece24b4c72f3b5846774b6e61b83fe685c2fc9d62093277fb3bc86", [:mix], [{:html_entities, "~> 0.4.0", [hex: :html_entities, repo: "hexpm", optional: false]}, {:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"},
"flow": {:hex, :flow, "0.14.3", "0d92991fe53035894d24aa8dec10dcfccf0ae00c4ed436ace3efa9813a646902", [:mix], [{:gen_stage, "~> 0.14.0", [hex: :gen_stage, repo: "hexpm", optional: false]}], "hexpm"},
"gen_stage": {:hex, :gen_stage, "0.14.2", "6a2a578a510c5bfca8a45e6b27552f613b41cf584b58210f017088d3d17d0b14", [:mix], [], "hexpm"},
"gettext": {:hex, :gettext, "0.16.1", "e2130b25eebcbe02bb343b119a07ae2c7e28bd4b146c4a154da2ffb2b3507af2", [:mix], [], "hexpm"},
"hackney": {:hex, :hackney, "1.15.2", "07e33c794f8f8964ee86cebec1a8ed88db5070e52e904b8f12209773c1036085", [:rebar3], [{:certifi, "2.5.1", [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.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.5", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"html_entities": {:hex, :html_entities, "0.4.0", "f2fee876858cf6aaa9db608820a3209e45a087c5177332799592142b50e89a6b", [:mix], [], "hexpm"},
"httpoison": {:hex, :httpoison, "1.0.0", "1f02f827148d945d40b24f0b0a89afe40bfe037171a6cf70f2486976d86921cd", [: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"},
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
"jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm"},
"junit_formatter": {:hex, :junit_formatter, "3.0.1", "4ed76a50886717a6d683a978cec775abdcb88d9d51cfddd3d8fbf8e6af4625da", [:mix], [], "hexpm"},
"keccakf1600": {:hex, :keccakf1600_orig, "2.0.0", "0a7217ddb3ee8220d449bbf7575ec39d4e967099f220a91e3dfca4dbaef91963", [:rebar3], [], "hexpm"},
"libsecp256k1": {:hex, :libsecp256k1, "0.1.10", "d27495e2b9851c7765129b76c53b60f5e275bd6ff68292c50536bf6b8d091a4d", [:make, :mix], [{:mix_erlang_tasks, "0.1.0", [hex: :mix_erlang_tasks, repo: "hexpm", optional: false]}], "hexpm"},
"logger_file_backend": {:hex, :logger_file_backend, "0.0.11", "3bbc5f31d3669e8d09d7a9443e86056fae7fc18e45c6f748c33b8c79a7e147a1", [:mix], [], "hexpm"},
"makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
"makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},
"math": {:hex, :math, "0.3.0", "e14e7291115201cb155a3567e66d196bf5088a6f55b030d598107d7ae934a11c", [:mix], [], "hexpm"},
"meck": {:hex, :meck, "0.8.13", "ffedb39f99b0b99703b8601c6f17c7f76313ee12de6b646e671e3188401f7866", [:rebar3], [], "hexpm"},
"memento": {:hex, :memento, "0.3.1", "b2909390820550d8b90b68ec96f9e15ff8a45a28b6f97fa4a62ef50e87c2f9d9", [:mix], [], "hexpm"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm"},
"mix_erlang_tasks": {:hex, :mix_erlang_tasks, "0.1.0", "36819fec60b80689eb1380938675af215565a89320a9e29c72c70d97512e4649", [:mix], [], "hexpm"},
"mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm"},
"mock": {:hex, :mock, "0.3.3", "42a433794b1291a9cf1525c6d26b38e039e0d3a360732b5e467bfc77ef26c914", [:mix], [{:meck, "~> 0.8.13", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"},
"mox": {:hex, :mox, "0.5.1", "f86bb36026aac1e6f924a4b6d024b05e9adbed5c63e8daa069bd66fb3292165b", [:mix], [], "hexpm"},
"msgpax": {:hex, :msgpax, "2.2.4", "7b3790ef684089076b63c0f08c2f4b079c6311daeb006b69e4ed2bf67518291e", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm"},
"nimble_csv": {:hex, :nimble_csv, "0.6.0", "a3673f26d41f986774fe6060e309615343d3cb83a6d435754d8b1fdbd5764879", [:mix], [], "hexpm"},
"nimble_parsec": {:hex, :nimble_parsec, "0.5.1", "c90796ecee0289dbb5ad16d3ad06f957b0cd1199769641c961cfe0b97db190e0", [:mix], [], "hexpm"},
"optimal": {:hex, :optimal, "0.3.6", "46bbf52fbbbd238cda81e02560caa84f93a53c75620f1fe19e81e4ae7b07d1dd", [:mix], [], "hexpm"},
"parallel_stream": {:hex, :parallel_stream, "1.0.6", "b967be2b23f0f6787fab7ed681b4c45a215a81481fb62b01a5b750fa8f30f76c", [:mix], [], "hexpm"},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"},
"phoenix": {:hex, :phoenix, "1.4.0", "56fe9a809e0e735f3e3b9b31c1b749d4b436e466d8da627b8d82f90eaae714d2", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm"},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.0.0", "c43117a136e7399ea04ecaac73f8f23ee0ffe3e07acfcb8062fe5f4c9f0f6531", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_form_awesomplete": {:hex, :phoenix_form_awesomplete, "0.1.5", "d09aade160b584e3428e1e095645482396f17bddda4f566f1118f12d2598d11c", [:mix], [{:phoenix_html, "~> 2.10", [hex: :phoenix_html, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_html": {:hex, :phoenix_html, "2.13.3", "850e292ff6e204257f5f9c4c54a8cb1f6fbc16ed53d360c2b780a3d0ba333867", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.2.1", "274a4b07c4adbdd7785d45a8b0bb57634d0b4f45b18d2c508b26c0344bd59b8f", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "1.1.2", "496c303bdf1b2e98a9d26e89af5bba3ab487ba3a3735f74bf1f4064d2a845a3e", [:mix], [], "hexpm"},
"plug": {:hex, :plug, "1.8.3", "12d5f9796dc72e8ac9614e94bda5e51c4c028d0d428e9297650d09e15a684478", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm"},
"plug_cowboy": {:hex, :plug_cowboy, "2.1.0", "b75768153c3a8a9e8039d4b25bb9b14efbc58e9c4a6e6a270abff1cd30cbe320", [: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, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm"},
"postgrex": {:hex, :postgrex, "0.15.3", "5806baa8a19a68c4d07c7a624ccdb9b57e89cbc573f1b98099e3741214746ae4", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [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"},
"prometheus": {:hex, :prometheus, "4.4.1", "1e96073b3ed7788053768fea779cbc896ddc3bdd9ba60687f2ad50b252ac87d6", [:mix, :rebar3], [], "hexpm"},
"prometheus_ecto": {:hex, :prometheus_ecto, "1.4.3", "3dd4da1812b8e0dbee81ea58bb3b62ed7588f2eae0c9e97e434c46807ff82311", [:mix], [{:ecto, "~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm"},
"prometheus_ex": {:hex, :prometheus_ex, "3.0.5", "fa58cfd983487fc5ead331e9a3e0aa622c67232b3ec71710ced122c4c453a02f", [:mix], [{:prometheus, "~> 4.0", [hex: :prometheus, repo: "hexpm", optional: false]}], "hexpm"},
"prometheus_phoenix": {:hex, :prometheus_phoenix, "1.3.0", "c4b527e0b3a9ef1af26bdcfbfad3998f37795b9185d475ca610fe4388fdd3bb5", [:mix], [{:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.3 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm"},
"prometheus_plugs": {:hex, :prometheus_plugs, "1.1.5", "25933d48f8af3a5941dd7b621c889749894d8a1082a6ff7c67cc99dec26377c5", [:mix], [{:accept, "~> 0.1", [hex: :accept, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}, {:prometheus_process_collector, "~> 1.1", [hex: :prometheus_process_collector, repo: "hexpm", optional: true]}], "hexpm"},
"prometheus_process_collector": {:hex, :prometheus_process_collector, "1.4.3", "657386e8f142fc817347d95c1f3a05ab08710f7df9e7f86db6facaed107ed929", [:rebar3], [{:prometheus, "~> 4.0", [hex: :prometheus, repo: "hexpm", optional: false]}], "hexpm"},
"qrcode": {:hex, :qrcode, "0.1.5", "551271830515c150f34568345b060c625deb0e6691db2a01b0a6de3aafc93886", [:mix], [], "hexpm"},
"que": {:hex, :que, "0.10.1", "788ed0ec92ed69bdf9cfb29bf41a94ca6355b8d44959bd0669cf706e557ac891", [:mix], [{:ex_utils, "~> 0.1.6", [hex: :ex_utils, repo: "hexpm", optional: false]}, {:memento, "~> 0.3.0", [hex: :memento, repo: "hexpm", optional: false]}], "hexpm"},
"ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm"},
"sobelow": {:hex, :sobelow, "0.8.0", "a3ec73e546dfde19f14818e5000c418e3f305d9edb070e79dd391de0ae1cd1ea", [:mix], [], "hexpm"},
"exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm", "32e95820a97cffea67830e91514a2ad53b888850442d6d395f53a1ac60c82e07"},
"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", "45d6faf4b889f8fc526deba059e0c7947423784ab1e7fa85be8db4c46cf4416b"},
"exvcr": {:hex, :exvcr, "0.10.1", "cb266e5cc0d4fef12572ce6673d13f97aa3c302911010d64d51cee0690f566d1", [:mix], [{:exactor, "~> 2.2", [hex: :exactor, repo: "hexpm", optional: false]}, {:exjsx, "~> 4.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: true]}, {:httpotion, "~> 3.1", [hex: :httpotion, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:meck, "~> 0.8", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "643cb18909d93b42d7be6fca7c9737284024a7200f9cb81dc4b3666afd840ede"},
"file_system": {:hex, :file_system, "0.2.7", "e6f7f155970975789f26e77b8b8d8ab084c59844d8ecfaf58cbda31c494d14aa", [:mix], [], "hexpm", "b4cfa2d69c7f0b18fd06db222b2398abeef743a72504e6bd7df9c52f171b047f"},
"floki": {:hex, :floki, "0.20.4", "be42ac911fece24b4c72f3b5846774b6e61b83fe685c2fc9d62093277fb3bc86", [:mix], [{:html_entities, "~> 0.4.0", [hex: :html_entities, repo: "hexpm", optional: false]}, {:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm", "2e7e21cd417c4b13523dd8b97379a33e5f432d4d1b149cf5ab496a4a29bdd7ab"},
"flow": {:hex, :flow, "0.14.3", "0d92991fe53035894d24aa8dec10dcfccf0ae00c4ed436ace3efa9813a646902", [:mix], [{:gen_stage, "~> 0.14.0", [hex: :gen_stage, repo: "hexpm", optional: false]}], "hexpm", "da6177f8d04f663a2894e38f9b55b293c69cb230c60f81bb8c090eb713aa4a45"},
"gen_stage": {:hex, :gen_stage, "0.14.2", "6a2a578a510c5bfca8a45e6b27552f613b41cf584b58210f017088d3d17d0b14", [:mix], [], "hexpm", "1f201083ca2ee1ea2b8e1eb6e98d9842ef93f2e5efa2d602740ab0c56c2bc90b"},
"gettext": {:hex, :gettext, "0.16.1", "e2130b25eebcbe02bb343b119a07ae2c7e28bd4b146c4a154da2ffb2b3507af2", [:mix], [], "hexpm", "dd3a7ea5e3e87ee9df29452dd9560709b4c7cc8141537d0b070155038d92bdf1"},
"hackney": {:hex, :hackney, "1.15.2", "07e33c794f8f8964ee86cebec1a8ed88db5070e52e904b8f12209773c1036085", [:rebar3], [{:certifi, "2.5.1", [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.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.5", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "e0100f8ef7d1124222c11ad362c857d3df7cb5f4204054f9f0f4a728666591fc"},
"html_entities": {:hex, :html_entities, "0.4.0", "f2fee876858cf6aaa9db608820a3209e45a087c5177332799592142b50e89a6b", [:mix], [], "hexpm", "3e3d7156a272950373ce5a4018b1490bea26676f8d6a7d409f6fac8568b8cb9a"},
"httpoison": {:hex, :httpoison, "1.0.0", "1f02f827148d945d40b24f0b0a89afe40bfe037171a6cf70f2486976d86921cd", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "07967c56199f716ce9adb27415ccea1bd76c44f777dd0a6d4166c3d932f37fdf"},
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "4bdd305eb64e18b0273864920695cb18d7a2021f31a11b9c5fbcd9a253f936e2"},
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fdf843bca858203ae1de16da2ee206f53416bbda5dc8c9e78f43243de4bc3afe"},
"jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm", "fc3499fed7a726995aa659143a248534adc754ebd16ccd437cd93b649a95091f"},
"junit_formatter": {:hex, :junit_formatter, "3.0.1", "4ed76a50886717a6d683a978cec775abdcb88d9d51cfddd3d8fbf8e6af4625da", [:mix], [], "hexpm", "55ba8f459c0d2568bb6ca7c44f1b1384194773fce4d8bc99454fa40320664af9"},
"keccakf1600": {:hex, :keccakf1600_orig, "2.0.0", "0a7217ddb3ee8220d449bbf7575ec39d4e967099f220a91e3dfca4dbaef91963", [:rebar3], [], "hexpm", "bdbbb02d67bea35605f95d4e3de48203347374e414da7945c4f2f7fd13ffe632"},
"libsecp256k1": {:hex, :libsecp256k1, "0.1.10", "d27495e2b9851c7765129b76c53b60f5e275bd6ff68292c50536bf6b8d091a4d", [:make, :mix], [{:mix_erlang_tasks, "0.1.0", [hex: :mix_erlang_tasks, repo: "hexpm", optional: false]}], "hexpm", "09ea06239938571124f7f5a27bc9ac45dfb1cfc2df40d46ee9b59c3d51366652"},
"logger_file_backend": {:hex, :logger_file_backend, "0.0.11", "3bbc5f31d3669e8d09d7a9443e86056fae7fc18e45c6f748c33b8c79a7e147a1", [:mix], [], "hexpm", "62be826f04644c62b0a2bc98a13e2e7ae52c0a4eda020f4c59d7287356d5e445"},
"makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "a10c6eb62cca416019663129699769f0c2ccf39428b3bb3c0cb38c718a0c186d"},
"makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "d4b316c7222a85bbaa2fd7c6e90e37e953257ad196dc229505137c5e505e9eff"},
"math": {:hex, :math, "0.3.0", "e14e7291115201cb155a3567e66d196bf5088a6f55b030d598107d7ae934a11c", [:mix], [], "hexpm", "5f2a14eeb8ed70b14c2dcd7c09e7e7b61aaa856d1fc0f07f53bf0f3586c561c1"},
"meck": {:hex, :meck, "0.8.13", "ffedb39f99b0b99703b8601c6f17c7f76313ee12de6b646e671e3188401f7866", [:rebar3], [], "hexpm", "d34f013c156db51ad57cc556891b9720e6a1c1df5fe2e15af999c84d6cebeb1a"},
"memento": {:hex, :memento, "0.3.1", "b2909390820550d8b90b68ec96f9e15ff8a45a28b6f97fa4a62ef50e87c2f9d9", [:mix], [], "hexpm", "ff8fc66255d21dcd539c5d77a0b5458715bf3efec91b389dd06017bbb4e2e916"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm", "6cbe761d6a0ca5a31a0931bf4c63204bceb64538e664a8ecf784a9a6f3b875f1"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
"mix_erlang_tasks": {:hex, :mix_erlang_tasks, "0.1.0", "36819fec60b80689eb1380938675af215565a89320a9e29c72c70d97512e4649", [:mix], [], "hexpm", "95d2839c422c482a70c08a8702da8242f86b773f8ab6e8602a4eb72da8da04ed"},
"mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm", "b93e2b1e564bdbadfecc297277f9e6d0902da645b417d6c9210f6038ac63489a"},
"mock": {:hex, :mock, "0.3.3", "42a433794b1291a9cf1525c6d26b38e039e0d3a360732b5e467bfc77ef26c914", [:mix], [{:meck, "~> 0.8.13", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "a280d1f7b6f4bbcbd9282616e57502721781c66ee5b540720efabeaf627cc7eb"},
"mox": {:hex, :mox, "0.5.1", "f86bb36026aac1e6f924a4b6d024b05e9adbed5c63e8daa069bd66fb3292165b", [:mix], [], "hexpm", "052346cf322311c49a0f22789f3698eea030eec09b8c47367f0686ef2634ae14"},
"msgpax": {:hex, :msgpax, "2.2.4", "7b3790ef684089076b63c0f08c2f4b079c6311daeb006b69e4ed2bf67518291e", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "b351b6d992d79624a8430a99d21a41b36b1b90edf84326a294e9f4a2de11f089"},
"nimble_csv": {:hex, :nimble_csv, "0.6.0", "a3673f26d41f986774fe6060e309615343d3cb83a6d435754d8b1fdbd5764879", [:mix], [], "hexpm", "b78e15f1c82fd963745ecc4073c47e1f0cdaf3622143342b8c30e9b5eaa546c6"},
"nimble_parsec": {:hex, :nimble_parsec, "0.5.1", "c90796ecee0289dbb5ad16d3ad06f957b0cd1199769641c961cfe0b97db190e0", [:mix], [], "hexpm", "00e3ebdc821fb3a36957320d49e8f4bfa310d73ea31c90e5f925dc75e030da8f"},
"optimal": {:hex, :optimal, "0.3.6", "46bbf52fbbbd238cda81e02560caa84f93a53c75620f1fe19e81e4ae7b07d1dd", [:mix], [], "hexpm", "1a06ea6a653120226b35b283a1cd10039550f2c566edcdec22b29316d73640fd"},
"parallel_stream": {:hex, :parallel_stream, "1.0.6", "b967be2b23f0f6787fab7ed681b4c45a215a81481fb62b01a5b750fa8f30f76c", [:mix], [], "hexpm", "639b2e8749e11b87b9eb42f2ad325d161c170b39b288ac8d04c4f31f8f0823eb"},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"},
"phoenix": {:hex, :phoenix, "1.4.0", "56fe9a809e0e735f3e3b9b31c1b749d4b436e466d8da627b8d82f90eaae714d2", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm", "22da8f659cf13d3ba73b767f66b8c389113ddf0ef7b94225cc84e94b85eac90e"},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.0.0", "c43117a136e7399ea04ecaac73f8f23ee0ffe3e07acfcb8062fe5f4c9f0f6531", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "fe15d9fee5b82f5e64800502011ffe530650d42e1710ae9b14bc4c9be38bf303"},
"phoenix_form_awesomplete": {:hex, :phoenix_form_awesomplete, "0.1.5", "d09aade160b584e3428e1e095645482396f17bddda4f566f1118f12d2598d11c", [:mix], [{:phoenix_html, "~> 2.10", [hex: :phoenix_html, repo: "hexpm", optional: false]}], "hexpm", "acef2dbc638b5bcad92c11e41eb2b55d71f2596741a2f936717b8472196456ec"},
"phoenix_html": {:hex, :phoenix_html, "2.13.3", "850e292ff6e204257f5f9c4c54a8cb1f6fbc16ed53d360c2b780a3d0ba333867", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "8b01b3d6d39731ab18aa548d928b5796166d2500755f553725cfe967bafba7d9"},
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.2.1", "274a4b07c4adbdd7785d45a8b0bb57634d0b4f45b18d2c508b26c0344bd59b8f", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "41b4103a2fa282cfd747d377233baf213c648fdcc7928f432937676532490eee"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "1.1.2", "496c303bdf1b2e98a9d26e89af5bba3ab487ba3a3735f74bf1f4064d2a845a3e", [:mix], [], "hexpm", "1f13f9f0f3e769a667a6b6828d29dec37497a082d195cc52dbef401a9b69bf38"},
"plug": {:hex, :plug, "1.8.3", "12d5f9796dc72e8ac9614e94bda5e51c4c028d0d428e9297650d09e15a684478", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "164baaeb382d19beee0ec484492aa82a9c8685770aee33b24ec727a0971b34d0"},
"plug_cowboy": {:hex, :plug_cowboy, "2.1.0", "b75768153c3a8a9e8039d4b25bb9b14efbc58e9c4a6e6a270abff1cd30cbe320", [:mix], [{:cowboy, "~> 2.5", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "6cd8ddd1bd1fbfa54d3fc61d4719c2057dae67615395d58d40437a919a46f132"},
"plug_crypto": {:hex, :plug_crypto, "1.0.0", "18e49317d3fa343f24620ed22795ec29d4a5e602d52d1513ccea0b07d8ea7d4d", [:mix], [], "hexpm", "73c1682f0e414cfb5d9b95c8e8cd6ffcfdae699e3b05e1db744e58b7be857759"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"},
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"},
"postgrex": {:hex, :postgrex, "0.15.3", "5806baa8a19a68c4d07c7a624ccdb9b57e89cbc573f1b98099e3741214746ae4", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [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", "4737ce62a31747b4c63c12b20c62307e51bb4fcd730ca0c32c280991e0606c90"},
"prometheus": {:hex, :prometheus, "4.4.1", "1e96073b3ed7788053768fea779cbc896ddc3bdd9ba60687f2ad50b252ac87d6", [:mix, :rebar3], [], "hexpm", "d39f2ce1f3f29f3bf04f915aa3cf9c7cd4d2cee2f975e05f526e06cae9b7c902"},
"prometheus_ecto": {:hex, :prometheus_ecto, "1.4.3", "3dd4da1812b8e0dbee81ea58bb3b62ed7588f2eae0c9e97e434c46807ff82311", [:mix], [{:ecto, "~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm", "8d66289f77f913b37eda81fd287340c17e61a447549deb28efc254532b2bed82"},
"prometheus_ex": {:hex, :prometheus_ex, "3.0.5", "fa58cfd983487fc5ead331e9a3e0aa622c67232b3ec71710ced122c4c453a02f", [:mix], [{:prometheus, "~> 4.0", [hex: :prometheus, repo: "hexpm", optional: false]}], "hexpm", "9fd13404a48437e044b288b41f76e64acd9735fb8b0e3809f494811dfa66d0fb"},
"prometheus_phoenix": {:hex, :prometheus_phoenix, "1.3.0", "c4b527e0b3a9ef1af26bdcfbfad3998f37795b9185d475ca610fe4388fdd3bb5", [:mix], [{:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.3 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm", "c4d1404ac4e9d3d963da601db2a7d8ea31194f0017057fabf0cfb9bf5a6c8c75"},
"prometheus_plugs": {:hex, :prometheus_plugs, "1.1.5", "25933d48f8af3a5941dd7b621c889749894d8a1082a6ff7c67cc99dec26377c5", [:mix], [{:accept, "~> 0.1", [hex: :accept, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}, {:prometheus_process_collector, "~> 1.1", [hex: :prometheus_process_collector, repo: "hexpm", optional: true]}], "hexpm", "0273a6483ccb936d79ca19b0ab629aef0dba958697c94782bb728b920dfc6a79"},
"prometheus_process_collector": {:hex, :prometheus_process_collector, "1.4.3", "657386e8f142fc817347d95c1f3a05ab08710f7df9e7f86db6facaed107ed929", [:rebar3], [{:prometheus, "~> 4.0", [hex: :prometheus, repo: "hexpm", optional: false]}], "hexpm", "c121bb973c31cce5314c8f0dec921ba0e483d054684597e831eea4d936254ddf"},
"qrcode": {:hex, :qrcode, "0.1.5", "551271830515c150f34568345b060c625deb0e6691db2a01b0a6de3aafc93886", [:mix], [], "hexpm", "a266b7fb7be0d3b713912055dde3575927eca920e5d604ded45cd534f6b7a447"},
"que": {:hex, :que, "0.10.1", "788ed0ec92ed69bdf9cfb29bf41a94ca6355b8d44959bd0669cf706e557ac891", [:mix], [{:ex_utils, "~> 0.1.6", [hex: :ex_utils, repo: "hexpm", optional: false]}, {:memento, "~> 0.3.0", [hex: :memento, repo: "hexpm", optional: false]}], "hexpm", "a737b365253e75dbd24b2d51acc1d851049e87baae08cd0c94e2bc5cd65088d5"},
"ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm", "451d8527787df716d99dc36162fca05934915db0b6141bbdac2ea8d3c7afc7d7"},
"sobelow": {:hex, :sobelow, "0.8.0", "a3ec73e546dfde19f14818e5000c418e3f305d9edb070e79dd391de0ae1cd1ea", [:mix], [], "hexpm", "06feb23b7e364c30091d2e49364e4a56148b37a4f841d27f7a5b2686bb046655"},
"spandex": {:git, "https://github.com/spandex-project/spandex.git", "92992b4aaf3d92e031c2417ff2e6c9e94d27fe36", [branch: "allow-setting-trace-key"]},
"spandex_datadog": {:hex, :spandex_datadog, "0.4.0", "75113a73e843123074886a2e31994af07d6e0632749a8d97e9ca6157b120c287", [:mix], [{:msgpax, "~> 2.2.1", [hex: :msgpax, repo: "hexpm", optional: false]}, {:spandex, "~> 2.3", [hex: :spandex, repo: "hexpm", optional: false]}], "hexpm"},
"spandex_ecto": {:hex, :spandex_ecto, "0.4.0", "deaeaddc11a35f1c551206c53d09bb93a0da5808dbef751430e465c8c7de01d3", [:mix], [{:spandex, "~> 2.2", [hex: :spandex, repo: "hexpm", optional: false]}], "hexpm"},
"spandex_phoenix": {:hex, :spandex_phoenix, "0.3.2", "e81889d80852a895cf62ce2e25181b15766d21e8647962e0a4458414b935feb3", [:mix], [{:plug, "~> 1.3", [hex: :plug, repo: "hexpm", optional: false]}, {:spandex, "~> 2.2", [hex: :spandex, repo: "hexpm", optional: false]}], "hexpm"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.5", "6eaf7ad16cb568bb01753dbbd7a95ff8b91c7979482b95f38443fe2c8852a79b", [:make, :mix, :rebar3], [], "hexpm"},
"telemetry": {:hex, :telemetry, "0.4.1", "ae2718484892448a24470e6aa341bc847c3277bfb8d4e9289f7474d752c09c7f", [:rebar3], [], "hexpm"},
"timex": {:hex, :timex, "3.6.1", "efdf56d0e67a6b956cc57774353b0329c8ab7726766a11547e529357ffdc1d56", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5 or ~> 1.0.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"},
"tzdata": {:hex, :tzdata, "1.0.1", "f6027a331af7d837471248e62733c6ebee86a72e57c613aa071ebb1f750fc71a", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"},
"wallaby": {:hex, :wallaby, "0.22.0", "e5d16bfa7ab23562c8a6e3b0a31445a2fd470ca622082a910114807ba823780d", [:mix], [{:httpoison, "~> 0.12 or ~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:poison, ">= 1.4.0", [hex: :poison, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}], "hexpm"},
"websocket_client": {:hex, :websocket_client, "1.3.0", "2275d7daaa1cdacebf2068891c9844b15f4fdc3de3ec2602420c2fb486db59b6", [:rebar3], [], "hexpm"},
"spandex_datadog": {:hex, :spandex_datadog, "0.4.0", "75113a73e843123074886a2e31994af07d6e0632749a8d97e9ca6157b120c287", [:mix], [{:msgpax, "~> 2.2.1", [hex: :msgpax, repo: "hexpm", optional: false]}, {:spandex, "~> 2.3", [hex: :spandex, repo: "hexpm", optional: false]}], "hexpm", "34de8fd2942e3c1097d596391fe2a8102591f2fa5f7edb6fe397559c0d39edcf"},
"spandex_ecto": {:hex, :spandex_ecto, "0.4.0", "deaeaddc11a35f1c551206c53d09bb93a0da5808dbef751430e465c8c7de01d3", [:mix], [{:spandex, "~> 2.2", [hex: :spandex, repo: "hexpm", optional: false]}], "hexpm", "ef6037134548bba7a3b0efe39d8fc1a0ff95b43d6a046f193a552d311a637a97"},
"spandex_phoenix": {:hex, :spandex_phoenix, "0.3.2", "e81889d80852a895cf62ce2e25181b15766d21e8647962e0a4458414b935feb3", [:mix], [{:plug, "~> 1.3", [hex: :plug, repo: "hexpm", optional: false]}, {:spandex, "~> 2.2", [hex: :spandex, repo: "hexpm", optional: false]}], "hexpm", "6e882bb64093889a73b7b77c426c1fd5651d072cd97e8f3e8d89d502d7b44b48"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.5", "6eaf7ad16cb568bb01753dbbd7a95ff8b91c7979482b95f38443fe2c8852a79b", [:make, :mix, :rebar3], [], "hexpm", "13104d7897e38ed7f044c4de953a6c28597d1c952075eb2e328bc6d6f2bfc496"},
"telemetry": {:hex, :telemetry, "0.4.1", "ae2718484892448a24470e6aa341bc847c3277bfb8d4e9289f7474d752c09c7f", [:rebar3], [], "hexpm", "4738382e36a0a9a2b6e25d67c960e40e1a2c95560b9f936d8e29de8cd858480f"},
"timex": {:hex, :timex, "3.6.1", "efdf56d0e67a6b956cc57774353b0329c8ab7726766a11547e529357ffdc1d56", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5 or ~> 1.0.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "f354efb2400dd7a80fd9eb6c8419068c4f632da4ac47f3d8822d6e33f08bc852"},
"tzdata": {:hex, :tzdata, "1.0.1", "f6027a331af7d837471248e62733c6ebee86a72e57c613aa071ebb1f750fc71a", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "cf1345dfbce6acdfd4e23cbb36e96e53d1981bc89181cd0b936f4f398f4c0b78"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm", "1d1848c40487cdb0b30e8ed975e34e025860c02e419cb615d255849f3427439d"},
"wallaby": {:hex, :wallaby, "0.22.0", "e5d16bfa7ab23562c8a6e3b0a31445a2fd470ca622082a910114807ba823780d", [:mix], [{:httpoison, "~> 0.12 or ~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:poison, ">= 1.4.0", [hex: :poison, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}], "hexpm", "b5ec4fdb22f79bc1656cf8766718d0ab77e961839a5946a3ecf212448e30bf15"},
"websocket_client": {:hex, :websocket_client, "1.3.0", "2275d7daaa1cdacebf2068891c9844b15f4fdc3de3ec2602420c2fb486db59b6", [:rebar3], [], "hexpm", "b864fa076f059b615da4ab99240e515b26132ce4d2d0f9df5d7f22f01fa04b65"},
"wobserver": {:git, "https://github.com/poanetwork/wobserver.git", "13bcda30a87f4f0be1878920a79433ad831eefbe", [branch: "support-https"]},
}

Loading…
Cancel
Save