diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index d33998115f..63ed708faf 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -1734,7 +1734,7 @@ defmodule Explorer.Chain do :ok """ @spec subscribe_to_events(chain_event()) :: :ok - def subscribe_to_events(event_type) when event_type in ~w(blocks logs)a do + def subscribe_to_events(event_type) when event_type in ~w(blocks logs transactions)a do Registry.register(Registry.ChainEvents, event_type, []) :ok end @@ -1893,7 +1893,7 @@ defmodule Explorer.Chain do end defp broadcast_events(data) do - for {event_type, event_data} <- data, event_type in ~w(blocks logs)a do + for {event_type, event_data} <- data, event_type in ~w(blocks logs transactions)a do broadcast_event_data(event_type, event_data) end end diff --git a/apps/explorer_web/lib/explorer_web/event_handler.ex b/apps/explorer_web/lib/explorer_web/event_handler.ex index c77473d49b..25284e2fb2 100644 --- a/apps/explorer_web/lib/explorer_web/event_handler.ex +++ b/apps/explorer_web/lib/explorer_web/event_handler.ex @@ -13,15 +13,12 @@ defmodule ExplorerWeb.EventHandler do def init([]) do Chain.subscribe_to_events(:blocks) + Chain.subscribe_to_events(:transactions) {:ok, []} end - def handle_info({:chain_event, :blocks, blocks}, state) do - Notifier.block_confirmations(Enum.max_by(blocks, & &1.number).number) - {:noreply, state} - end - - def handle_info(_event, state) do + def handle_info(event, state) do + Notifier.handle_event(event) {:noreply, state} end end diff --git a/apps/explorer_web/lib/explorer_web/notifier.ex b/apps/explorer_web/lib/explorer_web/notifier.ex index a2a5a6a63c..3ef33208fe 100644 --- a/apps/explorer_web/lib/explorer_web/notifier.ex +++ b/apps/explorer_web/lib/explorer_web/notifier.ex @@ -1,7 +1,39 @@ defmodule ExplorerWeb.Notifier do + alias Explorer.Chain alias ExplorerWeb.Endpoint - def block_confirmations(max_numbered_block) when is_integer(max_numbered_block) do + def handle_event({:chain_event, :blocks, []}), do: IO.inspect "EMPTY BLOCKS" + + def handle_event({:chain_event, :blocks, blocks}) do + max_numbered_block = Enum.max_by(blocks, & &1.number).number Endpoint.broadcast("transactions:confirmations", "update", %{block_number: max_numbered_block}) end + + def handle_event({:chain_event, :transactions, transactions}) do + transactions + |> Enum.each(&broadcast_transaction/1) + end + + def handle_event(event), do: IO.inspect({:error, event}) + + defp broadcast_transaction(transaction_hash) do + {:ok, transaction} = Chain.hash_to_transaction( + transaction_hash, + necessity_by_association: %{ + block: :required, + from_address: :optional, + to_address: :optional + } + ) + ExplorerWeb.Endpoint.broadcast("addresses:#{transaction.from_address_hash}", "transaction", %{ + address: transaction.from_address, + transaction: transaction + }) + if (transaction.from_address && transaction.to_address != transaction.from_address) do + ExplorerWeb.Endpoint.broadcast("addresses:#{transaction.to_address_hash}", "transaction", %{ + address: transaction.to_address, + transaction: transaction + }) + end + end end diff --git a/apps/explorer_web/test/explorer_web/features/viewing_addresses_test.exs b/apps/explorer_web/test/explorer_web/features/viewing_addresses_test.exs index 827324ca25..e0d96e4f25 100644 --- a/apps/explorer_web/test/explorer_web/features/viewing_addresses_test.exs +++ b/apps/explorer_web/test/explorer_web/features/viewing_addresses_test.exs @@ -4,7 +4,7 @@ defmodule ExplorerWeb.ViewingAddressesTest do alias Explorer.Chain alias Explorer.Chain.{Address, Wei} alias Explorer.ExchangeRates.Token - alias ExplorerWeb.{AddressPage, HomePage} + alias ExplorerWeb.{AddressPage, HomePage, Notifier} setup do block = insert(:block) @@ -234,21 +234,17 @@ defmodule ExplorerWeb.ViewingAddressesTest do end test "viewing new transactions via live update", %{addresses: addresses, session: session} do - session = - session - |> AddressPage.visit_page(addresses.lincoln) - |> assert_has(AddressPage.balance()) - transaction = :transaction |> insert(from_address: addresses.lincoln) |> with_block() - |> Repo.preload([:block, :from_address, :to_address]) - ExplorerWeb.Endpoint.broadcast!("addresses:#{addresses.lincoln.hash}", "transaction", %{ - address: addresses.lincoln, - transaction: transaction - }) + session = + session + |> AddressPage.visit_page(addresses.lincoln) + |> assert_has(AddressPage.balance()) + + Notifier.handle_event({:chain_event, :transactions, [transaction.hash]}) assert_has(session, AddressPage.transaction(transaction)) end diff --git a/apps/explorer_web/test/explorer_web/features/viewing_transactions_test.exs b/apps/explorer_web/test/explorer_web/features/viewing_transactions_test.exs index 29d466cf43..e9e83d73fd 100644 --- a/apps/explorer_web/test/explorer_web/features/viewing_transactions_test.exs +++ b/apps/explorer_web/test/explorer_web/features/viewing_transactions_test.exs @@ -3,9 +3,8 @@ defmodule ExplorerWeb.ViewingTransactionsTest do use ExplorerWeb.FeatureCase, async: true - alias Explorer.Chain alias Explorer.Chain.Wei - alias ExplorerWeb.{AddressPage, HomePage, TransactionListPage, TransactionLogsPage, TransactionPage} + alias ExplorerWeb.{AddressPage, HomePage, Notifier,TransactionListPage, TransactionLogsPage, TransactionPage} setup do block = @@ -123,91 +122,6 @@ defmodule ExplorerWeb.ViewingTransactionsTest do end describe "viewing a transaction page" do - @import_data [ - blocks: [ - params: [ - %{ - difficulty: 340_282_366_920_938_463_463_374_607_431_768_211_454, - gas_limit: 6_946_336, - gas_used: 50450, - hash: "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd", - miner_hash: "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", - nonce: 0, - number: 565, - parent_hash: "0xc37bbad7057945d1bf128c1ff009fb1ad632110bf6a000aac025a80f7766b66e", - size: 719, - timestamp: Timex.parse!("2017-12-15T21:06:30.000000Z", "{ISO:Extended:Z}"), - total_difficulty: 12_590_447_576_074_723_148_144_860_474_975_121_280_509 - } - ] - ], - internal_transactions: [ - params: [ - %{ - call_type: "call", - from_address_hash: "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", - gas: 4_677_320, - gas_used: 27770, - index: 0, - output: "0x", - to_address_hash: "0x8bf38d4764929064f2d4d3a56520a76ab3df415b", - trace_address: [], - transaction_hash: "0x53bd884872de3e488692881baeec262e7b95234d3965248c39fe992fffd433e5", - type: "call", - value: 0 - } - ] - ], - logs: [ - params: [ - %{ - address_hash: "0x8bf38d4764929064f2d4d3a56520a76ab3df415b", - data: "0x000000000000000000000000862d67cb0773ee3f8ce7ea89b328ffea861ab3ef", - first_topic: "0x600bcf04a13e752d1e3670a5a9f1c21177ca2a93c6f5391d4f1298d098097c22", - fourth_topic: nil, - index: 0, - second_topic: nil, - third_topic: nil, - transaction_hash: "0x53bd884872de3e488692881baeec262e7b95234d3965248c39fe992fffd433e5", - type: "mined" - } - ] - ], - transactions: [ - on_conflict: :replace_all, - params: [ - %{ - block_hash: "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd", - block_number: 37, - cumulative_gas_used: 50450, - from_address_hash: "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", - gas: 4_700_000, - gas_price: 100_000_000_000, - gas_used: 50450, - hash: "0x53bd884872de3e488692881baeec262e7b95234d3965248c39fe992fffd433e5", - index: 0, - input: "0x10855269000000000000000000000000862d67cb0773ee3f8ce7ea89b328ffea861ab3ef", - nonce: 4, - public_key: - "0xe5d196ad4ceada719d9e592f7166d0c75700f6eab2e3c3de34ba751ea786527cb3f6eb96ad9fdfdb9989ff572df50f1c42ef800af9c5207a38b929aff969b5c9", - r: 0xA7F8F45CCE375BB7AF8750416E1B03E0473F93C256DA2285D1134FC97A700E01, - s: 0x1F87A076F13824F4BE8963E3DFFD7300DAE64D5F23C9A062AF0C6EAD347C135F, - standard_v: 1, - status: :ok, - to_address_hash: "0x8bf38d4764929064f2d4d3a56520a76ab3df415b", - v: 0xBE, - value: 0 - } - ] - ], - addresses: [ - params: [ - %{hash: "0x8bf38d4764929064f2d4d3a56520a76ab3df415b"}, - %{hash: "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca"} - ] - ] - ] - test "can navigate to transaction show from list page", %{session: session, transaction: transaction} do session |> TransactionListPage.visit_page() @@ -253,11 +167,13 @@ defmodule ExplorerWeb.ViewingTransactionsTest do end test "block confirmations via live update", %{session: session, transaction: transaction} do + blocks = [insert(:block, number: transaction.block_number + 10)] + TransactionPage.visit_page(session, transaction) assert_text(session, TransactionPage.block_confirmations(), "0") - Chain.import_blocks(@import_data) + Notifier.handle_event({:chain_event, :blocks, blocks}) assert_text(session, TransactionPage.block_confirmations(), "10") end end