diff --git a/README.md b/README.md index 8a8d934b9d..f201753977 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,13 @@ The [development stack page](https://github.com/poanetwork/blockscout/wiki/Devel `cd apps/block_scout_web/assets && npm install; cd -` `cd apps/explorer && npm install; cd -` - 7. Start Phoenix Server. + 7. Update your JSON RPC Variant in `apps/explorer/config/dev.exs` and `apps/indexer/config/dev.exs`. + For `variant`, enter `ganache`, `geth`, or `parity` + + 8. Update your JSON RPC Endpoint in `apps/explorer/config/dev/` and `apps/indexer/config/dev/` + For the `variant` chosen in step 7, enter the correct information for the corresponding JSON RPC Endpoint in `parity.exs`, `geth.exs`, or `ganache.exs` + + 9. Start Phoenix Server. `mix phx.server` Now you can visit [`localhost:4000`](http://localhost:4000) from your browser. @@ -204,8 +210,8 @@ mix coveralls.html --umbrella --exclude no_parity | Protocol | URL | |:----------|:-----------------------------------| -| HTTP | `https://sokol-trace.poa.network` | -| WebSocket | `wss://sokol-ws.poa.network/ws` | +| HTTP | `http://localhost:8545` | +| WebSocket | `ws://localhost:8546` | ##### Geth diff --git a/apps/block_scout_web/lib/block_scout_web/chain.ex b/apps/block_scout_web/lib/block_scout_web/chain.ex index 08e4e5c321..1d956cfa65 100644 --- a/apps/block_scout_web/lib/block_scout_web/chain.ex +++ b/apps/block_scout_web/lib/block_scout_web/chain.ex @@ -130,9 +130,6 @@ defmodule BlockScoutWeb.Chain do end end - def paging_options(%{"inserted_at" => inserted_at}), - do: [paging_options: %{@default_paging_options | key: inserted_at}] - def paging_options(%{"token_name" => name, "token_type" => type, "token_inserted_at" => inserted_at}), do: [paging_options: %{@default_paging_options | key: {name, type, inserted_at}}] @@ -180,13 +177,8 @@ defmodule BlockScoutWeb.Chain do %{"block_number" => block_number, "index" => index} end - defp paging_params(%TokenTransfer{inserted_at: inserted_at}) do - inserted_at_datetime = - inserted_at - |> DateTime.from_naive!("Etc/UTC") - |> DateTime.to_iso8601() - - %{"inserted_at" => inserted_at_datetime} + defp paging_params(%TokenTransfer{block_number: block_number, log_index: index}) do + %{"block_number" => block_number, "index" => index} end defp paging_params(%Address.Token{name: name, type: type, inserted_at: inserted_at}) do diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex index 36c32740e7..08be14a9fc 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex @@ -8,10 +8,12 @@ defmodule BlockScoutWeb.AddressInternalTransactionController do import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1] import BlockScoutWeb.Chain, only: [current_filter: 1, paging_options: 1, next_page_params: 3, split_list_by_page: 1] + alias BlockScoutWeb.InternalTransactionView alias Explorer.{Chain, Market} alias Explorer.ExchangeRates.Token + alias Phoenix.View - def index(conn, %{"address_id" => address_hash_string} = params) do + def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), {:ok, address} <- Chain.hash_to_address(address_hash) do full_options = @@ -28,14 +30,45 @@ defmodule BlockScoutWeb.AddressInternalTransactionController do internal_transactions_plus_one = Chain.address_to_internal_transactions(address, full_options) {internal_transactions, next_page} = split_list_by_page(internal_transactions_plus_one) + next_page_path = + case next_page_params(next_page, internal_transactions, params) do + nil -> + nil + + next_page_params -> + address_internal_transaction_path(conn, :index, address_hash, Map.delete(next_page_params, "type")) + end + + internal_transactions_json = + Enum.map(internal_transactions, fn internal_transaction -> + View.render_to_string( + InternalTransactionView, + "_tile.html", + current_address: address, + internal_transaction: internal_transaction + ) + end) + + json(conn, %{items: internal_transactions_json, next_page_path: next_page_path}) + else + :error -> + not_found(conn) + + {:error, :not_found} -> + not_found(conn) + end + end + + def index(conn, %{"address_id" => address_hash_string} = params) do + with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), + {:ok, address} <- Chain.hash_to_address(address_hash) do render( conn, "index.html", address: address, - next_page_params: next_page_params(next_page, internal_transactions, params), + current_path: current_path(conn), exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), filter: params["filter"], - internal_transactions: internal_transactions, transaction_count: transaction_count(address), validation_count: validation_count(address) ) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex index 15a757065f..a0e96df02a 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex @@ -1,8 +1,10 @@ defmodule BlockScoutWeb.AddressTokenTransferController do use BlockScoutWeb, :controller - alias Explorer.{Chain, Market} + alias BlockScoutWeb.TransactionView alias Explorer.ExchangeRates.Token + alias Explorer.{Chain, Market} + alias Phoenix.View import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1] @@ -11,12 +13,16 @@ defmodule BlockScoutWeb.AddressTokenTransferController do def index( conn, - %{"address_id" => address_hash_string, "address_token_id" => token_hash_string} = params + %{ + "address_id" => address_hash_string, + "address_token_id" => token_hash_string, + "type" => "JSON" + } = params ) do with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), {:ok, token_hash} <- Chain.string_to_address_hash(token_hash_string), {:ok, address} <- Chain.hash_to_address(address_hash), - {:ok, token} <- Chain.token_from_address_hash(token_hash) do + {:ok, _} <- Chain.token_from_address_hash(token_hash) do transactions = Chain.address_to_transactions_with_token_transfers( address_hash, @@ -26,15 +32,58 @@ defmodule BlockScoutWeb.AddressTokenTransferController do {transactions_paginated, next_page} = split_list_by_page(transactions) + next_page_path = + case next_page_params(next_page, transactions_paginated, params) do + nil -> + nil + + next_page_params -> + address_token_transfers_path( + conn, + :index, + address_hash_string, + token_hash_string, + Map.delete(next_page_params, "type") + ) + end + + transfers_json = + Enum.map(transactions_paginated, fn transaction -> + View.render_to_string( + TransactionView, + "_tile.html", + conn: conn, + transaction: transaction, + current_address: address + ) + end) + + json(conn, %{items: transfers_json, next_page_path: next_page_path}) + else + :error -> + unprocessable_entity(conn) + + {:error, :not_found} -> + not_found(conn) + end + end + + def index( + conn, + %{"address_id" => address_hash_string, "address_token_id" => token_hash_string} + ) do + with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), + {:ok, token_hash} <- Chain.string_to_address_hash(token_hash_string), + {:ok, address} <- Chain.hash_to_address(address_hash), + {:ok, token} <- Chain.token_from_address_hash(token_hash) do render( conn, "index.html", address: address, exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), - next_page_params: next_page_params(next_page, transactions_paginated, params), + current_path: current_path(conn), token: token, transaction_count: transaction_count(address), - transactions: transactions_paginated, validation_count: validation_count(address) ) else diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_internal_transaction/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_internal_transaction/index.html.eex index e866c4ae19..2883e278f2 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_internal_transaction/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_internal_transaction/index.html.eex @@ -7,7 +7,7 @@ <%= render BlockScoutWeb.AddressView, "_tabs.html", assigns %> -
+
+

<%= gettext "Internal Transactions" %>

- <%= if Enum.count(@internal_transactions) > 0 do %> - - <%= for internal_transaction <- @internal_transactions do %> - <%= render BlockScoutWeb.InternalTransactionView, "_tile.html", current_address: @address, internal_transaction: internal_transaction %> - <% end %> - - <% else %> + +
<%= gettext "There are no internal transactions for this address." %>
- <% end %> -
- <%= if @next_page_params do %> - <%= link( - gettext("Older"), - class: "button button-secondary button-sm float-right mt-3", - to: address_internal_transaction_path( - @conn, - :index, - @address, - @next_page_params - ) - ) %> - <% end %> +
+
+ + + + + <%= gettext("Loading") %>... +
+
+ +
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_token_transfer/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_token_transfer/index.html.eex index f6334637bf..ba10748ee1 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_token_transfer/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_token_transfer/index.html.eex @@ -7,41 +7,36 @@ <%= render BlockScoutWeb.AddressView, "_tabs.html", assigns %>
-
+

<%= gettext "Tokens" %> / <%= token_name(@token) %>

- - <%= if Enum.any?(@transactions) do %> - - <%= for transaction <- @transactions do %> - <%= render( - BlockScoutWeb.TransactionView, - "_tile.html", - transaction: transaction, - current_address: @address - ) %> - <% end %> +
+ + + - <% else %> -
- <%= gettext "There are no token transfers for this address." %> -
- <% end %> - - <%= if @next_page_params do %> - <%= link( - gettext("Next"), - class: "button button-secondary button-sm float-right mt-3", - to: address_token_transfers_path( - @conn, - :index, - @address.hash, - @token.contract_address_hash, - @next_page_params - ) - ) %> - <% end %> + <%= gettext("Loading...") %> +
+ + +
+ +
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/tokens/transfer/_token_transfer.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/tokens/transfer/_token_transfer.html.eex index 311c41ec2f..a478c791de 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/tokens/transfer/_token_transfer.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/tokens/transfer/_token_transfer.html.eex @@ -43,7 +43,7 @@ <%= link( gettext( "Block #%{number}", - number: @transfer.transaction.block_number + number: @transfer.block_number ), class: "mr-2 mr-sm-0 text-muted", to: block_path(BlockScoutWeb.Endpoint, :show, @transfer.transaction.block_number) diff --git a/apps/block_scout_web/priv/gettext/default.pot b/apps/block_scout_web/priv/gettext/default.pot index 07e1143075..6734912e56 100644 --- a/apps/block_scout_web/priv/gettext/default.pot +++ b/apps/block_scout_web/priv/gettext/default.pot @@ -505,7 +505,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/_tabs.html.eex:21 #: lib/block_scout_web/templates/address/_tabs.html.eex:81 -#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:57 +#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:58 #: lib/block_scout_web/templates/address_validation/index.html.eex:24 #: lib/block_scout_web/templates/address_validation/index.html.eex:75 #: lib/block_scout_web/templates/transaction/_tabs.html.eex:14 @@ -610,7 +610,6 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_token/index.html.eex:25 -#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:34 msgid "Next" msgstr "" @@ -638,7 +637,8 @@ msgid "OUT" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:72 +#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:76 +#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:31 #: lib/block_scout_web/templates/address_validation/index.html.eex:117 #: lib/block_scout_web/templates/block/index.html.eex:30 #: lib/block_scout_web/templates/block_transaction/index.html.eex:50 @@ -815,7 +815,7 @@ msgid "There are no holders for this Token." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:66 +#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:64 msgid "There are no internal transactions for this address." msgstr "" @@ -831,7 +831,7 @@ msgid "There are no logs for this transaction." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:28 +#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:22 msgid "There are no token transfers for this address." msgstr "" @@ -1187,6 +1187,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_read_contract/index.html.eex:17 +#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:19 #: lib/block_scout_web/templates/tokens/read_contract/index.html.eex:25 msgid "Loading..." msgstr "" @@ -1214,6 +1215,9 @@ msgid "GraphQL" msgstr "" #, elixir-format +#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:72 +#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:83 +#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:38 #: lib/block_scout_web/templates/address_transaction/index.html.eex:61 #: lib/block_scout_web/templates/block/index.html.eex:22 #: lib/block_scout_web/templates/pending_transaction/index.html.eex:33 @@ -1409,6 +1413,8 @@ msgid "Log Data" msgstr "" #, elixir-format +#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:60 +#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:26 #: lib/block_scout_web/templates/tokens/transfer/index.html.eex:21 msgid "Something went wrong, click to reload." msgstr "" diff --git a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po index dbedb19301..105c66ff83 100644 --- a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po +++ b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po @@ -505,7 +505,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/_tabs.html.eex:21 #: lib/block_scout_web/templates/address/_tabs.html.eex:81 -#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:57 +#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:58 #: lib/block_scout_web/templates/address_validation/index.html.eex:24 #: lib/block_scout_web/templates/address_validation/index.html.eex:75 #: lib/block_scout_web/templates/transaction/_tabs.html.eex:14 @@ -610,7 +610,6 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_token/index.html.eex:25 -#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:34 msgid "Next" msgstr "" @@ -638,7 +637,8 @@ msgid "OUT" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:72 +#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:76 +#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:31 #: lib/block_scout_web/templates/address_validation/index.html.eex:117 #: lib/block_scout_web/templates/block/index.html.eex:30 #: lib/block_scout_web/templates/block_transaction/index.html.eex:50 @@ -815,7 +815,7 @@ msgid "There are no holders for this Token." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:66 +#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:64 msgid "There are no internal transactions for this address." msgstr "" @@ -831,7 +831,7 @@ msgid "There are no logs for this transaction." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:28 +#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:22 msgid "There are no token transfers for this address." msgstr "" @@ -1187,6 +1187,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_read_contract/index.html.eex:17 +#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:19 #: lib/block_scout_web/templates/tokens/read_contract/index.html.eex:25 msgid "Loading..." msgstr "" @@ -1214,6 +1215,9 @@ msgid "GraphQL" msgstr "" #, elixir-format +#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:72 +#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:83 +#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:38 #: lib/block_scout_web/templates/address_transaction/index.html.eex:61 #: lib/block_scout_web/templates/block/index.html.eex:22 #: lib/block_scout_web/templates/pending_transaction/index.html.eex:33 @@ -1409,6 +1413,8 @@ msgid "Log Data" msgstr "" #, elixir-format +#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:60 +#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:26 #: lib/block_scout_web/templates/tokens/transfer/index.html.eex:21 msgid "Something went wrong, click to reload." msgstr "" diff --git a/apps/block_scout_web/test/block_scout_web/controllers/address_internal_transaction_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/address_internal_transaction_controller_test.exs index 19d03d9cdd..dd30205fd4 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/address_internal_transaction_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/address_internal_transaction_controller_test.exs @@ -1,7 +1,8 @@ defmodule BlockScoutWeb.AddressInternalTransactionControllerTest do use BlockScoutWeb.ConnCase - import BlockScoutWeb.Router.Helpers, only: [address_internal_transaction_path: 3] + import BlockScoutWeb.Router.Helpers, + only: [address_internal_transaction_path: 3, address_internal_transaction_path: 4] alias Explorer.Chain.{Block, InternalTransaction, Transaction} alias Explorer.ExchangeRates.Token @@ -21,6 +22,14 @@ defmodule BlockScoutWeb.AddressInternalTransactionControllerTest do assert html_response(conn, 404) end + test "includes USD exchange rate value for address in assigns", %{conn: conn} do + address = insert(:address) + + conn = get(conn, address_internal_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash)) + + assert %Token{} = conn.assigns.exchange_rate + end + test "returns internal transactions for the address", %{conn: conn} do address = insert(:address) @@ -47,29 +56,101 @@ defmodule BlockScoutWeb.AddressInternalTransactionControllerTest do transaction_index: transaction.index ) - path = address_internal_transaction_path(conn, :index, address) + path = address_internal_transaction_path(conn, :index, address, %{"type" => "JSON"}) conn = get(conn, path) - actual_internal_transaction_primary_keys = - Enum.map(conn.assigns.internal_transactions, &{&1.transaction_hash, &1.index}) + internal_transaction_tiles = json_response(conn, 200)["items"] + + assert Enum.all?([from_internal_transaction, to_internal_transaction], fn internal_transaction -> + Enum.any?(internal_transaction_tiles, fn tile -> + String.contains?(tile, to_string(internal_transaction.transaction_hash)) && + String.contains?(tile, "data-internal-transaction-index=\"#{internal_transaction.index}\"") + end) + end) + end + + test "returns internal transactions coming from the address", %{conn: conn} do + address = insert(:address) + + transaction = + :transaction + |> insert() + |> with_block(insert(:block, number: 1)) + + from_internal_transaction = + insert(:internal_transaction, + transaction: transaction, + from_address: address, + index: 1, + block_number: transaction.block_number, + transaction_index: transaction.index + ) + + to_internal_transaction = + insert(:internal_transaction, + transaction: transaction, + to_address: address, + index: 2, + block_number: transaction.block_number, + transaction_index: transaction.index + ) + + path = address_internal_transaction_path(conn, :index, address, %{"filter" => "from", "type" => "JSON"}) + conn = get(conn, path) - assert Enum.member?( - actual_internal_transaction_primary_keys, - {from_internal_transaction.transaction_hash, from_internal_transaction.index} - ) + internal_transaction_tiles = json_response(conn, 200)["items"] - assert Enum.member?( - actual_internal_transaction_primary_keys, - {to_internal_transaction.transaction_hash, to_internal_transaction.index} - ) + assert Enum.any?(internal_transaction_tiles, fn tile -> + String.contains?(tile, to_string(from_internal_transaction.transaction_hash)) && + String.contains?(tile, "data-internal-transaction-index=\"#{from_internal_transaction.index}\"") + end) + + refute Enum.any?(internal_transaction_tiles, fn tile -> + String.contains?(tile, to_string(to_internal_transaction.transaction_hash)) && + String.contains?(tile, "data-internal-transaction-index=\"#{to_internal_transaction.index}\"") + end) end - test "includes USD exchange rate value for address in assigns", %{conn: conn} do + test "returns internal transactions going to the address", %{conn: conn} do address = insert(:address) - conn = get(conn, address_internal_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash)) + transaction = + :transaction + |> insert() + |> with_block(insert(:block, number: 1)) - assert %Token{} = conn.assigns.exchange_rate + from_internal_transaction = + insert(:internal_transaction, + transaction: transaction, + from_address: address, + index: 1, + block_number: transaction.block_number, + transaction_index: transaction.index + ) + + to_internal_transaction = + insert(:internal_transaction, + transaction: transaction, + to_address: address, + index: 2, + block_number: transaction.block_number, + transaction_index: transaction.index + ) + + path = address_internal_transaction_path(conn, :index, address, %{"filter" => "to", "type" => "JSON"}) + conn = get(conn, path) + + internal_transaction_tiles = json_response(conn, 200)["items"] + + assert Enum.any?(internal_transaction_tiles, fn tile -> + String.contains?(tile, to_string(to_internal_transaction.transaction_hash)) && + String.contains?(tile, "data-internal-transaction-index=\"#{to_internal_transaction.index}\"") + end) + + refute Enum.any?(internal_transaction_tiles, fn tile -> + String.contains?(tile, to_string(from_internal_transaction.transaction_hash)) && + String.contains?(tile, "data-internal-transaction-index=\"#{from_internal_transaction.index}\"") + end) end test "returns next page of results based on last seen internal transaction", %{conn: conn} do @@ -105,7 +186,6 @@ defmodule BlockScoutWeb.AddressInternalTransactionControllerTest do transaction_index: transaction_1.index ) end) - |> Enum.map(&"#{&1.transaction_hash}.#{&1.index}") transaction_2_hashes = 1..20 @@ -119,7 +199,6 @@ defmodule BlockScoutWeb.AddressInternalTransactionControllerTest do transaction_index: transaction_2.index ) end) - |> Enum.map(&"#{&1.transaction_hash}.#{&1.index}") transaction_3_hashes = 1..10 @@ -133,9 +212,8 @@ defmodule BlockScoutWeb.AddressInternalTransactionControllerTest do transaction_index: transaction_3.index ) end) - |> Enum.map(&"#{&1.transaction_hash}.#{&1.index}") - second_page_hashes = transaction_1_hashes ++ transaction_2_hashes ++ transaction_3_hashes + second_page = transaction_1_hashes ++ transaction_2_hashes ++ transaction_3_hashes %InternalTransaction{index: index} = insert( @@ -151,15 +229,18 @@ defmodule BlockScoutWeb.AddressInternalTransactionControllerTest do get(conn, address_internal_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash), %{ "block_number" => Integer.to_string(b_block.number), "transaction_index" => Integer.to_string(transaction_3.index), - "index" => Integer.to_string(index) + "index" => Integer.to_string(index), + "type" => "JSON" }) - actual_hashes = - conn.assigns.internal_transactions - |> Enum.map(&"#{&1.transaction_hash}.#{&1.index}") - |> Enum.reverse() + internal_transaction_tiles = json_response(conn, 200)["items"] - assert second_page_hashes == actual_hashes + assert Enum.all?(second_page, fn internal_transaction -> + Enum.any?(internal_transaction_tiles, fn tile -> + String.contains?(tile, to_string(internal_transaction.transaction_hash)) && + String.contains?(tile, "data-internal-transaction-index=\"#{internal_transaction.index}\"") + end) + end) end test "next_page_params exist if not on last page", %{conn: conn} do @@ -184,10 +265,17 @@ defmodule BlockScoutWeb.AddressInternalTransactionControllerTest do ) end) - conn = get(conn, address_internal_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash)) + conn = + get(conn, address_internal_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash, %{"type" => "JSON"})) - assert %{"block_number" => ^number, "index" => 11, "transaction_index" => ^transaction_index} = - conn.assigns.next_page_params + expected_response = + address_internal_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash, %{ + "block_number" => number, + "index" => 11, + "transaction_index" => transaction_index + }) + + assert expected_response == json_response(conn, 200)["next_page_path"] end test "next_page_params are empty if on last page", %{conn: conn} do @@ -208,9 +296,10 @@ defmodule BlockScoutWeb.AddressInternalTransactionControllerTest do ) end) - conn = get(conn, address_internal_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash)) + conn = + get(conn, address_internal_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash, %{"type" => "JSON"})) - refute conn.assigns.next_page_params + assert %{"next_page_path" => nil} = json_response(conn, 200) end end end diff --git a/apps/block_scout_web/test/block_scout_web/controllers/address_token_transfer_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/address_token_transfer_controller_test.exs index aeb32b06ac..d064eae688 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/address_token_transfer_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/address_token_transfer_controller_test.exs @@ -1,7 +1,8 @@ defmodule BlockScoutWeb.AddressTokenTransferControllerTest do use BlockScoutWeb.ConnCase - import BlockScoutWeb.Router.Helpers, only: [address_token_transfers_path: 4] + import BlockScoutWeb.Router.Helpers, + only: [address_token_transfers_path: 4, address_token_transfers_path: 5] alias Explorer.Chain.{Address, Token} @@ -15,6 +16,7 @@ defmodule BlockScoutWeb.AddressTokenTransferControllerTest do test "with invalid token hash", %{conn: conn} do address_hash = "0x8bf38d4764929064f2d4d3a56520a76ab3df415b" + conn = get(conn, address_token_transfers_path(conn, :index, address_hash, "invalid_address")) assert html_response(conn, 422) @@ -35,25 +37,80 @@ defmodule BlockScoutWeb.AddressTokenTransferControllerTest do assert html_response(conn, 404) end + end + describe "GET index/2 JSON" do test "without token transfers for a token", %{conn: conn} do %Address{hash: address_hash} = insert(:address) %Token{contract_address_hash: token_hash} = insert(:token) - conn = get(conn, address_token_transfers_path(conn, :index, address_hash, token_hash)) + conn = + get(conn, address_token_transfers_path(conn, :index, address_hash, token_hash), %{ + type: "JSON" + }) + + assert json_response(conn, 200) == %{"items" => [], "next_page_path" => nil} + end + + test "returns the correct number of transactions", %{conn: conn} do + address = insert(:address) + token = insert(:token) + + inserted_transactions = + Enum.map(1..5, fn index -> + block = insert(:block, number: 1000 - index) + + transaction = + :transaction + |> insert() + |> with_block(block) + + insert( + :token_transfer, + to_address: address, + transaction: transaction, + token_contract_address: token.contract_address + ) + + transaction + end) - assert html_response(conn, 200) - assert conn.assigns.transactions == [] + conn = + get( + conn, + address_token_transfers_path(conn, :index, address.hash, token.contract_address_hash), + %{type: "JSON"} + ) + + response_items = + conn + |> json_response(200) + |> Map.get("items") + + items_length = length(response_items) + + assert items_length == 5 + + assert Enum.all?(inserted_transactions, fn transaction -> + Enum.any?(response_items, fn item -> + String.contains?( + item, + "data-transaction-hash=\"#{to_string(transaction.hash)}\"" + ) + end) + end) end - test "returns the transactions that have token transfers for the given address and token", %{conn: conn} do + test "returns next_page_path as null when there are no more pages", %{conn: conn} do address = insert(:address) token = insert(:token) + block = insert(:block, number: 1000) + transaction = :transaction |> insert() - |> with_block() + |> with_block(block) insert( :token_transfer, @@ -62,19 +119,21 @@ defmodule BlockScoutWeb.AddressTokenTransferControllerTest do token_contract_address: token.contract_address ) - conn = get(conn, address_token_transfers_path(conn, :index, address.hash, token.contract_address_hash)) - - transaction_hashes = Enum.map(conn.assigns.transactions, & &1.hash) + conn = + get( + conn, + address_token_transfers_path(conn, :index, address.hash, token.contract_address_hash), + %{type: "JSON"} + ) - assert html_response(conn, 200) - assert transaction_hashes == [transaction.hash] + assert Map.get(json_response(conn, 200), "next_page_path") == nil end - test "returns next page of results based on last seen transactions", %{conn: conn} do + test "returns next_page_path when there are more items", %{conn: conn} do address = insert(:address) token = insert(:token) - second_page_transactions = + page_last_transfer = 1..50 |> Enum.map(fn index -> block = insert(:block, number: 1000 - index) @@ -93,22 +152,84 @@ defmodule BlockScoutWeb.AddressTokenTransferControllerTest do transaction end) - |> Enum.map(& &1.hash) + |> List.last() - transaction = - :transaction - |> insert() - |> with_block(insert(:block, number: 1002)) + Enum.each(51..60, fn index -> + block = insert(:block, number: 1000 - index) + + transaction = + :transaction + |> insert() + |> with_block(block) + + insert( + :token_transfer, + to_address: address, + transaction: transaction, + token_contract_address: token.contract_address + ) + end) conn = - get(conn, address_token_transfers_path(conn, :index, address.hash, token.contract_address_hash), %{ - "block_number" => Integer.to_string(transaction.block_number), - "index" => Integer.to_string(transaction.index) + get( + conn, + address_token_transfers_path(conn, :index, address.hash, token.contract_address_hash), + %{type: "JSON"} + ) + + expected_path = + address_token_transfers_path(conn, :index, address.hash, token.contract_address_hash, %{ + block_number: page_last_transfer.block_number, + index: page_last_transfer.index }) - actual_transactions = Enum.map(conn.assigns.transactions, & &1.hash) + assert Map.get(json_response(conn, 200), "next_page_path") == expected_path + end + + test "with invalid address hash", %{conn: conn} do + token_hash = "0xc8982771dd50285389c352c175ada74d074427c7" + + conn = + get(conn, address_token_transfers_path(conn, :index, "invalid_address", token_hash), %{ + type: "JSON" + }) + + assert html_response(conn, 422) + end + + test "with invalid token hash", %{conn: conn} do + address_hash = "0x8bf38d4764929064f2d4d3a56520a76ab3df415b" + + conn = + get(conn, address_token_transfers_path(conn, :index, address_hash, "invalid_address"), %{ + type: "JSON" + }) + + assert html_response(conn, 422) + end + + test "with an address that doesn't exist in our database", %{conn: conn} do + address_hash = "0x8bf38d4764929064f2d4d3a56520a76ab3df415b" + %Token{contract_address_hash: token_hash} = insert(:token) + + conn = + get(conn, address_token_transfers_path(conn, :index, address_hash, token_hash), %{ + type: "JSON" + }) + + assert html_response(conn, 404) + end + + test "with a token that doesn't exist in our database", %{conn: conn} do + %Address{hash: address_hash} = insert(:address) + token_hash = "0x8bf38d4764929064f2d4d3a56520a76ab3df415b" - assert second_page_transactions == actual_transactions + conn = + get(conn, address_token_transfers_path(conn, :index, address_hash, token_hash), %{ + type: "JSON" + }) + + assert html_response(conn, 404) end end end diff --git a/apps/block_scout_web/test/block_scout_web/controllers/transaction_token_transfer_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/transaction_token_transfer_controller_test.exs index a5b13b6bb0..4ff1801610 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/transaction_token_transfer_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/transaction_token_transfer_controller_test.exs @@ -82,25 +82,21 @@ defmodule BlockScoutWeb.TransactionTokenTransferControllerTest do |> insert() |> with_block() - {:ok, first_transfer_time} = NaiveDateTime.new(2000, 1, 1, 0, 0, 5) - {:ok, remaining_transfers_time} = NaiveDateTime.new(1999, 1, 1, 0, 0, 0) - insert(:token_transfer, transaction: transaction, inserted_at: first_transfer_time) + token_transfer = insert(:token_transfer, transaction: transaction, block_number: 1000, log_index: 1) - 1..5 - |> Enum.each(fn log_index -> - insert(:token_transfer, transaction: transaction, inserted_at: remaining_transfers_time, log_index: log_index) + Enum.each(2..5, fn item -> + insert(:token_transfer, transaction: transaction, block_number: item + 1001, log_index: item + 1) end) conn = get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, transaction.hash), %{ - "inserted_at" => first_transfer_time |> DateTime.from_naive!("Etc/UTC") |> DateTime.to_iso8601() + "block_number" => "1000", + "index" => "1" }) - actual_times = - conn.assigns.token_transfers - |> Enum.map(& &1.inserted_at) + actual_log_indexes = Enum.map(conn.assigns.token_transfers, & &1.log_index) - refute Enum.any?(actual_times, fn time -> first_transfer_time == time end) + refute Enum.any?(actual_log_indexes, fn log_index -> log_index == token_transfer.log_index end) end test "next_page_params exist if not on last page", %{conn: conn} do diff --git a/apps/block_scout_web/test/block_scout_web/features/viewing_addresses_test.exs b/apps/block_scout_web/test/block_scout_web/features/viewing_addresses_test.exs index 05c7e85360..58e4682114 100644 --- a/apps/block_scout_web/test/block_scout_web/features/viewing_addresses_test.exs +++ b/apps/block_scout_web/test/block_scout_web/features/viewing_addresses_test.exs @@ -147,35 +147,6 @@ defmodule BlockScoutWeb.ViewingAddressesTest do |> assert_has(AddressPage.transaction(transactions.from_taft)) end - test "contract creation is shown for to_address on list page", %{ - addresses: addresses, - block: block, - session: session - } do - lincoln = addresses.lincoln - - contract_address = insert(:contract_address) - - from_lincoln = - :transaction - |> insert(from_address: lincoln, to_address: nil) - |> with_contract_creation(contract_address) - |> with_block(block) - - internal_transaction = - :internal_transaction_create - |> insert( - transaction: from_lincoln, - from_address: lincoln, - index: 1 - ) - |> with_contract_creation(contract_address) - - session - |> AddressPage.visit_page(addresses.lincoln) - |> assert_has(AddressPage.contract_creation(internal_transaction)) - end - test "only addresses not matching the page are links", %{ addresses: addresses, session: session, @@ -213,29 +184,7 @@ defmodule BlockScoutWeb.ViewingAddressesTest do {:ok, %{internal_transaction_lincoln_to_address: internal_transaction_lincoln_to_address}} end - test "can see internal transactions for an address", %{addresses: addresses, session: session} do - session - |> AddressPage.visit_page(addresses.lincoln) - |> AddressPage.click_internal_transactions() - |> assert_has(AddressPage.internal_transactions(count: 2)) - end - - test "can filter to only see internal transactions from an address", %{addresses: addresses, session: session} do - session - |> AddressPage.visit_page(addresses.lincoln) - |> AddressPage.click_internal_transactions() - |> AddressPage.apply_filter("From") - |> assert_has(AddressPage.internal_transactions(count: 1)) - end - - test "can filter to only see internal transactions to an address", %{addresses: addresses, session: session} do - session - |> AddressPage.visit_page(addresses.lincoln) - |> AddressPage.click_internal_transactions() - |> AddressPage.apply_filter("To") - |> assert_has(AddressPage.internal_transactions(count: 1)) - end - + @tag :skip test "only addresses not matching the page are links", %{ addresses: addresses, internal_transaction_lincoln_to_address: internal_transaction, @@ -248,6 +197,7 @@ defmodule BlockScoutWeb.ViewingAddressesTest do |> refute_has(AddressPage.internal_transaction_address_link(internal_transaction, :to)) end + @tag :skip test "viewing new internal transactions via live update", %{addresses: addresses, session: session} do transaction = :transaction @@ -276,37 +226,6 @@ defmodule BlockScoutWeb.ViewingAddressesTest do end end - test "contract creation is shown for to_address on list page", %{ - addresses: addresses, - block: block, - session: session - } do - lincoln = addresses.lincoln - contract_address = insert(:contract_address) - - from_lincoln = - :transaction - |> insert(from_address: lincoln, to_address: nil) - |> with_block(block) - |> with_contract_creation(contract_address) - - internal_transaction = - :internal_transaction_create - |> insert( - transaction: from_lincoln, - from_address: lincoln, - index: 1, - block_number: from_lincoln.block_number, - transaction_index: from_lincoln.index - ) - |> with_contract_creation(contract_address) - - session - |> AddressPage.visit_page(addresses.lincoln) - |> AddressPage.click_internal_transactions() - |> assert_has(AddressPage.contract_creation(internal_transaction)) - end - describe "viewing token transfers" do test "contributor can see all token transfers that he sent", %{ addresses: addresses, @@ -445,6 +364,7 @@ defmodule BlockScoutWeb.ViewingAddressesTest do end describe "viewing token transfers from a specific token" do + @tag :skip test "list token transfers related to the address", %{ addresses: addresses, block: block, diff --git a/apps/ethereum_jsonrpc/README.md b/apps/ethereum_jsonrpc/README.md index da62fd2447..5d9d469ea4 100644 --- a/apps/ethereum_jsonrpc/README.md +++ b/apps/ethereum_jsonrpc/README.md @@ -9,8 +9,8 @@ config: ```elixir config :ethereum_jsonrpc, - url: "https://sokol.poa.network", - trace_url: "https://sokol-trace.poa.network", + url: "http://localhost:8545", + trace_url: "http://localhost:8545", http: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] ``` @@ -44,8 +44,8 @@ mix test --exclude no_parity | Protocol | URL | |:----------|:-----------------------------------| -| HTTP | `https://sokol-trace.poa.network` | -| WebSocket | `wss://sokol-ws.poa.network/ws` | +| HTTP | `http://localhost:8545` | +| WebSocket | `ws://localhost:8546` | ### Geth diff --git a/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex index 49006a9ff6..bd6cbefc0d 100644 --- a/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex @@ -7,8 +7,8 @@ defmodule EthereumJSONRPC do Configuration for parity URLs can be provided with the following mix config: config :ethereum_jsonrpc, - url: "https://sokol.poa.network", - trace_url: "https://sokol-trace.poa.network", + url: "http://localhost:8545", + trace_url: "http://localhost:8545", http: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] diff --git a/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/case/parity/http_websocket.ex b/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/case/parity/http_websocket.ex index 70d7b4426f..73be4705eb 100644 --- a/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/case/parity/http_websocket.ex +++ b/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/case/parity/http_websocket.ex @@ -12,7 +12,7 @@ defmodule EthereumJSONRPC.Case.Parity.HTTPWebSocket do transport_options: [ http: EthereumJSONRPC.HTTP.HTTPoison, http_options: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]], - url: "https://sokol-trace.poa.network" + url: "http://18.207.247.30:8545" ], variant: EthereumJSONRPC.Parity ) diff --git a/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/web_socket/case/parity.ex b/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/web_socket/case/parity.ex index f63321283c..3fe72075bd 100644 --- a/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/web_socket/case/parity.ex +++ b/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/web_socket/case/parity.ex @@ -6,7 +6,7 @@ defmodule EthereumJSONRPC.WebSocket.Case.Parity do import ExUnit.Callbacks, only: [start_supervised!: 1] def setup do - url = "wss://sokol-ws.poa.network/ws" + url = "ws://18.207.247.30:8546" web_socket_module = EthereumJSONRPC.WebSocket.WebSocketClient web_socket = start_supervised!({web_socket_module, [url, []]}) diff --git a/apps/explorer/config/dev.exs b/apps/explorer/config/dev.exs index 2436efae81..8cc1f28a5f 100644 --- a/apps/explorer/config/dev.exs +++ b/apps/explorer/config/dev.exs @@ -22,7 +22,7 @@ import_config "dev.secret.exs" variant = if is_nil(System.get_env("ETHEREUM_JSONRPC_VARIANT")) do - "parity" + "ganache" else System.get_env("ETHEREUM_JSONRPC_VARIANT") |> String.split(".") diff --git a/apps/explorer/config/dev/parity.exs b/apps/explorer/config/dev/parity.exs index 64e9ee1a37..d503892fe0 100644 --- a/apps/explorer/config/dev/parity.exs +++ b/apps/explorer/config/dev/parity.exs @@ -5,11 +5,11 @@ config :explorer, transport: EthereumJSONRPC.HTTP, transport_options: [ http: EthereumJSONRPC.HTTP.HTTPoison, - url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "https://sokol.poa.network", + url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "http://localhost:8545", method_to_url: [ - eth_call: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "https://sokol-trace.poa.network", - eth_getBalance: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "https://sokol-trace.poa.network", - trace_replayTransaction: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "https://sokol-trace.poa.network" + eth_call: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "http://localhost:8545", + eth_getBalance: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "http://localhost:8545", + trace_replayTransaction: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "http://localhost:8545" ], http_options: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] ], @@ -19,7 +19,7 @@ config :explorer, transport: EthereumJSONRPC.WebSocket, transport_options: [ web_socket: EthereumJSONRPC.WebSocket.WebSocketClient, - url: System.get_env("ETHEREUM_JSONRPC_WS_URL") || "wss://sokol-ws.poa.network/ws" + url: System.get_env("ETHEREUM_JSONRPC_WS_URL") || "ws://localhost:8546" ], variant: EthereumJSONRPC.Parity ] diff --git a/apps/explorer/config/prod/parity.exs b/apps/explorer/config/prod/parity.exs index 64e9ee1a37..3e5c8ca64d 100644 --- a/apps/explorer/config/prod/parity.exs +++ b/apps/explorer/config/prod/parity.exs @@ -5,11 +5,11 @@ config :explorer, transport: EthereumJSONRPC.HTTP, transport_options: [ http: EthereumJSONRPC.HTTP.HTTPoison, - url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "https://sokol.poa.network", + url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL"), method_to_url: [ - eth_call: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "https://sokol-trace.poa.network", - eth_getBalance: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "https://sokol-trace.poa.network", - trace_replayTransaction: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "https://sokol-trace.poa.network" + eth_call: System.get_env("ETHEREUM_JSONRPC_TRACE_URL"), + eth_getBalance: System.get_env("ETHEREUM_JSONRPC_TRACE_URL"), + trace_replayTransaction: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") ], http_options: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] ], @@ -19,7 +19,7 @@ config :explorer, transport: EthereumJSONRPC.WebSocket, transport_options: [ web_socket: EthereumJSONRPC.WebSocket.WebSocketClient, - url: System.get_env("ETHEREUM_JSONRPC_WS_URL") || "wss://sokol-ws.poa.network/ws" + url: System.get_env("ETHEREUM_JSONRPC_WS_URL") ], variant: EthereumJSONRPC.Parity ] diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index a2a55dcbd5..efcd2af83d 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -899,12 +899,9 @@ defmodule Explorer.Chain do def list_top_addresses do query = from(a in Address, - left_join: t in Transaction, - on: a.hash == t.from_address_hash, where: a.fetched_coin_balance > ^0, - group_by: [a.hash, a.fetched_coin_balance], order_by: [desc: a.fetched_coin_balance, asc: a.hash], - select: {a, fragment("coalesce(1 + max(?), 0)", t.nonce)}, + select: {a, fragment("coalesce(1 + ?, 0)", a.nonce)}, limit: 250 ) diff --git a/apps/explorer/lib/explorer/chain/address.ex b/apps/explorer/lib/explorer/chain/address.ex index c5e2df3c9a..5777606d84 100644 --- a/apps/explorer/lib/explorer/chain/address.ex +++ b/apps/explorer/lib/explorer/chain/address.ex @@ -8,7 +8,7 @@ defmodule Explorer.Chain.Address do alias Ecto.Changeset alias Explorer.Chain.{Address, Block, Data, Hash, InternalTransaction, SmartContract, Token, Wei} - @optional_attrs ~w(contract_code fetched_coin_balance fetched_coin_balance_block_number)a + @optional_attrs ~w(contract_code fetched_coin_balance fetched_coin_balance_block_number nonce)a @required_attrs ~w(hash)a @allowed_attrs @optional_attrs ++ @required_attrs @@ -34,7 +34,8 @@ defmodule Explorer.Chain.Address do contract_code: Data.t() | nil, names: %Ecto.Association.NotLoaded{} | [Address.Name.t()], inserted_at: DateTime.t(), - updated_at: DateTime.t() + updated_at: DateTime.t(), + nonce: non_neg_integer() | nil } @primary_key {:hash, Hash.Address, autogenerate: false} @@ -42,6 +43,7 @@ defmodule Explorer.Chain.Address do field(:fetched_coin_balance, Wei) field(:fetched_coin_balance_block_number, :integer) field(:contract_code, Data) + field(:nonce, :integer) has_one(:smart_contract, SmartContract) has_one(:token, Token, foreign_key: :contract_address_hash) diff --git a/apps/explorer/lib/explorer/chain/import/addresses.ex b/apps/explorer/lib/explorer/chain/import/addresses.ex index ae6c92e887..fd0546ef3a 100644 --- a/apps/explorer/lib/explorer/chain/import/addresses.ex +++ b/apps/explorer/lib/explorer/chain/import/addresses.ex @@ -95,18 +95,10 @@ defmodule Explorer.Chain.Import.Addresses do # MAX on two columns fetched_coin_balance_block_number: fragment( - """ - CASE WHEN EXCLUDED.fetched_coin_balance_block_number IS NOT NULL AND - (? IS NULL OR - EXCLUDED.fetched_coin_balance_block_number >= ?) THEN - EXCLUDED.fetched_coin_balance_block_number - ELSE ? - END - """, - address.fetched_coin_balance_block_number, - address.fetched_coin_balance_block_number, + "GREATEST(EXCLUDED.fetched_coin_balance_block_number, ?)", address.fetched_coin_balance_block_number - ) + ), + nonce: fragment("GREATEST(EXCLUDED.nonce, ?)", address.nonce) ] ] ) diff --git a/apps/explorer/lib/explorer/chain/token_transfer.ex b/apps/explorer/lib/explorer/chain/token_transfer.ex index ccebaa2ee6..c50bc23c64 100644 --- a/apps/explorer/lib/explorer/chain/token_transfer.ex +++ b/apps/explorer/lib/explorer/chain/token_transfer.ex @@ -24,15 +24,17 @@ defmodule Explorer.Chain.TokenTransfer do use Ecto.Schema - import Ecto.{Changeset, Query} + import Ecto.Changeset + import Ecto.Query, only: [from: 2, dynamic: 2, limit: 2, where: 3] - alias Explorer.Chain.{Address, Block, Hash, Token, TokenTransfer, Transaction} + alias Explorer.Chain.{Address, Hash, Token, TokenTransfer, Transaction} alias Explorer.{PagingOptions, Repo} @default_paging_options %PagingOptions{page_size: 50} @typedoc """ * `:amount` - The token transferred amount + * `:block_number` - The block number that the transfer took place. * `:from_address` - The `t:Explorer.Chain.Address.t/0` that sent the tokens * `:from_address_hash` - Address hash foreign key * `:to_address` - The `t:Explorer.Chain.Address.t/0` that received the tokens @@ -46,6 +48,7 @@ defmodule Explorer.Chain.TokenTransfer do """ @type t :: %TokenTransfer{ amount: Decimal.t(), + block_number: non_neg_integer() | nil, from_address: %Ecto.Association.NotLoaded{} | Address.t(), from_address_hash: Hash.Address.t(), to_address: %Ecto.Association.NotLoaded{} | Address.t(), @@ -65,6 +68,7 @@ defmodule Explorer.Chain.TokenTransfer do @primary_key false schema "token_transfers" do field(:amount, :decimal) + field(:block_number, :integer) field(:log_index, :integer, primary_key: true) field(:token_id, :decimal) @@ -91,7 +95,7 @@ defmodule Explorer.Chain.TokenTransfer do timestamps() end - @required_attrs ~w(log_index from_address_hash to_address_hash token_contract_address_hash transaction_hash)a + @required_attrs ~w(block_number log_index from_address_hash to_address_hash token_contract_address_hash transaction_hash)a @optional_attrs ~w(amount token_id)a @doc false @@ -118,13 +122,9 @@ defmodule Explorer.Chain.TokenTransfer do query = from( tt in TokenTransfer, - join: t in Transaction, - on: tt.transaction_hash == t.hash, - join: b in Block, - on: t.block_hash == b.hash, where: tt.token_contract_address_hash == ^token_address_hash, preload: [{:transaction, :block}, :token, :from_address, :to_address], - order_by: [desc: b.timestamp] + order_by: [desc: tt.block_number, desc: tt.log_index] ) query @@ -135,19 +135,11 @@ defmodule Explorer.Chain.TokenTransfer do def page_token_transfer(query, %PagingOptions{key: nil}), do: query - def page_token_transfer(query, %PagingOptions{key: {token_id}}) do + def page_token_transfer(query, %PagingOptions{key: {block_number, log_index}}) do where( query, - [token_transfer], - token_transfer.token_id > ^token_id - ) - end - - def page_token_transfer(query, %PagingOptions{key: inserted_at}) do - where( - query, - [token_transfer], - token_transfer.inserted_at < ^inserted_at + [tt], + tt.block_number < ^block_number or (tt.block_number == ^block_number and tt.log_index < ^log_index) ) end diff --git a/apps/explorer/priv/repo/migrations/20181106152300_add_nonce_to_addresses.exs b/apps/explorer/priv/repo/migrations/20181106152300_add_nonce_to_addresses.exs new file mode 100644 index 0000000000..871c1daf57 --- /dev/null +++ b/apps/explorer/priv/repo/migrations/20181106152300_add_nonce_to_addresses.exs @@ -0,0 +1,26 @@ +defmodule Explorer.Repo.Migrations.AddNonceToAddresses do + @moduledoc """ + Use `priv/repo/migrations/scripts/20181126182700_migrate_address_nonce.sql` to migrate data. + + ```sh + mix ecto.migrate + psql -d $DATABASE -a -f priv/repo/migrations/scripts/20181126182700_migrate_address_nonce.sql + ``` + """ + + use Ecto.Migration + + def up do + # Add nonce + alter table(:addresses) do + add(:nonce, :integer) + end + end + + def down do + # Remove nonce + alter table(:addresses) do + remove(:nonce) + end + end +end diff --git a/apps/explorer/priv/repo/migrations/20181121170616_add_block_number_to_token_transfers.exs b/apps/explorer/priv/repo/migrations/20181121170616_add_block_number_to_token_transfers.exs new file mode 100644 index 0000000000..60c426e304 --- /dev/null +++ b/apps/explorer/priv/repo/migrations/20181121170616_add_block_number_to_token_transfers.exs @@ -0,0 +1,18 @@ +defmodule Explorer.Repo.Migrations.AddBlockNumberToTokenTransfers do + @moduledoc """ + Use `priv/repo/migrations/scripts/20181121170616_token_transfers_update_block_number_in_batches.sql` to migrate data. + + ```sh + mix ecto.migrate + psql -d $DATABASE -a -f priv/repo/migrations/scripts/20181121170616_token_transfers_update_block_number_in_batches.sql + ``` + """ + + use Ecto.Migration + + def change do + alter table(:token_transfers) do + add(:block_number, :integer) + end + end +end diff --git a/apps/explorer/priv/repo/migrations/20181126203826_add_index_to_addresses.exs b/apps/explorer/priv/repo/migrations/20181126203826_add_index_to_addresses.exs new file mode 100644 index 0000000000..3c1b16dfec --- /dev/null +++ b/apps/explorer/priv/repo/migrations/20181126203826_add_index_to_addresses.exs @@ -0,0 +1,13 @@ +defmodule Explorer.Repo.Migrations.AddIndexToAddresses do + use Ecto.Migration + + def up do + execute( + "CREATE INDEX addresses_fetched_coin_balance_hash_index ON addresses (fetched_coin_balance DESC, hash ASC) WHERE fetched_coin_balance > 0" + ) + end + + def down do + execute("DROP INDEX addresses_fetched_coin_balance_hash_index") + end +end diff --git a/apps/explorer/priv/repo/migrations/scripts/20181121170616_token_transfers_update_block_number_in_batches.sql b/apps/explorer/priv/repo/migrations/scripts/20181121170616_token_transfers_update_block_number_in_batches.sql new file mode 100644 index 0000000000..1fc30be9a9 --- /dev/null +++ b/apps/explorer/priv/repo/migrations/scripts/20181121170616_token_transfers_update_block_number_in_batches.sql @@ -0,0 +1,39 @@ +DO $$ +DECLARE + row_count integer; + batch_size integer := 100000; -- HOW MANY ITEMS WILL BE UPDATED AT TIME + affected integer; +BEGIN + RAISE NOTICE 'Counting items to be updated'; + + row_count := (SELECT COUNT(*) FROM token_transfers WHERE block_number IS NULL); + + RAISE NOTICE '% items', row_count; + + WHILE row_count > 0 LOOP + WITH cte AS ( + SELECT + t.hash, + t.block_number + FROM token_transfers AS tt + INNER JOIN transactions AS t ON t.hash = tt.transaction_hash + WHERE tt.block_number IS NULL + LIMIT batch_size + ) + UPDATE token_transfers + SET + block_number = cte.block_number + FROM cte + WHERE token_transfers.transaction_hash = cte.hash; + + GET DIAGNOSTICS affected = ROW_COUNT; + RAISE NOTICE '-> % token transfers updated!', affected; + + -- UPDATES THE COUNTER SO IT DOESN'T TURN INTO AN INFINITE LOOP + row_count := row_count - batch_size; + + RAISE NOTICE '-> % items missing to update', row_count; + + CHECKPOINT; -- COMMITS THE BATCH UPDATES + END LOOP; +END $$; diff --git a/apps/explorer/priv/repo/migrations/scripts/20181126182700_migrate_address_nonce.sql b/apps/explorer/priv/repo/migrations/scripts/20181126182700_migrate_address_nonce.sql new file mode 100644 index 0000000000..bae18c3e84 --- /dev/null +++ b/apps/explorer/priv/repo/migrations/scripts/20181126182700_migrate_address_nonce.sql @@ -0,0 +1,55 @@ +DO $$ + DECLARE + row_count integer := 1; + batch_size integer := 50000; -- HOW MANY ITEMS WILL BE UPDATED AT TIME + iterator integer := batch_size; + affected integer; + BEGIN + DROP TABLE IF EXISTS addresses_nonce_temp; + + -- CREATES TEMP TABLE TO STORE THE ADDRESS NONCE TO BE UPDATED + CREATE TEMP TABLE addresses_nonce_temp( + from_address_hash bytea, + nonce integer, + row_number integer + ); + + INSERT INTO addresses_nonce_temp + SELECT DISTINCT ON (from_address_hash) + from_address_hash, + nonce, + ROW_NUMBER () OVER () + FROM transactions + ORDER BY from_address_hash, nonce DESC; + + row_count := (SELECT count(*) FROM addresses_nonce_temp); + + RAISE NOTICE '% items to be updated', row_count; + + -- ITERATES THROUGH THE ITEMS UNTIL THE TEMP TABLE IS EMPTY + WHILE row_count > 0 LOOP + -- UPDATES THE ADDRESS NONCE AND RETURNS THE ADDRESS_HASH + WITH updated_addresses AS ( + UPDATE addresses SET nonce = addresses_nonce_temp.nonce + FROM addresses_nonce_temp + WHERE addresses_nonce_temp.from_address_hash = addresses.hash + AND addresses_nonce_temp.row_number <= iterator + RETURNING addresses_nonce_temp.from_address_hash + ) + DELETE FROM addresses_nonce_temp + WHERE (from_address_hash) IN (select from_address_hash from updated_addresses); + + GET DIAGNOSTICS affected = ROW_COUNT; + RAISE NOTICE '-> % addresses updated!', affected; + + -- COMMITS THE BATCH UPDATES + CHECKPOINT; + + -- UPDATES THE COUNTER SO IT DOESN'T TURN INTO A INFINITE LOOP + row_count := (SELECT count(*) FROM addresses_nonce_temp); + iterator := iterator + batch_size; + + RAISE NOTICE '-> % counter', row_count; + RAISE NOTICE '-> % next batch', iterator; + END LOOP; + END $$; diff --git a/apps/explorer/test/explorer/chain/import_test.exs b/apps/explorer/test/explorer/chain/import_test.exs index d006893cb7..9b79362721 100644 --- a/apps/explorer/test/explorer/chain/import_test.exs +++ b/apps/explorer/test/explorer/chain/import_test.exs @@ -1517,7 +1517,9 @@ defmodule Explorer.Chain.ImportTest do }, token_transfers: %{ params: [ - params_for(:token_transfer, + params_for( + :token_transfer, + block_number: 35, from_address_hash: from_address_hash, to_address_hash: to_address_hash, token_contract_address_hash: token_contract_address_hash, diff --git a/apps/explorer/test/explorer/chain/token_transfer_test.exs b/apps/explorer/test/explorer/chain/token_transfer_test.exs index a48326cc8c..0ba6b11b66 100644 --- a/apps/explorer/test/explorer/chain/token_transfer_test.exs +++ b/apps/explorer/test/explorer/chain/token_transfer_test.exs @@ -8,7 +8,7 @@ defmodule Explorer.Chain.TokenTransferTest do doctest Explorer.Chain.TokenTransfer - describe "fetch_token_transfers/2" do + describe "fetch_token_transfers_from_token_hash/2" do test "returns token transfers for the given address" do token_contract_address = insert(:contract_address) @@ -87,6 +87,7 @@ defmodule Explorer.Chain.TokenTransferTest do second_page = insert( :token_transfer, + block_number: 999, to_address: build(:address), transaction: transaction, token_contract_address: token_contract_address, @@ -96,23 +97,53 @@ defmodule Explorer.Chain.TokenTransferTest do first_page = insert( :token_transfer, + block_number: 1000, to_address: build(:address), transaction: transaction, token_contract_address: token_contract_address, token: token ) - paging_options = %PagingOptions{key: first_page.inserted_at, page_size: 1} + paging_options = %PagingOptions{key: {first_page.block_number, first_page.log_index}, page_size: 1} token_transfers_primary_keys_paginated = - TokenTransfer.fetch_token_transfers_from_token_hash( - token_contract_address.hash, - paging_options: paging_options - ) + token_contract_address.hash + |> TokenTransfer.fetch_token_transfers_from_token_hash(paging_options: paging_options) |> Enum.map(&{&1.transaction_hash, &1.log_index}) assert token_transfers_primary_keys_paginated == [{second_page.transaction_hash, second_page.log_index}] end + + test "paginates considering the log_index when there are repeated block numbers" do + token_contract_address = insert(:contract_address) + + transaction = + :transaction + |> insert() + |> with_block() + + token = insert(:token) + + token_transfer = + insert( + :token_transfer, + block_number: 1000, + log_index: 0, + to_address: build(:address), + transaction: transaction, + token_contract_address: token_contract_address, + token: token + ) + + paging_options = %PagingOptions{key: {token_transfer.block_number, token_transfer.log_index + 1}, page_size: 1} + + token_transfers_primary_keys_paginated = + token_contract_address.hash + |> TokenTransfer.fetch_token_transfers_from_token_hash(paging_options: paging_options) + |> Enum.map(&{&1.transaction_hash, &1.log_index}) + + assert token_transfers_primary_keys_paginated == [{token_transfer.transaction_hash, token_transfer.log_index}] + end end describe "count_token_transfers/0" do diff --git a/apps/explorer/test/explorer/chain_test.exs b/apps/explorer/test/explorer/chain_test.exs index 13c0f44906..7c4dbdf8e0 100644 --- a/apps/explorer/test/explorer/chain_test.exs +++ b/apps/explorer/test/explorer/chain_test.exs @@ -3112,6 +3112,7 @@ defmodule Explorer.ChainTest do first_page = insert( :token_transfer, + block_number: 1000, to_address: build(:address), transaction: transaction, token_contract_address: token_contract_address, @@ -3122,6 +3123,7 @@ defmodule Explorer.ChainTest do second_page = insert( :token_transfer, + block_number: 999, to_address: build(:address), transaction: transaction, token_contract_address: token_contract_address, @@ -3129,13 +3131,11 @@ defmodule Explorer.ChainTest do token_id: 29 ) - paging_options = %PagingOptions{key: {first_page.token_id}, page_size: 1} + paging_options = %PagingOptions{key: {first_page.block_number, first_page.log_index}, page_size: 1} unique_tokens_ids_paginated = - Chain.address_to_unique_tokens( - token_contract_address.hash, - paging_options: paging_options - ) + token_contract_address.hash + |> Chain.address_to_unique_tokens(paging_options: paging_options) |> Enum.map(& &1.token_id) assert unique_tokens_ids_paginated == [second_page.token_id] diff --git a/apps/explorer/test/support/factory.ex b/apps/explorer/test/support/factory.ex index edcf896cea..e1aac30fd8 100644 --- a/apps/explorer/test/support/factory.ex +++ b/apps/explorer/test/support/factory.ex @@ -387,6 +387,7 @@ defmodule Explorer.Factory do %TokenTransfer{ amount: Decimal.new(1), + block_number: block_number(), from_address: from_address, to_address: to_address, token_contract_address: token_address, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/block_importer_download_block_1_downloads_the_block.json b/apps/explorer/test/support/fixture/vcr_cassettes/block_importer_download_block_1_downloads_the_block.json index ef08dd0c98..b62aa3277f 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/block_importer_download_block_1_downloads_the_block.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/block_importer_download_block_1_downloads_the_block.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/block_importer_import_1_duplicate_block.json b/apps/explorer/test/support/fixture/vcr_cassettes/block_importer_import_1_duplicate_block.json index ed01d15e03..169a8160a8 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/block_importer_import_1_duplicate_block.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/block_importer_import_1_duplicate_block.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/block_importer_import_1_pending.json b/apps/explorer/test/support/fixture/vcr_cassettes/block_importer_import_1_pending.json index a45df1eab5..375279645a 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/block_importer_import_1_pending.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/block_importer_import_1_pending.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/block_importer_import_1_saves_the_block.json b/apps/explorer/test/support/fixture/vcr_cassettes/block_importer_import_1_saves_the_block.json index 9ae55768bf..e62eae9925 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/block_importer_import_1_saves_the_block.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/block_importer_import_1_saves_the_block.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/ethereumex_extensions_trace_transaction_1.json b/apps/explorer/test/support/fixture/vcr_cassettes/ethereumex_extensions_trace_transaction_1.json index 75123fd84a..d31ed57dd9 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/ethereumex_extensions_trace_transaction_1.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/ethereumex_extensions_trace_transaction_1.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_duplicate.json b/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_duplicate.json index d7cd1acd56..e66fd00420 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_duplicate.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_duplicate.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_earliest.json b/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_earliest.json index fbe9128192..b3057bb033 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_earliest.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_earliest.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_integer.json b/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_integer.json index c019c8b19b..6eff0a1e04 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_integer.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_integer.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_latest.json b/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_latest.json index 1cf796f617..b8348fb16f 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_latest.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_latest.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_string.json b/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_string.json index 8d8d1e3c3f..5be3ed31ba 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_string.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/import_block_perform_1_string.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/import_receipt_perform_1.json b/apps/explorer/test/support/fixture/vcr_cassettes/import_receipt_perform_1.json index 8a2b337a73..f23d3abbca 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/import_receipt_perform_1.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/import_receipt_perform_1.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/internal_transaction_importer_import_1.json b/apps/explorer/test/support/fixture/vcr_cassettes/internal_transaction_importer_import_1.json index 691989cee1..65051c71ef 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/internal_transaction_importer_import_1.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/internal_transaction_importer_import_1.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/internal_transaction_importer_import_1_with_contract_creation.json b/apps/explorer/test/support/fixture/vcr_cassettes/internal_transaction_importer_import_1_with_contract_creation.json index 2d7a1970a0..28e8e4f211 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/internal_transaction_importer_import_1_with_contract_creation.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/internal_transaction_importer_import_1_with_contract_creation.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_binds_internal_transactions.json b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_binds_internal_transactions.json index 48fff5d094..86dfd87e03 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_binds_internal_transactions.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_binds_internal_transactions.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_creates_a_from_address.json b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_creates_a_from_address.json index e756422df8..088f9d6c05 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_creates_a_from_address.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_creates_a_from_address.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_creates_a_to_address.json b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_creates_a_to_address.json index b2095fd971..30f110f066 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_creates_a_to_address.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_creates_a_to_address.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_creates_a_to_address_from_creates.json b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_creates_a_to_address_from_creates.json index 3f2d41867c..a36208621a 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_creates_a_to_address_from_creates.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_creates_a_to_address_from_creates.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_download_transaction.json b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_download_transaction.json index 2dec11562e..dbb71df424 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_download_transaction.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_download_transaction.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_download_transaction_with_a_bad_hash.json b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_download_transaction_with_a_bad_hash.json index 20e80fd6fd..73f2eb7cfc 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_download_transaction_with_a_bad_hash.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_download_transaction_with_a_bad_hash.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_1_failed.json b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_1_failed.json index a8fa4d3f51..333c2b9bef 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_1_failed.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_1_failed.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_1_out_of_gas.json b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_1_out_of_gas.json index b3e5a1fc00..f9bd56b2d9 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_1_out_of_gas.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_1_out_of_gas.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_1_pending.json b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_1_pending.json index 98ea77155c..f1ea9378a8 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_1_pending.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_1_pending.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_1_receipt.json b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_1_receipt.json index 29da0b90b4..cab876ebfa 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_1_receipt.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_1_receipt.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_saves_the_transaction.json b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_saves_the_transaction.json index d1858cbe7f..829b214442 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_saves_the_transaction.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_import_saves_the_transaction.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_saves_the_association.json b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_saves_the_association.json index 3c118d1f5f..1c03f4aaae 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_saves_the_association.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_saves_the_association.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_txn_without_block.json b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_txn_without_block.json index 0a3e395453..55803dd737 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_txn_without_block.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_txn_without_block.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_updates_the_association.json b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_updates_the_association.json index 1337f8fb6c..67d9d0c9f7 100644 --- a/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_updates_the_association.json +++ b/apps/explorer/test/support/fixture/vcr_cassettes/transaction_importer_updates_the_association.json @@ -8,7 +8,7 @@ "method": "post", "options": [], "request_body": "", - "url": "https://sokol-trace.poa.network" + "url": "http://18.207.247.30:8545" }, "response": { "binary": false, diff --git a/apps/indexer/README.md b/apps/indexer/README.md index 154914d9e5..e7e7d83e6d 100644 --- a/apps/indexer/README.md +++ b/apps/indexer/README.md @@ -53,8 +53,8 @@ mix test --exclude no_parity | Protocol | URL | |:----------|:-----------------------------------| -| HTTP | `https://sokol-trace.poa.network` | -| WebSocket | `wss://sokol-ws.poa.network/ws` | +| HTTP | `http://localhost:8545` | +| WebSocket | `ws://localhost:8546` | ### Geth diff --git a/apps/indexer/config/dev.exs b/apps/indexer/config/dev.exs index 2f445c38dc..337e2f9b97 100644 --- a/apps/indexer/config/dev.exs +++ b/apps/indexer/config/dev.exs @@ -11,7 +11,7 @@ config :logger, :indexer_token_balances, variant = if is_nil(System.get_env("ETHEREUM_JSONRPC_VARIANT")) do - "parity" + "ganache" else System.get_env("ETHEREUM_JSONRPC_VARIANT") |> String.split(".") diff --git a/apps/indexer/config/dev/parity.exs b/apps/indexer/config/dev/parity.exs index 8bd5e87c07..e903be4141 100644 --- a/apps/indexer/config/dev/parity.exs +++ b/apps/indexer/config/dev/parity.exs @@ -6,11 +6,11 @@ config :indexer, transport: EthereumJSONRPC.HTTP, transport_options: [ http: EthereumJSONRPC.HTTP.HTTPoison, - url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "https://sokol.poa.network", + url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "http://localhost:8545", method_to_url: [ - eth_getBalance: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "https://sokol-trace.poa.network", - trace_block: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "https://sokol-trace.poa.network", - trace_replayTransaction: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "https://sokol-trace.poa.network" + eth_getBalance: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "http://localhost:8545", + trace_block: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "http://localhost:8545", + trace_replayTransaction: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "http://localhost:8545" ], http_options: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] ], @@ -20,6 +20,6 @@ config :indexer, transport: EthereumJSONRPC.WebSocket, transport_options: [ web_socket: EthereumJSONRPC.WebSocket.WebSocketClient, - url: System.get_env("ETHEREUM_JSONRPC_WS_URL") || "wss://sokol-ws.poa.network/ws" + url: System.get_env("ETHEREUM_JSONRPC_WS_URL") || "ws://localhost:8546" ] ] diff --git a/apps/indexer/config/prod/parity.exs b/apps/indexer/config/prod/parity.exs index 8bd5e87c07..463dc3f079 100644 --- a/apps/indexer/config/prod/parity.exs +++ b/apps/indexer/config/prod/parity.exs @@ -6,11 +6,11 @@ config :indexer, transport: EthereumJSONRPC.HTTP, transport_options: [ http: EthereumJSONRPC.HTTP.HTTPoison, - url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "https://sokol.poa.network", + url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL"), method_to_url: [ - eth_getBalance: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "https://sokol-trace.poa.network", - trace_block: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "https://sokol-trace.poa.network", - trace_replayTransaction: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "https://sokol-trace.poa.network" + eth_getBalance: System.get_env("ETHEREUM_JSONRPC_TRACE_URL"), + trace_block: System.get_env("ETHEREUM_JSONRPC_TRACE_URL"), + trace_replayTransaction: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") ], http_options: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] ], @@ -20,6 +20,6 @@ config :indexer, transport: EthereumJSONRPC.WebSocket, transport_options: [ web_socket: EthereumJSONRPC.WebSocket.WebSocketClient, - url: System.get_env("ETHEREUM_JSONRPC_WS_URL") || "wss://sokol-ws.poa.network/ws" + url: System.get_env("ETHEREUM_JSONRPC_WS_URL") ] ] diff --git a/apps/indexer/lib/indexer/address_extraction.ex b/apps/indexer/lib/indexer/address_extraction.ex index 995465589a..9dbfb43cd6 100644 --- a/apps/indexer/lib/indexer/address_extraction.ex +++ b/apps/indexer/lib/indexer/address_extraction.ex @@ -84,7 +84,8 @@ defmodule Indexer.AddressExtraction do ], [ %{from: :block_number, to: :fetched_coin_balance_block_number}, - %{from: :from_address_hash, to: :hash} + %{from: :from_address_hash, to: :hash}, + %{from: :nonce, to: :nonce} ], [ %{from: :block_number, to: :fetched_coin_balance_block_number}, @@ -136,6 +137,7 @@ defmodule Indexer.AddressExtraction do required(:hash) => String.t(), required(:fetched_coin_balance_block_number) => non_neg_integer(), optional(:fetched_coin_balance) => non_neg_integer(), + optional(:nonce) => non_neg_integer(), optional(:contract_code) => String.t() } @@ -209,11 +211,13 @@ defmodule Indexer.AddressExtraction do ...> %{ ...> block_number: 1, ...> from_address_hash: "0x0000000000000000000000000000000000000001", - ...> to_address_hash: "0x0000000000000000000000000000000000000002" + ...> to_address_hash: "0x0000000000000000000000000000000000000002", + ...> nonce: 3 ...> }, ...> %{ ...> block_number: 2, - ...> from_address_hash: "0x0000000000000000000000000000000000000003" + ...> from_address_hash: "0x0000000000000000000000000000000000000003", + ...> nonce: 4 ...> } ...> ] ...> } @@ -221,7 +225,8 @@ defmodule Indexer.AddressExtraction do [ %{ fetched_coin_balance_block_number: 1, - hash: "0x0000000000000000000000000000000000000001" + hash: "0x0000000000000000000000000000000000000001", + nonce: 3 }, %{ fetched_coin_balance_block_number: 1, @@ -229,7 +234,8 @@ defmodule Indexer.AddressExtraction do }, %{ fetched_coin_balance_block_number: 2, - hash: "0x0000000000000000000000000000000000000003" + hash: "0x0000000000000000000000000000000000000003", + nonce: 4 } ] @@ -279,11 +285,13 @@ defmodule Indexer.AddressExtraction do ...> transactions: [ ...> %{ ...> block_number: 3, - ...> to_address_hash: "0x0000000000000000000000000000000000000001" + ...> to_address_hash: "0x0000000000000000000000000000000000000001", + ...> nonce: 5 ...> }, ...> %{ ...> block_number: 2, - ...> from_address_hash: "0x0000000000000000000000000000000000000001" + ...> from_address_hash: "0x0000000000000000000000000000000000000001", + ...> nonce: 4 ...> } ...> ], ...> logs: [ @@ -297,7 +305,8 @@ defmodule Indexer.AddressExtraction do [ %{ fetched_coin_balance_block_number: 7, - hash: "0x0000000000000000000000000000000000000001" + hash: "0x0000000000000000000000000000000000000001", + nonce: 4 } ] @@ -316,11 +325,13 @@ defmodule Indexer.AddressExtraction do ...> transactions: [ ...> %{ ...> block_number: 2, - ...> from_address_hash: "0x0000000000000000000000000000000000000001" + ...> from_address_hash: "0x0000000000000000000000000000000000000001", + ...> nonce: 4 ...> }, ...> %{ ...> block_number: 3, - ...> to_address_hash: "0x0000000000000000000000000000000000000001" + ...> to_address_hash: "0x0000000000000000000000000000000000000001", + ...> nonce: 5 ...> } ...> ] ...> } @@ -329,7 +340,8 @@ defmodule Indexer.AddressExtraction do %{ contract_code: "0x", fetched_coin_balance_block_number: 3, - hash: "0x0000000000000000000000000000000000000001" + hash: "0x0000000000000000000000000000000000000001", + nonce: 4 } ] @@ -366,6 +378,7 @@ defmodule Indexer.AddressExtraction do %{ required(:block_number) => non_neg_integer(), required(:from_address_hash) => String.t(), + required(:nonce) => non_neg_integer(), optional(:to_address_hash) => String.t(), optional(:created_contract_address_hash) => String.t() } @@ -445,38 +458,42 @@ defmodule Indexer.AddressExtraction do # Ensure that when `:addresses` or `:address_coin_balances` are present, their :fetched_coin_balance will win defp merge_addresses(%{hash: hash} = first, %{hash: hash} = second) do - case {first[:fetched_coin_balance], second[:fetched_coin_balance]} do - {nil, nil} -> - first - |> Map.merge(second) - |> Map.put( - :fetched_coin_balance_block_number, - max_nil_last( - Map.get(first, :fetched_coin_balance_block_number), - Map.get(second, :fetched_coin_balance_block_number) + merged_addresses = + case {first[:fetched_coin_balance], second[:fetched_coin_balance]} do + {nil, nil} -> + first + |> Map.merge(second) + |> Map.put( + :fetched_coin_balance_block_number, + max_nil_last( + Map.get(first, :fetched_coin_balance_block_number), + Map.get(second, :fetched_coin_balance_block_number) + ) ) - ) - - {nil, _} -> - # merge in `second` so its balance and block_number wins - Map.merge(first, second) - - {_, nil} -> - # merge in `first` so its balance and block_number wins - Map.merge(second, first) - - {_, _} -> - if greater_than_nil_last( - Map.get(first, :fetched_coin_balance_block_number), - Map.get(second, :fetched_coin_balance_block_number) - ) do - # merge in `first` so its block number wins - Map.merge(second, first) - else - # merge in `second` so its block number wins + + {nil, _} -> + # merge in `second` so its balance and block_number wins Map.merge(first, second) - end - end + + {_, nil} -> + # merge in `first` so its balance and block_number wins + Map.merge(second, first) + + {_, _} -> + if greater_than_nil_last( + Map.get(first, :fetched_coin_balance_block_number), + Map.get(second, :fetched_coin_balance_block_number) + ) do + # merge in `first` so its block number wins + Map.merge(second, first) + else + # merge in `second` so its block number wins + Map.merge(first, second) + end + end + + merged_addresses + |> Map.put(:nonce, max_nil_last(first[:nonce], second[:nonce])) end # `nil > 5 == true`, but we want numbers instead diff --git a/apps/indexer/test/indexer/address_extraction_test.exs b/apps/indexer/test/indexer/address_extraction_test.exs index 4b03173c99..8b5a8a4dfc 100644 --- a/apps/indexer/test/indexer/address_extraction_test.exs +++ b/apps/indexer/test/indexer/address_extraction_test.exs @@ -76,7 +76,8 @@ defmodule Indexer.AddressExtractionTest do %{ fetched_coin_balance_block_number: 2, contract_code: "0x1", - hash: "0x0000000000000000000000000000000000000001" + hash: "0x0000000000000000000000000000000000000001", + nonce: nil } ] end @@ -95,7 +96,8 @@ defmodule Indexer.AddressExtractionTest do transaction = %{ block_number: 3, from_address_hash: gen_hash(), - to_address_hash: gen_hash() + to_address_hash: gen_hash(), + nonce: 7 } log = %{address_hash: gen_hash(), block_number: 4} @@ -136,7 +138,11 @@ defmodule Indexer.AddressExtractionTest do contract_code: internal_transaction.created_contract_code, fetched_coin_balance_block_number: internal_transaction.block_number }, - %{hash: transaction.from_address_hash, fetched_coin_balance_block_number: transaction.block_number}, + %{ + hash: transaction.from_address_hash, + fetched_coin_balance_block_number: transaction.block_number, + nonce: 7 + }, %{hash: transaction.to_address_hash, fetched_coin_balance_block_number: transaction.block_number}, %{hash: log.address_hash, fetched_coin_balance_block_number: log.block_number}, %{ @@ -176,7 +182,7 @@ defmodule Indexer.AddressExtractionTest do blockchain_data = %{ blocks: [%{miner_hash: hash, number: 34}], - transactions: [%{block_number: 34, from_address_hash: hash}], + transactions: [%{block_number: 34, from_address_hash: hash, nonce: 12}], internal_transactions: [ %{ block_number: 34, @@ -188,7 +194,7 @@ defmodule Indexer.AddressExtractionTest do assert AddressExtraction.extract_addresses(blockchain_data) == [ - %{hash: hash, fetched_coin_balance_block_number: 34, contract_code: "code"} + %{hash: hash, fetched_coin_balance_block_number: 34, contract_code: "code", nonce: 12} ] end diff --git a/apps/indexer/test/indexer/block/realtime/fetcher_test.exs b/apps/indexer/test/indexer/block/realtime/fetcher_test.exs index 2a8457bc76..48ff3b9cc7 100644 --- a/apps/indexer/test/indexer/block/realtime/fetcher_test.exs +++ b/apps/indexer/test/indexer/block/realtime/fetcher_test.exs @@ -20,12 +20,12 @@ defmodule Indexer.Block.Realtime.FetcherTest do setup %{json_rpc_named_arguments: json_rpc_named_arguments} do core_json_rpc_named_arguments = json_rpc_named_arguments - |> put_in([:transport_options, :url], "https://core.poa.network") + |> put_in([:transport_options, :url], "http://54.144.107.14:8545") |> put_in( [:transport_options, :method_to_url], - eth_getBalance: "https://core-trace.poa.network", - trace_replayTransaction: "https://core-trace.poa.network", - trace_block: "https://core-trace.poa.network" + eth_getBalance: "http://54.144.107.14:8545", + trace_replayTransaction: "http://54.144.107.14:8545", + trace_block: "http://54.144.107.14:8545" ) block_fetcher = %Indexer.Block.Fetcher{ diff --git a/docker/README.md b/docker/README.md index 17e142c27f..f8ab76051b 100644 --- a/docker/README.md +++ b/docker/README.md @@ -54,7 +54,7 @@ Available options are: | `ETHEREUM_JSONRPC_VARIANT` | Variant of your JSON RPC service: `parity`, `geth` or `ganache` | `parity` | | `ETHEREUM_JSONRPC_HTTP_URL` | HTTP JSON RPC URL Only for `geth` or `ganache` variant | Different per JSONRPC variant | | `ETHEREUM_JSONRPC_WS_URL` | WS JSON RPC url | Different per JSONRPC variant | -| `ETHEREUM_JSONRPC_TRACE_URL` | Trace URL **Only for `parity` variant** | `https://sokol-trace.poa.network` | +| `ETHEREUM_JSONRPC_TRACE_URL` | Trace URL **Only for `parity` variant** | `http://localhost:8545` | | `COIN` | Default Coin | `POA` | | `LOGO` | Coin logo | Empty | | `NETWORK` | Network | Empty | @@ -65,13 +65,13 @@ Available options are: `ETHEREUM_JSONRPC_HTTP_URL` default values: - * For `parity` - `https://sokol.poa.network` + * For `parity` - `http://localhost:8545` * For `geth` - `https://mainnet.infura.io/8lTvJTKmHPCHazkneJsY` * For `ganache` - `http://localhost:7545` `ETHEREUM_JSONRPC_WS_URL` default values: - * For `parity` - `wss://sokol-ws.poa.network/ws` + * For `parity` - `ws://localhost:8546` * For `geth` - `wss://mainnet.infura.io/8lTvJTKmHPCHazkneJsY/ws` * For `ganache` - `ws://localhost:7545`