Fix bug with proxy for twins

pull/6549/head
Никита Поздняков 2 years ago
parent 9df316a946
commit 21381914aa
No known key found for this signature in database
GPG Key ID: F344106F9804FE5F
  1. 2
      CHANGELOG.md
  2. 17
      apps/explorer/lib/explorer/chain.ex
  3. 54
      apps/explorer/lib/explorer/chain/smart_contract.ex

@ -3,7 +3,7 @@
### Features
- [#6544](https://github.com/blockscout/blockscout/pull/6544) - API improvements
- [#5561](https://github.com/blockscout/blockscout/pull/5561), [#6523](https://github.com/blockscout/blockscout/pull/6523) - Improve working with contracts implementations
- [#5561](https://github.com/blockscout/blockscout/pull/5561), [#6523](https://github.com/blockscout/blockscout/pull/6523), [#6549](https://github.com/blockscout/blockscout/pull/6549) - Improve working with contracts implementations
- [#6401](https://github.com/blockscout/blockscout/pull/6401) - Add Sol2Uml contract visualization
- [#6481](https://github.com/blockscout/blockscout/pull/6481) - Smart contract verification improvements
- [#6444](https://github.com/blockscout/blockscout/pull/6444) - Add support for yul verification via rust microservice

@ -1384,7 +1384,10 @@ defmodule Explorer.Chain do
address_verified_twin_contract_updated =
address_verified_twin_contract
|> Map.put(:address_hash, hash)
|> Map.put_new(:metadata_from_verified_twin, true)
|> Map.put(:metadata_from_verified_twin, true)
|> Map.put(:implementation_address_hash, nil)
|> Map.put(:implementation_name, nil)
|> Map.put(:implementation_fetched_at, nil)
address_result
|> Map.put(:smart_contract, address_verified_twin_contract_updated)
@ -1902,7 +1905,10 @@ defmodule Explorer.Chain do
address_verified_twin_contract_updated =
address_verified_twin_contract
|> Map.put(:address_hash, hash)
|> Map.put_new(:metadata_from_verified_twin, true)
|> Map.put(:metadata_from_verified_twin, true)
|> Map.put(:implementation_address_hash, nil)
|> Map.put(:implementation_name, nil)
|> Map.put(:implementation_fetched_at, nil)
address_result
|> Map.put(:smart_contract, address_verified_twin_contract_updated)
@ -4349,9 +4355,10 @@ defmodule Explorer.Chain do
if address_verified_twin_contract do
address_verified_twin_contract
|> Map.put(:address_hash, address_hash)
|> Map.put(:implementation_address_hash, current_smart_contract.implementation_address_hash)
|> Map.put(:implementation_name, current_smart_contract.implementation_name)
|> Map.put(:implementation_fetched_at, current_smart_contract.implementation_fetched_at)
|> Map.put(:metadata_from_verified_twin, true)
|> Map.put(:implementation_address_hash, nil)
|> Map.put(:implementation_name, nil)
|> Map.put(:implementation_fetched_at, nil)
else
current_smart_contract
end

@ -261,6 +261,7 @@ defmodule Explorer.Chain.SmartContract do
field(:implementation_address_hash, Hash.Address, default: nil)
field(:autodetect_constructor_args, :boolean, virtual: true)
field(:is_yul, :boolean, virtual: true)
field(:metadata_from_verified_twin, :boolean, virtual: true)
has_many(
:decompiled_smart_contracts,
@ -529,7 +530,11 @@ defmodule Explorer.Chain.SmartContract do
def proxy_contract?(_), do: false
def get_implementation_address_hash(%__MODULE__{abi: nil}), do: false
def get_implementation_address_hash(%__MODULE__{abi: nil}), do: {nil, nil}
def get_implementation_address_hash(%__MODULE__{metadata_from_verified_twin: true} = smart_contract) do
get_implementation_address_hash({:updated, smart_contract})
end
def get_implementation_address_hash(
%__MODULE__{
@ -540,7 +545,7 @@ defmodule Explorer.Chain.SmartContract do
updated_smart_contract =
if Application.get_env(:explorer, :enable_caching_implementation_data_of_proxy) &&
check_implementation_refetch_neccessity(implementation_fetched_at) do
Chain.address_hash_to_smart_contract(address_hash)
Chain.address_hash_to_smart_contract_without_twin(address_hash)
else
smart_contract
end
@ -555,11 +560,13 @@ defmodule Explorer.Chain.SmartContract do
abi: abi,
implementation_address_hash: implementation_address_hash_from_db,
implementation_name: implementation_name_from_db,
implementation_fetched_at: implementation_fetched_at
implementation_fetched_at: implementation_fetched_at,
metadata_from_verified_twin: metadata_from_verified_twin
}}
) do
if check_implementation_refetch_neccessity(implementation_fetched_at) do
get_implementation_address_hash_task = Task.async(fn -> get_implementation_address_hash(address_hash, abi) end)
get_implementation_address_hash_task =
Task.async(fn -> get_implementation_address_hash(address_hash, abi, metadata_from_verified_twin) end)
timeout = Application.get_env(:explorer, :implementation_data_fetching_timeout)
@ -624,8 +631,9 @@ defmodule Explorer.Chain.SmartContract do
end
end
@spec get_implementation_address_hash(Hash.Address.t(), list()) :: {String.t() | nil, String.t() | nil}
defp get_implementation_address_hash(proxy_address_hash, abi)
@spec get_implementation_address_hash(Hash.Address.t(), list(), boolean() | nil) ::
{String.t() | nil, String.t() | nil}
defp get_implementation_address_hash(proxy_address_hash, abi, metadata_from_verified_twin)
when not is_nil(proxy_address_hash) and not is_nil(abi) do
implementation_method_abi =
abi
@ -651,10 +659,10 @@ defmodule Explorer.Chain.SmartContract do
get_implementation_address_hash_eip_1967(proxy_address_hash)
end
save_implementation_data(implementation_address, proxy_address_hash)
save_implementation_data(implementation_address, proxy_address_hash, metadata_from_verified_twin)
end
defp get_implementation_address_hash(proxy_address_hash, abi) when is_nil(proxy_address_hash) or is_nil(abi) do
defp get_implementation_address_hash(_proxy_address_hash, _abi, _) do
{nil, nil}
end
@ -794,28 +802,30 @@ defmodule Explorer.Chain.SmartContract do
abi_decode_address_output(implementation_address)
end
defp save_implementation_data(nil, _), do: {nil, nil}
defp save_implementation_data(nil, _, _), do: {nil, nil}
defp save_implementation_data(empty_address_hash_string, proxy_address_hash)
defp save_implementation_data(empty_address_hash_string, proxy_address_hash, metadata_from_verified_twin)
when empty_address_hash_string in [
"0x",
"0x0",
"0x0000000000000000000000000000000000000000000000000000000000000000",
@burn_address_hash_str
] do
proxy_address_hash
|> Chain.address_hash_to_smart_contract_without_twin()
|> changeset(%{
implementation_name: nil,
implementation_address_hash: nil,
implementation_fetched_at: DateTime.utc_now()
})
|> Repo.update()
if is_nil(metadata_from_verified_twin) or !metadata_from_verified_twin do
proxy_address_hash
|> Chain.address_hash_to_smart_contract_without_twin()
|> changeset(%{
implementation_name: nil,
implementation_address_hash: nil,
implementation_fetched_at: DateTime.utc_now()
})
|> Repo.update()
end
{:empty, :empty}
end
defp save_implementation_data(implementation_address_hash_string, proxy_address_hash)
defp save_implementation_data(implementation_address_hash_string, proxy_address_hash, _)
when is_binary(implementation_address_hash_string) do
with {:ok, address_hash} <- Chain.string_to_address_hash(implementation_address_hash_string),
proxy_contract <- Chain.address_hash_to_smart_contract_without_twin(proxy_address_hash),
@ -845,6 +855,12 @@ defmodule Explorer.Chain.SmartContract do
{implementation_address_hash_string, nil}
true ->
{:ok, address_hash} = Chain.string_to_address_hash(implementation_address_hash_string)
smart_contract = Chain.address_hash_to_smart_contract(address_hash)
{implementation_address_hash_string, smart_contract && smart_contract.name}
_ ->
{implementation_address_hash_string, nil}
end

Loading…
Cancel
Save