From e6b39be251dbbf79728f66e3acb0c95ec9367388 Mon Sep 17 00:00:00 2001 From: Viktor Baranov Date: Mon, 15 Jan 2024 11:26:04 +0300 Subject: [PATCH] Manage proxy implementation ttl via avg block time --- CHANGELOG.md | 1 + apps/explorer/config/test.exs | 10 ++- .../lib/explorer/chain/smart_contract.ex | 14 +-- .../explorer/chain/smart_contract_test.exs | 89 +++++++++++++++---- config/runtime.exs | 11 ++- 5 files changed, 94 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b96216dbee..42c62c075d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Features +- [#9155](https://github.com/blockscout/blockscout/pull/9155) - Allow bypassing avg block time in proxy implementation re-fetch ttl calculation - [#9072](https://github.com/blockscout/blockscout/pull/9072) - Add tracing by block logic for geth - [#9056](https://github.com/blockscout/blockscout/pull/9056) - Noves.fi API proxy diff --git a/apps/explorer/config/test.exs b/apps/explorer/config/test.exs index 955f9df842..b292598e17 100644 --- a/apps/explorer/config/test.exs +++ b/apps/explorer/config/test.exs @@ -24,12 +24,14 @@ config :explorer, Explorer.Repo.Replica1, ownership_timeout: :timer.minutes(1), timeout: :timer.seconds(60), queue_target: 1000, - enable_caching_implementation_data_of_proxy: true, - avg_block_time_as_ttl_cached_implementation_data_of_proxy: false, - fallback_ttl_cached_implementation_data_of_proxy: :timer.seconds(20), - implementation_data_fetching_timeout: :timer.seconds(20), log: false +config :explorer, :proxy, + caching_implementation_data_enabled: true, + implementation_data_ttl_via_avg_block_time: false, + fallback_cached_implementation_data_ttl: :timer.seconds(20), + implementation_data_fetching_timeout: :timer.seconds(20) + # Configure API database config :explorer, Explorer.Repo.Account, database: "explorer_test_account", diff --git a/apps/explorer/lib/explorer/chain/smart_contract.ex b/apps/explorer/lib/explorer/chain/smart_contract.ex index 1d381ef92e..65105cbf85 100644 --- a/apps/explorer/lib/explorer/chain/smart_contract.ex +++ b/apps/explorer/lib/explorer/chain/smart_contract.ex @@ -516,7 +516,7 @@ defmodule Explorer.Chain.SmartContract do options ) do updated_smart_contract = - if Application.get_env(:explorer, :enable_caching_implementation_data_of_proxy) && + if Application.get_env(:explorer, :proxy)[:caching_implementation_data_enabled] && check_implementation_refetch_necessity(implementation_fetched_at) do address_hash_to_smart_contract_without_twin(address_hash, options) else @@ -544,7 +544,7 @@ defmodule Explorer.Chain.SmartContract do Proxy.fetch_implementation_address_hash(address_hash, abi, metadata_from_verified_twin, options) end) - timeout = Application.get_env(:explorer, :implementation_data_fetching_timeout) + timeout = Application.get_env(:explorer, :proxy)[:implementation_data_fetching_timeout] case Task.yield(get_implementation_address_hash_task, timeout) || Task.ignore(get_implementation_address_hash_task) do @@ -1182,15 +1182,15 @@ defmodule Explorer.Chain.SmartContract do defp check_implementation_refetch_necessity(nil), do: true defp check_implementation_refetch_necessity(timestamp) do - if Application.get_env(:explorer, :enable_caching_implementation_data_of_proxy) do + if Application.get_env(:explorer, :proxy)[:caching_implementation_data_enabled] do now = DateTime.utc_now() - average_block_time = get_average_block_time() + average_block_time = get_average_block_time_for_implementation_refetch() fresh_time_distance = case average_block_time do 0 -> - Application.get_env(:explorer, :fallback_ttl_cached_implementation_data_of_proxy) + Application.get_env(:explorer, :proxy)[:fallback_cached_implementation_data_ttl] time -> round(time) @@ -1204,8 +1204,8 @@ defmodule Explorer.Chain.SmartContract do end end - defp get_average_block_time do - if Application.get_env(:explorer, :avg_block_time_as_ttl_cached_implementation_data_of_proxy) do + defp get_average_block_time_for_implementation_refetch do + if Application.get_env(:explorer, :proxy)[:implementation_data_ttl_via_avg_block_time] do case AverageBlockTime.average_block_time() do {:error, :disabled} -> 0 diff --git a/apps/explorer/test/explorer/chain/smart_contract_test.exs b/apps/explorer/test/explorer/chain/smart_contract_test.exs index f7c45251b0..1501d08859 100644 --- a/apps/explorer/test/explorer/chain/smart_contract_test.exs +++ b/apps/explorer/test/explorer/chain/smart_contract_test.exs @@ -15,8 +15,13 @@ defmodule Explorer.Chain.SmartContractTest do test "check proxy_contract/1 function" do smart_contract = insert(:smart_contract) - Application.put_env(:explorer, :fallback_ttl_cached_implementation_data_of_proxy, :timer.seconds(20)) - Application.put_env(:explorer, :implementation_data_fetching_timeout, :timer.seconds(20)) + proxy = + :explorer + |> Application.get_env(:proxy) + |> Keyword.replace(:fallback_cached_implementation_data_ttl, :timer.seconds(20)) + |> Keyword.replace(:implementation_data_fetching_timeout, :timer.seconds(20)) + + Application.put_env(:explorer, :proxy, proxy) refute smart_contract.implementation_fetched_at @@ -26,7 +31,12 @@ defmodule Explorer.Chain.SmartContractTest do verify!(EthereumJSONRPC.Mox) assert_implementation_never_fetched(smart_contract.address_hash) - Application.put_env(:explorer, :fallback_ttl_cached_implementation_data_of_proxy, 0) + proxy = + :explorer + |> Application.get_env(:proxy) + |> Keyword.replace(:fallback_cached_implementation_data_ttl, 0) + + Application.put_env(:explorer, :proxy, proxy) get_eip1967_implementation_error_response() refute Proxy.proxy_contract?(smart_contract) @@ -42,10 +52,22 @@ defmodule Explorer.Chain.SmartContractTest do verify!(EthereumJSONRPC.Mox) assert_implementation_address(smart_contract.address_hash) - Application.put_env(:explorer, :fallback_ttl_cached_implementation_data_of_proxy, :timer.seconds(20)) + proxy = + :explorer + |> Application.get_env(:proxy) + |> Keyword.replace(:fallback_cached_implementation_data_ttl, :timer.seconds(20)) + + Application.put_env(:explorer, :proxy, proxy) + assert Proxy.proxy_contract?(smart_contract) - Application.put_env(:explorer, :fallback_ttl_cached_implementation_data_of_proxy, 0) + proxy = + :explorer + |> Application.get_env(:proxy) + |> Keyword.replace(:fallback_cached_implementation_data_ttl, 0) + + Application.put_env(:explorer, :proxy, proxy) + get_eip1967_implementation_non_zero_address() assert Proxy.proxy_contract?(smart_contract) verify!(EthereumJSONRPC.Mox) @@ -59,8 +81,13 @@ defmodule Explorer.Chain.SmartContractTest do smart_contract = insert(:smart_contract) implementation_smart_contract = insert(:smart_contract, name: "proxy") - Application.put_env(:explorer, :fallback_ttl_cached_implementation_data_of_proxy, :timer.seconds(20)) - Application.put_env(:explorer, :implementation_data_fetching_timeout, :timer.seconds(20)) + proxy = + :explorer + |> Application.get_env(:proxy) + |> Keyword.replace(:fallback_cached_implementation_data_ttl, :timer.seconds(20)) + |> Keyword.replace(:implementation_data_fetching_timeout, :timer.seconds(20)) + + Application.put_env(:explorer, :proxy, proxy) refute smart_contract.implementation_fetched_at @@ -71,7 +98,12 @@ defmodule Explorer.Chain.SmartContractTest do assert_implementation_never_fetched(smart_contract.address_hash) # extract proxy info from db - Application.put_env(:explorer, :fallback_ttl_cached_implementation_data_of_proxy, 0) + proxy = + :explorer + |> Application.get_env(:proxy) + |> Keyword.replace(:fallback_cached_implementation_data_ttl, 0) + + Application.put_env(:explorer, :proxy, proxy) string_implementation_address_hash = to_string(implementation_smart_contract.address_hash) @@ -116,7 +148,12 @@ defmodule Explorer.Chain.SmartContractTest do contract_1 = SmartContract.address_hash_to_smart_contract(smart_contract.address_hash) - Application.put_env(:explorer, :fallback_ttl_cached_implementation_data_of_proxy, :timer.seconds(20)) + proxy = + :explorer + |> Application.get_env(:proxy) + |> Keyword.replace(:fallback_cached_implementation_data_ttl, :timer.seconds(20)) + + Application.put_env(:explorer, :proxy, proxy) assert {^string_implementation_address_hash, "proxy"} = SmartContract.get_implementation_address_hash(smart_contract) @@ -126,7 +163,12 @@ defmodule Explorer.Chain.SmartContractTest do assert contract_1.implementation_fetched_at == contract_2.implementation_fetched_at && contract_1.updated_at == contract_2.updated_at - Application.put_env(:explorer, :fallback_ttl_cached_implementation_data_of_proxy, 0) + proxy = + :explorer + |> Application.get_env(:proxy) + |> Keyword.replace(:fallback_cached_implementation_data_ttl, 0) + + Application.put_env(:explorer, :proxy, proxy) get_eip1967_implementation_zero_addresses() assert {^string_implementation_address_hash, "proxy"} = @@ -147,8 +189,13 @@ defmodule Explorer.Chain.SmartContractTest do twin = SmartContract.address_hash_to_smart_contract(another_address.hash) implementation_smart_contract = insert(:smart_contract, name: "proxy") - Application.put_env(:explorer, :fallback_ttl_cached_implementation_data_of_proxy, :timer.seconds(20)) - Application.put_env(:explorer, :implementation_data_fetching_timeout, :timer.seconds(20)) + proxy = + :explorer + |> Application.get_env(:proxy) + |> Keyword.replace(:fallback_cached_implementation_data_ttl, :timer.seconds(20)) + |> Keyword.replace(:implementation_data_fetching_timeout, :timer.seconds(20)) + + Application.put_env(:explorer, :proxy, proxy) # fetch nil implementation get_eip1967_implementation_zero_addresses() @@ -184,8 +231,13 @@ defmodule Explorer.Chain.SmartContractTest do implementation_smart_contract = insert(:smart_contract, name: "proxy") - Application.put_env(:explorer, :fallback_ttl_cached_implementation_data_of_proxy, :timer.seconds(20)) - Application.put_env(:explorer, :implementation_data_fetching_timeout, :timer.seconds(20)) + proxy = + :explorer + |> Application.get_env(:proxy) + |> Keyword.replace(:fallback_cached_implementation_data_ttl, :timer.seconds(20)) + |> Keyword.replace(:implementation_data_fetching_timeout, :timer.seconds(20)) + + Application.put_env(:explorer, :proxy, proxy) # fetch nil implementation get_eip1967_implementation_zero_addresses() @@ -231,8 +283,13 @@ defmodule Explorer.Chain.SmartContractTest do implementation_smart_contract = insert(:smart_contract, name: "proxy") - Application.put_env(:explorer, :fallback_ttl_cached_implementation_data_of_proxy, :timer.seconds(20)) - Application.put_env(:explorer, :implementation_data_fetching_timeout, :timer.seconds(20)) + proxy = + :explorer + |> Application.get_env(:proxy) + |> Keyword.replace(:fallback_cached_implementation_data_ttl, :timer.seconds(20)) + |> Keyword.replace(:implementation_data_fetching_timeout, :timer.seconds(20)) + + Application.put_env(:explorer, :proxy, proxy) # fetch nil implementation get_eip1967_implementation_zero_addresses() diff --git a/config/runtime.exs b/config/runtime.exs index 5b7b097170..c81ceeafbb 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -203,15 +203,18 @@ config :explorer, do: Explorer.Chain.Events.DBSender, else: Explorer.Chain.Events.SimpleSender ), - enable_caching_implementation_data_of_proxy: true, - avg_block_time_as_ttl_cached_implementation_data_of_proxy: true, - fallback_ttl_cached_implementation_data_of_proxy: :timer.seconds(4), - implementation_data_fetching_timeout: :timer.seconds(2), restricted_list: System.get_env("RESTRICTED_LIST"), restricted_list_key: System.get_env("RESTRICTED_LIST_KEY"), checksum_function: checksum_function && String.to_atom(checksum_function), elasticity_multiplier: ConfigHelper.parse_integer_env_var("EIP_1559_ELASTICITY_MULTIPLIER", 2) +config :explorer, :proxy, + caching_implementation_data_enabled: true, + implementation_data_ttl_via_avg_block_time: + ConfigHelper.parse_bool_env_var("CONTRACT_PROXY_IMPLEMENTATION_TTL_VIA_AVG_BLOCK_TIME", "true"), + fallback_cached_implementation_data_ttl: :timer.seconds(4), + implementation_data_fetching_timeout: :timer.seconds(2) + config :explorer, Explorer.Chain.Events.Listener, enabled: if(disable_webapp? && disable_indexer?,