diff --git a/apps/explorer/lib/explorer/tags/address_tag.ex b/apps/explorer/lib/explorer/tags/address_tag.ex index 65d7cc008b..d6c20c2d26 100644 --- a/apps/explorer/lib/explorer/tags/address_tag.ex +++ b/apps/explorer/lib/explorer/tags/address_tag.ex @@ -1,6 +1,6 @@ defmodule Explorer.Tags.AddressTag do @moduledoc """ - Represents a Tag object. + Represents an address Tag object. """ use Explorer.Schema @@ -9,11 +9,12 @@ defmodule Explorer.Tags.AddressTag do import Ecto.Query, only: [ - from: 2 + from: 2, + select: 3 ] alias Explorer.Repo - alias Explorer.Tags.{AddressTag, AddressToTag} + alias Explorer.Tags.AddressToTag @typedoc """ * `:id` - id of Tag @@ -21,7 +22,7 @@ defmodule Explorer.Tags.AddressTag do * `:display_name` - Label's display name """ typed_schema "address_tags" do - field(:label, :string, null: false) + field(:label, :string, primary_key: true, null: false) field(:display_name, :string, null: false) has_many(:tag_id, AddressToTag, foreign_key: :id) @@ -38,55 +39,61 @@ defmodule Explorer.Tags.AddressTag do |> unique_constraint(:label, name: :address_tags_label_index) end - def set_tag(name, display_name) do - tag = get_tag(name) + @spec set(String.t() | nil, String.t() | nil) :: {:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()} | :invalid + def set(name, display_name) + + def set(nil, _), do: :invalid + + def set(_, nil), do: :invalid + + def set(name, display_name) do + tag = get_by_label(name) if tag do tag - |> AddressTag.changeset(%{display_name: display_name}) + |> __MODULE__.changeset(%{display_name: display_name}) |> Repo.update() else - %AddressTag{} - |> AddressTag.changeset(%{label: name, display_name: display_name}) + %__MODULE__{} + |> __MODULE__.changeset(%{label: name, display_name: display_name}) |> Repo.insert() end end - def get_tag_id(nil), do: nil - - def get_tag_id(label) do - query = - from( - tag in AddressTag, - where: tag.label == ^label, - select: tag.id - ) + @doc """ + Fetches AddressTag.t() by label name from the DB + """ + @spec get_id_by_label(String.t()) :: non_neg_integer() + def get_id_by_label(nil), do: nil - query + def get_id_by_label(label) do + label + |> get_by_label_query() + |> select([tag], tag.id) |> Repo.one() end - def get_tag(nil), do: nil + @doc """ + Fetches all AddressTag.t() from the DB + """ + @spec get_all() :: __MODULE__.t() + def get_all do + __MODULE__ + |> Repo.all() + end - def get_tag(label) do - query = - from( - tag in AddressTag, - where: tag.label == ^label - ) + defp get_by_label(nil), do: nil - query + defp get_by_label(label) do + label + |> get_by_label_query() |> Repo.one() end - def get_all_tags do - query = - from( - tag in AddressTag, - select: tag - ) - - query - |> Repo.all() + defp get_by_label_query(label) do + from( + tag in __MODULE__, + where: tag.label == ^label + ) end end diff --git a/apps/explorer/lib/explorer/tags/address_tag_cataloger.ex b/apps/explorer/lib/explorer/tags/address_tag_cataloger.ex index da54d81e2d..5295a29d30 100644 --- a/apps/explorer/lib/explorer/tags/address_tag_cataloger.ex +++ b/apps/explorer/lib/explorer/tags/address_tag_cataloger.ex @@ -9,7 +9,6 @@ defmodule Explorer.Tags.AddressTag.Cataloger do alias Explorer.EnvVarTranslator alias Explorer.Tags.{AddressTag, AddressToTag} alias Explorer.Validator.MetadataRetriever - alias Poison.Parser def start_link(_) do GenServer.start_link(__MODULE__, :ok, name: __MODULE__) @@ -24,9 +23,6 @@ defmodule Explorer.Tags.AddressTag.Cataloger do @impl GenServer def handle_info(:fetch_tags, state) do - # set tag for every chainlink oracle - create_chainlink_oracle_tag() - create_new_tags() send(self(), :bind_addresses) @@ -47,7 +43,7 @@ defmodule Explorer.Tags.AddressTag.Cataloger do # set L2 tag set_l2_tag() - all_tags = AddressTag.get_all_tags() + all_tags = AddressTag.get_all() all_tags |> Enum.each(fn %{label: tag_name} -> @@ -68,21 +64,6 @@ defmodule Explorer.Tags.AddressTag.Cataloger do |> String.replace(".", "_") end - def create_chainlink_oracle_tag do - chainlink_oracles_config = Application.get_env(:block_scout_web, :chainlink_oracles) - - if chainlink_oracles_config do - chainlink_oracles_config - |> Parser.parse!(%{keys: :atoms!}) - |> Enum.each(fn %{:name => name, :address => address} -> - chainlink_tag_name = "chainlink oracle #{String.downcase(name)}" - AddressTag.set_tag(chainlink_tag_name, chainlink_tag_name) - tag_id = AddressTag.get_tag_id(chainlink_tag_name) - AddressToTag.set_tag_to_addresses(tag_id, [address]) - end) - end - end - defp set_tag_for_multiple_env_var_addresses(env_vars, tag) do addresses = env_vars @@ -92,7 +73,7 @@ defmodule Explorer.Tags.AddressTag.Cataloger do |> String.downcase() end) - tag_id = AddressTag.get_tag_id(tag) + tag_id = AddressTag.get_id_by_label(tag) AddressToTag.set_tag_to_addresses(tag_id, addresses) end @@ -112,23 +93,23 @@ defmodule Explorer.Tags.AddressTag.Cataloger do end) end) - tag_id = AddressTag.get_tag_id(tag) + tag_id = AddressTag.get_id_by_label(tag) AddressToTag.set_tag_to_addresses(tag_id, addresses) end - def create_new_tags do + defp create_new_tags do tags = EnvVarTranslator.map_array_env_var_to_list(:new_tags) tags |> Enum.each(fn %{tag: tag_name, title: tag_display_name} -> - AddressTag.set_tag(tag_name, tag_display_name) + AddressTag.set(tag_name, tag_display_name) end) end defp set_tag_for_env_var_multiple_addresses(env_var, tag) do addresses = env_var_string_array_to_list(env_var) - tag_id = AddressTag.get_tag_id(tag) + tag_id = AddressTag.get_id_by_label(tag) AddressToTag.set_tag_to_addresses(tag_id, addresses) end @@ -152,7 +133,7 @@ defmodule Explorer.Tags.AddressTag.Cataloger do defp set_validator_tag do validators = MetadataRetriever.fetch_validators_list() FetchValidatorInfoOnDemand.trigger_fetch(validators) - tag_id = AddressTag.get_tag_id("validator") + tag_id = AddressTag.get_id_by_label("validator") AddressToTag.set_tag_to_addresses(tag_id, validators) end @@ -177,28 +158,4 @@ defmodule Explorer.Tags.AddressTag.Cataloger do defp set_l2_tag do set_tag_for_multiple_env_var_addresses(["CUSTOM_CONTRACT_ADDRESSES_AOX"], "l2") end - - def set_chainlink_oracle_tag do - chainlink_oracles = chainlink_oracles_list() - - tag_id = AddressTag.get_tag_id("chainlink oracle") - AddressToTag.set_tag_to_addresses(tag_id, chainlink_oracles) - end - - defp chainlink_oracles_list do - chainlink_oracles_config = Application.get_env(:block_scout_web, :chainlink_oracles) - - if chainlink_oracles_config do - try do - chainlink_oracles_config - |> Parser.parse!(%{keys: :atoms!}) - |> Enum.map(fn %{:name => _name, :address => address} -> address end) - rescue - _ -> - [] - end - else - [] - end - end end diff --git a/apps/explorer/lib/explorer/tags/address_to_tag.ex b/apps/explorer/lib/explorer/tags/address_to_tag.ex index 729b5eb505..6f83a0cdce 100644 --- a/apps/explorer/lib/explorer/tags/address_to_tag.ex +++ b/apps/explorer/lib/explorer/tags/address_to_tag.ex @@ -1,6 +1,6 @@ defmodule Explorer.Tags.AddressToTag do @moduledoc """ - Represents ann Address to Tag relation. + Represents Address to Tag relation. """ use Explorer.Schema @@ -9,7 +9,7 @@ defmodule Explorer.Tags.AddressToTag do alias Explorer.{Chain, Repo} alias Explorer.Chain.{Address, Hash} - alias Explorer.Tags.{AddressTag, AddressToTag} + alias Explorer.Tags.AddressTag # Notation.import_types(BlockScoutWeb.GraphQL.Schema.Types) @@ -53,7 +53,7 @@ defmodule Explorer.Tags.AddressToTag do defp get_address_hashes_mapped_to_tag(tag_id) do query = from( - att in AddressToTag, + att in __MODULE__, where: att.tag_id == ^tag_id, select: att.address_hash ) @@ -62,6 +62,7 @@ defmodule Explorer.Tags.AddressToTag do |> Repo.all() end + @spec set_tag_to_addresses(non_neg_integer(), list()) :: any() def set_tag_to_addresses(tag_id, address_hash_string_list) do current_address_hashes = get_address_hashes_mapped_to_tag(tag_id) @@ -105,10 +106,10 @@ defmodule Explorer.Tags.AddressToTag do end) |> Enum.filter(&(!is_nil(&1))) - if not Enum.empty?(addresses_to_delete) do + unless Enum.empty?(addresses_to_delete) do delete_query_base = from( - att in AddressToTag, + att in __MODULE__, where: att.tag_id == ^tag_id ) @@ -119,7 +120,7 @@ defmodule Explorer.Tags.AddressToTag do Repo.delete_all(delete_query) end - Repo.insert_all(AddressToTag, changeset_to_add_list, + Repo.insert_all(__MODULE__, changeset_to_add_list, on_conflict: :nothing, conflict_target: [:address_hash, :tag_id] ) diff --git a/apps/explorer/priv/repo/migrations/20240923173516_address_tags_add_primary_key.exs b/apps/explorer/priv/repo/migrations/20240923173516_address_tags_add_primary_key.exs new file mode 100644 index 0000000000..97a93144c5 --- /dev/null +++ b/apps/explorer/priv/repo/migrations/20240923173516_address_tags_add_primary_key.exs @@ -0,0 +1,9 @@ +defmodule Explorer.Repo.Migrations.AddressTagsAddPrimaryKey do + use Ecto.Migration + + def change do + alter table(:address_tags) do + modify(:label, :string, null: false, primary_key: true) + end + end +end