Merge pull request #8821 from blockscout/np-add-eth-bytecode-db-event

Add new events to addresses channel: eth_bytecode_db_lookup_started a…
pull/8860/head
nikitosing 1 year ago committed by GitHub
commit 167af786fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 22
      apps/block_scout_web/lib/block_scout_web/notifier.ex
  3. 2
      apps/block_scout_web/lib/block_scout_web/realtime_event_handler.ex
  4. 129
      apps/block_scout_web/test/block_scout_web/controllers/api/v2/smart_contract_controller_test.exs
  5. 6
      apps/explorer/config/test.exs
  6. 2
      apps/explorer/lib/explorer/chain/events/publisher.ex
  7. 2
      apps/explorer/lib/explorer/chain/events/subscriber.ex
  8. 3
      apps/explorer/lib/explorer/chain/fetcher/look_up_smart_contract_sources_on_demand.ex

@ -5,6 +5,7 @@
### Features ### Features
- [#8848](https://github.com/blockscout/blockscout/pull/8848) - Add MainPageRealtimeEventHandler - [#8848](https://github.com/blockscout/blockscout/pull/8848) - Add MainPageRealtimeEventHandler
- [#8821](https://github.com/blockscout/blockscout/pull/8821) - Add new events to addresses channel: `eth_bytecode_db_lookup_started` and `smart_contract_was_not_verified`
- [#8795](https://github.com/blockscout/blockscout/pull/8795) - Disable catchup indexer by env - [#8795](https://github.com/blockscout/blockscout/pull/8795) - Disable catchup indexer by env
- [#8768](https://github.com/blockscout/blockscout/pull/8768) - Add possibility to search tokens by address hash - [#8768](https://github.com/blockscout/blockscout/pull/8768) - Add possibility to search tokens by address hash
- [#8750](https://github.com/blockscout/blockscout/pull/8750) - Support new eth-bytecode-db request metadata fields - [#8750](https://github.com/blockscout/blockscout/pull/8750) - Support new eth-bytecode-db request metadata fields

@ -232,9 +232,16 @@ defmodule BlockScoutWeb.Notifier do
Endpoint.broadcast("addresses:#{to_string(address_hash)}", "changed_bytecode", %{}) Endpoint.broadcast("addresses:#{to_string(address_hash)}", "changed_bytecode", %{})
end end
def handle_event({:chain_event, :smart_contract_was_verified, :on_demand, [address_hash]}) do def handle_event({:chain_event, :smart_contract_was_verified = event, :on_demand, [address_hash]}) do
log_broadcast_smart_contract_was_verified(address_hash) broadcast_automatic_verification_events(event, address_hash)
Endpoint.broadcast("addresses:#{to_string(address_hash)}", "smart_contract_was_verified", %{}) end
def handle_event({:chain_event, :smart_contract_was_not_verified = event, :on_demand, [address_hash]}) do
broadcast_automatic_verification_events(event, address_hash)
end
def handle_event({:chain_event, :eth_bytecode_db_lookup_started = event, :on_demand, [address_hash]}) do
broadcast_automatic_verification_events(event, address_hash)
end end
def handle_event({:chain_event, :address_current_token_balances, :on_demand, address_current_token_balances}) do def handle_event({:chain_event, :address_current_token_balances, :on_demand, address_current_token_balances}) do
@ -505,7 +512,12 @@ defmodule BlockScoutWeb.Notifier do
Logger.info("Broadcast smart-contract #{address_hash} verification results") Logger.info("Broadcast smart-contract #{address_hash} verification results")
end end
defp log_broadcast_smart_contract_was_verified(address_hash) do defp log_broadcast_smart_contract_event(address_hash, event) do
Logger.info("Broadcast smart-contract #{address_hash} was verified") Logger.info("Broadcast smart-contract #{address_hash}: #{event}")
end
defp broadcast_automatic_verification_events(event, address_hash) do
log_broadcast_smart_contract_event(address_hash, event)
Endpoint.broadcast("addresses:#{to_string(address_hash)}", to_string(event), %{})
end end
end end

@ -28,6 +28,8 @@ defmodule BlockScoutWeb.RealtimeEventHandler do
Subscriber.to(:token_total_supply, :on_demand) Subscriber.to(:token_total_supply, :on_demand)
Subscriber.to(:changed_bytecode, :on_demand) Subscriber.to(:changed_bytecode, :on_demand)
Subscriber.to(:smart_contract_was_verified, :on_demand) Subscriber.to(:smart_contract_was_verified, :on_demand)
Subscriber.to(:smart_contract_was_not_verified, :on_demand)
Subscriber.to(:eth_bytecode_db_lookup_started, :on_demand)
Subscriber.to(:zkevm_confirmed_batches, :realtime) Subscriber.to(:zkevm_confirmed_batches, :realtime)
# Does not come from the indexer # Does not come from the indexer
Subscriber.to(:exchange_rate) Subscriber.to(:exchange_rate)

@ -1,5 +1,5 @@
defmodule BlockScoutWeb.API.V2.SmartContractControllerTest do defmodule BlockScoutWeb.API.V2.SmartContractControllerTest do
use BlockScoutWeb.ConnCase use BlockScoutWeb.ConnCase, async: false
use BlockScoutWeb.ChannelCase, async: false use BlockScoutWeb.ChannelCase, async: false
import Mox import Mox
@ -308,6 +308,16 @@ defmodule BlockScoutWeb.API.V2.SmartContractControllerTest do
end end
describe "/smart-contracts/{address_hash} <> eth_bytecode_db" do describe "/smart-contracts/{address_hash} <> eth_bytecode_db" do
setup do
old_interval_env = Application.get_env(:explorer, Explorer.Chain.Fetcher.LookUpSmartContractSourcesOnDemand)
:ok
on_exit(fn ->
Application.put_env(:explorer, Explorer.Chain.Fetcher.LookUpSmartContractSourcesOnDemand, old_interval_env)
end)
end
test "automatically verify contract", %{conn: conn} do test "automatically verify contract", %{conn: conn} do
{:ok, pid} = Explorer.Chain.Fetcher.LookUpSmartContractSourcesOnDemand.start_link([]) {:ok, pid} = Explorer.Chain.Fetcher.LookUpSmartContractSourcesOnDemand.start_link([])
old_chain_id = Application.get_env(:block_scout_web, :chain_id) old_chain_id = Application.get_env(:block_scout_web, :chain_id)
@ -321,7 +331,9 @@ defmodule BlockScoutWeb.API.V2.SmartContractControllerTest do
Application.put_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour, Application.put_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour,
service_url: "http://localhost:#{bypass.port}", service_url: "http://localhost:#{bypass.port}",
enabled: true enabled: true,
type: "eth_bytecode_db",
eth_bytecode_db?: true
) )
address = insert(:contract_address) address = insert(:contract_address)
@ -346,6 +358,13 @@ defmodule BlockScoutWeb.API.V2.SmartContractControllerTest do
request = get(conn, "/api/v2/smart-contracts/#{Address.checksum(address.hash)}") request = get(conn, "/api/v2/smart-contracts/#{Address.checksum(address.hash)}")
assert_receive %Phoenix.Socket.Message{
payload: %{},
event: "eth_bytecode_db_lookup_started",
topic: ^topic
},
:timer.seconds(1)
assert_receive %Phoenix.Socket.Message{ assert_receive %Phoenix.Socket.Message{
payload: %{}, payload: %{},
event: "smart_contract_was_verified", event: "smart_contract_was_verified",
@ -391,7 +410,9 @@ defmodule BlockScoutWeb.API.V2.SmartContractControllerTest do
Application.put_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour, Application.put_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour,
service_url: "http://localhost:#{bypass.port}", service_url: "http://localhost:#{bypass.port}",
enabled: true enabled: true,
type: "eth_bytecode_db",
eth_bytecode_db?: true
) )
address = insert(:contract_address) address = insert(:contract_address)
@ -416,6 +437,13 @@ defmodule BlockScoutWeb.API.V2.SmartContractControllerTest do
request = get(conn, "/api/v2/smart-contracts/#{Address.checksum(address.hash)}") request = get(conn, "/api/v2/smart-contracts/#{Address.checksum(address.hash)}")
assert_receive %Phoenix.Socket.Message{
payload: %{},
event: "eth_bytecode_db_lookup_started",
topic: ^topic
},
:timer.seconds(1)
assert_receive %Phoenix.Socket.Message{ assert_receive %Phoenix.Socket.Message{
payload: %{}, payload: %{},
event: "smart_contract_was_verified", event: "smart_contract_was_verified",
@ -508,7 +536,9 @@ defmodule BlockScoutWeb.API.V2.SmartContractControllerTest do
Application.put_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour, Application.put_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour,
service_url: "http://localhost:#{bypass.port}", service_url: "http://localhost:#{bypass.port}",
enabled: true enabled: true,
type: "eth_bytecode_db",
eth_bytecode_db?: true
) )
address = insert(:contract_address) address = insert(:contract_address)
@ -533,6 +563,13 @@ defmodule BlockScoutWeb.API.V2.SmartContractControllerTest do
request = get(conn, "/api/v2/smart-contracts/#{Address.checksum(address.hash)}") request = get(conn, "/api/v2/smart-contracts/#{Address.checksum(address.hash)}")
assert_receive %Phoenix.Socket.Message{
payload: %{},
event: "eth_bytecode_db_lookup_started",
topic: ^topic
},
:timer.seconds(1)
assert_receive %Phoenix.Socket.Message{ assert_receive %Phoenix.Socket.Message{
payload: %{}, payload: %{},
event: "smart_contract_was_verified", event: "smart_contract_was_verified",
@ -582,7 +619,9 @@ defmodule BlockScoutWeb.API.V2.SmartContractControllerTest do
Application.put_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour, Application.put_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour,
service_url: "http://localhost:#{bypass.port}", service_url: "http://localhost:#{bypass.port}",
enabled: true enabled: true,
type: "eth_bytecode_db",
eth_bytecode_db?: true
) )
address = insert(:contract_address) address = insert(:contract_address)
@ -607,6 +646,13 @@ defmodule BlockScoutWeb.API.V2.SmartContractControllerTest do
request = get(conn, "/api/v2/smart-contracts/#{Address.checksum(address.hash)}") request = get(conn, "/api/v2/smart-contracts/#{Address.checksum(address.hash)}")
assert_receive %Phoenix.Socket.Message{
payload: %{},
event: "eth_bytecode_db_lookup_started",
topic: ^topic
},
:timer.seconds(1)
assert_receive %Phoenix.Socket.Message{ assert_receive %Phoenix.Socket.Message{
payload: %{}, payload: %{},
event: "smart_contract_was_verified", event: "smart_contract_was_verified",
@ -673,6 +719,12 @@ defmodule BlockScoutWeb.API.V2.SmartContractControllerTest do
bypass = Bypass.open() bypass = Bypass.open()
address = insert(:contract_address) address = insert(:contract_address)
topic = "addresses:#{address.hash}"
{:ok, _reply, _socket} =
BlockScoutWeb.UserSocketV2
|> socket("no_id", %{})
|> subscribe_and_join(topic)
insert(:transaction, insert(:transaction,
created_contract_address_hash: address.hash, created_contract_address_hash: address.hash,
@ -685,7 +737,9 @@ defmodule BlockScoutWeb.API.V2.SmartContractControllerTest do
Application.put_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour, Application.put_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour,
service_url: "http://localhost:#{bypass.port}", service_url: "http://localhost:#{bypass.port}",
enabled: true enabled: true,
type: "eth_bytecode_db",
eth_bytecode_db?: true
) )
old_interval_env = Application.get_env(:explorer, Explorer.Chain.Fetcher.LookUpSmartContractSourcesOnDemand) old_interval_env = Application.get_env(:explorer, Explorer.Chain.Fetcher.LookUpSmartContractSourcesOnDemand)
@ -698,6 +752,20 @@ defmodule BlockScoutWeb.API.V2.SmartContractControllerTest do
_request = get(conn, "/api/v2/smart-contracts/#{Address.checksum(address.hash)}") _request = get(conn, "/api/v2/smart-contracts/#{Address.checksum(address.hash)}")
assert_receive %Phoenix.Socket.Message{
payload: %{},
event: "eth_bytecode_db_lookup_started",
topic: ^topic
},
:timer.seconds(1)
assert_receive %Phoenix.Socket.Message{
payload: %{},
event: "smart_contract_was_not_verified",
topic: ^topic
},
:timer.seconds(1)
:timer.sleep(10) :timer.sleep(10)
Bypass.expect_once(bypass, "POST", "/api/v2/bytecodes/sources_search", fn conn -> Bypass.expect_once(bypass, "POST", "/api/v2/bytecodes/sources_search", fn conn ->
@ -706,6 +774,20 @@ defmodule BlockScoutWeb.API.V2.SmartContractControllerTest do
_request = get(conn, "/api/v2/smart-contracts/#{Address.checksum(address.hash)}") _request = get(conn, "/api/v2/smart-contracts/#{Address.checksum(address.hash)}")
assert_receive %Phoenix.Socket.Message{
payload: %{},
event: "eth_bytecode_db_lookup_started",
topic: ^topic
},
:timer.seconds(1)
assert_receive %Phoenix.Socket.Message{
payload: %{},
event: "smart_contract_was_not_verified",
topic: ^topic
},
:timer.seconds(1)
:timer.sleep(10) :timer.sleep(10)
Bypass.expect_once(bypass, "POST", "/api/v2/bytecodes/sources_search", fn conn -> Bypass.expect_once(bypass, "POST", "/api/v2/bytecodes/sources_search", fn conn ->
@ -714,12 +796,47 @@ defmodule BlockScoutWeb.API.V2.SmartContractControllerTest do
_request = get(conn, "/api/v2/smart-contracts/#{Address.checksum(address.hash)}") _request = get(conn, "/api/v2/smart-contracts/#{Address.checksum(address.hash)}")
assert_receive %Phoenix.Socket.Message{
payload: %{},
event: "eth_bytecode_db_lookup_started",
topic: ^topic
},
:timer.seconds(1)
assert_receive %Phoenix.Socket.Message{
payload: %{},
event: "smart_contract_was_not_verified",
topic: ^topic
},
:timer.seconds(1)
:timer.sleep(10) :timer.sleep(10)
Application.put_env(:explorer, Explorer.Chain.Fetcher.LookUpSmartContractSourcesOnDemand, fetch_interval: 10000) Application.put_env(:explorer, Explorer.Chain.Fetcher.LookUpSmartContractSourcesOnDemand, fetch_interval: 10000)
_request = get(conn, "/api/v2/smart-contracts/#{Address.checksum(address.hash)}") _request = get(conn, "/api/v2/smart-contracts/#{Address.checksum(address.hash)}")
refute_receive %Phoenix.Socket.Message{
payload: %{},
event: "eth_bytecode_db_lookup_started",
topic: ^topic
},
:timer.seconds(1)
refute_receive %Phoenix.Socket.Message{
payload: %{},
event: "smart_contract_was_not_verified",
topic: ^topic
},
:timer.seconds(1)
refute_receive %Phoenix.Socket.Message{
payload: %{},
event: "smart_contract_was_verified",
topic: ^topic
},
:timer.seconds(1)
Application.put_env(:block_scout_web, :chain_id, old_chain_id) Application.put_env(:block_scout_web, :chain_id, old_chain_id)
Application.put_env(:explorer, Explorer.Chain.Fetcher.LookUpSmartContractSourcesOnDemand, old_interval_env) Application.put_env(:explorer, Explorer.Chain.Fetcher.LookUpSmartContractSourcesOnDemand, old_interval_env)
Application.put_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour, old_env) Application.put_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour, old_env)

@ -12,7 +12,8 @@ config :explorer, Explorer.Repo,
ownership_timeout: :timer.minutes(7), ownership_timeout: :timer.minutes(7),
timeout: :timer.seconds(60), timeout: :timer.seconds(60),
queue_target: 1000, queue_target: 1000,
migration_lock: nil migration_lock: nil,
log: false
# Configure API database # Configure API database
config :explorer, Explorer.Repo.Replica1, config :explorer, Explorer.Repo.Replica1,
@ -26,7 +27,8 @@ config :explorer, Explorer.Repo.Replica1,
enable_caching_implementation_data_of_proxy: true, enable_caching_implementation_data_of_proxy: true,
avg_block_time_as_ttl_cached_implementation_data_of_proxy: false, avg_block_time_as_ttl_cached_implementation_data_of_proxy: false,
fallback_ttl_cached_implementation_data_of_proxy: :timer.seconds(20), fallback_ttl_cached_implementation_data_of_proxy: :timer.seconds(20),
implementation_data_fetching_timeout: :timer.seconds(20) implementation_data_fetching_timeout: :timer.seconds(20),
log: false
# Configure API database # Configure API database
config :explorer, Explorer.Repo.Account, config :explorer, Explorer.Repo.Account,

@ -3,7 +3,7 @@ defmodule Explorer.Chain.Events.Publisher do
Publishes events related to the Chain context. Publishes events related to the Chain context.
""" """
@allowed_events ~w(addresses address_coin_balances address_token_balances address_current_token_balances blocks block_rewards internal_transactions last_block_number polygon_edge_reorg_block token_transfers transactions contract_verification_result token_total_supply changed_bytecode smart_contract_was_verified zkevm_confirmed_batches)a @allowed_events ~w(addresses address_coin_balances address_token_balances address_current_token_balances blocks block_rewards internal_transactions last_block_number polygon_edge_reorg_block token_transfers transactions contract_verification_result token_total_supply changed_bytecode smart_contract_was_verified zkevm_confirmed_batches eth_bytecode_db_lookup_started smart_contract_was_not_verified)a
def broadcast(_data, false), do: :ok def broadcast(_data, false), do: :ok

@ -3,7 +3,7 @@ defmodule Explorer.Chain.Events.Subscriber do
Subscribes to events related to the Chain context. Subscribes to events related to the Chain context.
""" """
@allowed_broadcast_events ~w(addresses address_coin_balances address_token_balances address_current_token_balances blocks block_rewards internal_transactions last_block_number polygon_edge_reorg_block token_transfers transactions contract_verification_result token_total_supply changed_bytecode smart_contract_was_verified zkevm_confirmed_batches)a @allowed_broadcast_events ~w(addresses address_coin_balances address_token_balances address_current_token_balances blocks block_rewards internal_transactions last_block_number polygon_edge_reorg_block token_transfers transactions contract_verification_result token_total_supply changed_bytecode smart_contract_was_verified zkevm_confirmed_batches eth_bytecode_db_lookup_started smart_contract_was_not_verified)a
@allowed_broadcast_types ~w(catchup realtime on_demand contract_verification_result)a @allowed_broadcast_types ~w(catchup realtime on_demand contract_verification_result)a

@ -34,6 +34,8 @@ defmodule Explorer.Chain.Fetcher.LookUpSmartContractSourcesOnDemand do
end end
defp fetch_sources(address, only_full?) do defp fetch_sources(address, only_full?) do
Publisher.broadcast(%{eth_bytecode_db_lookup_started: [address.hash]}, :on_demand)
creation_tx_input = contract_creation_input(address.hash) creation_tx_input = contract_creation_input(address.hash)
with {:ok, %{"sourceType" => type, "matchType" => match_type} = source} <- with {:ok, %{"sourceType" => type, "matchType" => match_type} = source} <-
@ -45,6 +47,7 @@ defmodule Explorer.Chain.Fetcher.LookUpSmartContractSourcesOnDemand do
Publisher.broadcast(%{smart_contract_was_verified: [address.hash]}, :on_demand) Publisher.broadcast(%{smart_contract_was_verified: [address.hash]}, :on_demand)
else else
_ -> _ ->
Publisher.broadcast(%{smart_contract_was_not_verified: [address.hash]}, :on_demand)
false false
end end
end end

Loading…
Cancel
Save