fix: abi cache for non-proxied addresses (#11065)

* fix: abi cache for non-proxied addresses

* chore: rename
pull/11074/head
Kirill Fedoseev 4 weeks ago committed by GitHub
parent 608f319765
commit a65b7f82ba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 49
      apps/explorer/lib/explorer/chain/transaction.ex

@ -769,10 +769,10 @@ defmodule Explorer.Chain.Transaction do
boolean(),
[Chain.api?()],
methods_map,
proxy_implementation_abi_map
smart_contract_full_abi_map
) :: error_type | success_type
when methods_map: map(),
proxy_implementation_abi_map: map(),
smart_contract_full_abi_map: map(),
error_type: {:error, any()} | {:error, :contract_not_verified | :contract_verified, list()},
success_type: {:ok | binary(), any()} | {:ok, binary(), binary(), list()}
def decoded_input_data(
@ -780,7 +780,7 @@ defmodule Explorer.Chain.Transaction do
skip_sig_provider? \\ false,
options,
methods_map \\ %{},
proxy_implementation_abi_map \\ %{}
smart_contract_full_abi_map \\ %{}
)
# skip decoding if there is no to_address
@ -831,7 +831,7 @@ defmodule Explorer.Chain.Transaction do
skip_sig_provider?,
options,
methods_map,
proxy_implementation_abi_map
smart_contract_full_abi_map
) do
decoded_input_data(
%__MODULE__{
@ -842,7 +842,7 @@ defmodule Explorer.Chain.Transaction do
skip_sig_provider?,
options,
methods_map,
proxy_implementation_abi_map
smart_contract_full_abi_map
)
end
@ -856,7 +856,7 @@ defmodule Explorer.Chain.Transaction do
skip_sig_provider?,
options,
methods_map,
proxy_implementation_abi_map
smart_contract_full_abi_map
) do
decoded_input_data(
%__MODULE__{
@ -867,7 +867,7 @@ defmodule Explorer.Chain.Transaction do
skip_sig_provider?,
options,
methods_map,
proxy_implementation_abi_map
smart_contract_full_abi_map
)
end
@ -881,7 +881,7 @@ defmodule Explorer.Chain.Transaction do
skip_sig_provider?,
options,
methods_map,
_proxy_implementation_abi_map
_smart_contract_full_abi_map
) do
methods = check_methods_cache(method_id, methods_map, options)
@ -922,9 +922,9 @@ defmodule Explorer.Chain.Transaction do
skip_sig_provider?,
options,
methods_map,
proxy_implementation_abi_map
smart_contract_full_abi_map
) do
full_abi = check_full_abi_cache(smart_contract, proxy_implementation_abi_map, options)
full_abi = check_full_abi_cache(smart_contract, smart_contract_full_abi_map, options)
case do_decoded_input_data(data, full_abi, hash) do
# In some cases transactions use methods of some unpredictable contracts, so we can try to look up for method in a whole DB
@ -938,7 +938,7 @@ defmodule Explorer.Chain.Transaction do
skip_sig_provider?,
options,
methods_map,
proxy_implementation_abi_map
smart_contract_full_abi_map
) do
{:error, :contract_not_verified, []} ->
decode_function_call_via_sig_provider_wrapper(input, hash, skip_sig_provider?)
@ -999,10 +999,10 @@ defmodule Explorer.Chain.Transaction do
defp check_full_abi_cache(
smart_contract,
proxy_implementation_abi_map,
smart_contract_full_abi_map,
options
) do
Map.get_lazy(proxy_implementation_abi_map, smart_contract.address_hash, fn ->
Map.get_lazy(smart_contract_full_abi_map, smart_contract.address_hash, fn ->
Proxy.combine_proxy_implementation_abi(smart_contract, options)
end)
end
@ -1994,7 +1994,7 @@ defmodule Explorer.Chain.Transaction do
"""
@spec decode_transactions([Transaction.t()], boolean(), Keyword.t()) :: [nil | {:ok, String.t(), String.t(), map()}]
def decode_transactions(transactions, skip_sig_provider?, opts) do
proxy_implementation_abi_map = combine_proxy_implementation_abi_map(transactions)
smart_contract_full_abi_map = combine_smart_contract_full_abi_map(transactions)
# first we assemble an empty methods map, so that decoded_input_data will skip ContractMethod.t() lookup and decoding
empty_methods_map =
@ -2005,12 +2005,12 @@ defmodule Explorer.Chain.Transaction do
end)
|> Enum.into(%{}, &{&1, []})
# try to decode transaction using full abi data from proxy_implementation_abi_map
# try to decode transaction using full abi data from smart_contract_full_abi_map
decoded_transactions =
transactions
|> Enum.map(fn transaction ->
transaction
|> decoded_input_data(skip_sig_provider?, opts, empty_methods_map, proxy_implementation_abi_map)
|> decoded_input_data(skip_sig_provider?, opts, empty_methods_map, smart_contract_full_abi_map)
|> format_decoded_input()
end)
|> Enum.zip(transactions)
@ -2032,7 +2032,7 @@ defmodule Explorer.Chain.Transaction do
{nil, transaction} ->
transaction
|> Map.put(:to_address, %NotLoaded{})
|> decoded_input_data(skip_sig_provider?, opts, methods_map, proxy_implementation_abi_map)
|> decoded_input_data(skip_sig_provider?, opts, methods_map, smart_contract_full_abi_map)
|> format_decoded_input()
{decoded, _} ->
@ -2040,7 +2040,7 @@ defmodule Explorer.Chain.Transaction do
end)
end
defp combine_proxy_implementation_abi_map(transactions) do
defp combine_smart_contract_full_abi_map(transactions) do
# parse unique address hashes of smart-contracts from to_address and created_contract_address properties of the transactions list
unique_to_address_hashes =
transactions
@ -2063,11 +2063,16 @@ defmodule Explorer.Chain.Transaction do
|> Chain.hashes_to_addresses(necessity_by_association: %{smart_contract: :optional})
|> Enum.into(%{}, &{&1.hash, &1})
# combine map %{proxy_address_hash => combined proxy abi}
# combine map %{proxy_address_hash => implementation address hashes}
proxy_implementations_map =
multiple_proxy_implementations
|> Enum.into(%{}, fn proxy_implementations ->
|> Enum.into(%{}, &{&1.proxy_address_hash, &1.address_hashes})
# combine map %{proxy_address_hash => combined proxy abi}
unique_to_address_hashes
|> Enum.into(%{}, fn to_address_hash ->
full_abi =
[proxy_implementations.proxy_address_hash | proxy_implementations.address_hashes]
[to_address_hash | Map.get(proxy_implementations_map, to_address_hash, [])]
|> Enum.map(&Map.get(addresses_with_smart_contracts, &1))
|> Enum.flat_map(fn
%{smart_contract: %{abi: abi}} when is_list(abi) -> abi
@ -2075,7 +2080,7 @@ defmodule Explorer.Chain.Transaction do
end)
|> Enum.filter(&(!is_nil(&1)))
{proxy_implementations.proxy_address_hash, full_abi}
{to_address_hash, full_abi}
end)
end

Loading…
Cancel
Save