diff --git a/CHANGELOG.md b/CHANGELOG.md index 25082d68b2..bf819c2ba9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Features +- [#8673](https://github.com/blockscout/blockscout/pull/8673) - Add a window for balances fetching from non-archive node + ### Fixes ### Chore diff --git a/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex index 24579b642a..3b67a4dd7f 100644 --- a/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex @@ -189,9 +189,13 @@ defmodule EthereumJSONRPC do when is_list(params_list) and is_list(json_rpc_named_arguments) do filtered_params = if Application.get_env(:ethereum_jsonrpc, :disable_archive_balances?) do + {:ok, max_block_number} = fetch_block_number_by_tag("latest", json_rpc_named_arguments) + window = Application.get_env(:ethereum_jsonrpc, :archive_balances_window) + params_list |> Enum.filter(fn %{block_quantity: "latest"} -> true + %{block_quantity: block_quantity} -> quantity_to_integer(block_quantity) > max_block_number - window _ -> false end) else diff --git a/apps/ethereum_jsonrpc/test/ethereum_jsonrpc_test.exs b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc_test.exs index 7299d48478..0409dc1c64 100644 --- a/apps/ethereum_jsonrpc/test/ethereum_jsonrpc_test.exs +++ b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc_test.exs @@ -994,26 +994,72 @@ defmodule EthereumJSONRPCSyncTest do on_exit(fn -> Application.put_all_env([{:indexer, initial_env}]) end) end - test "ignores all request with block_quantity != latest when env ETHEREUM_JSONRPC_DISABLE_ARCHIVE_BALANCES is true", + test "ignores all request with block_quantity != latest or lower than window when env ETHEREUM_JSONRPC_DISABLE_ARCHIVE_BALANCES is true", %{ json_rpc_named_arguments: json_rpc_named_arguments } do hash = "0x8bf38d4764929064f2d4d3a56520a76ab3df415b" expected_fetched_balance = 1 - expect(EthereumJSONRPC.Mox, :json_rpc, 1, fn [ - %{ - id: 0, - jsonrpc: "2.0", - method: "eth_getBalance", - params: [^hash, "latest"] - } - ], - _options -> - {:ok, [%{id: 0, result: EthereumJSONRPC.integer_to_quantity(expected_fetched_balance)}]} + expect(EthereumJSONRPC.Mox, :json_rpc, 2, fn + [ + %{ + id: 0, + jsonrpc: "2.0", + method: "eth_getBalance", + params: [^hash, "0x4"] + }, + %{ + id: 1, + jsonrpc: "2.0", + method: "eth_getBalance", + params: [^hash, "latest"] + } + ], + _options -> + {:ok, + [ + %{id: 0, result: EthereumJSONRPC.integer_to_quantity(expected_fetched_balance)}, + %{id: 1, result: EthereumJSONRPC.integer_to_quantity(expected_fetched_balance)} + ]} + + [ + %{ + id: id, + method: "eth_getBlockByNumber" + } + ], + _options -> + {:ok, + [ + %{ + id: id, + result: %{ + "difficulty" => "0x0", + "gasLimit" => "0x0", + "gasUsed" => "0x0", + "hash" => "0x29c850324e357f3c0c836d79860c5af55f7b651e5d7ee253c1af1b14908af49c", + "extraData" => "0x0", + "logsBloom" => "0x0", + "miner" => "0x0", + "number" => "0x4", + "parentHash" => "0x0", + "receiptsRoot" => "0x0", + "size" => "0x0", + "sha3Uncles" => "0x0", + "stateRoot" => "0x0", + "timestamp" => "0x0", + "totalDifficulty" => "0x0", + "transactions" => ["0xa2e81bb56b55ba3dab2daf76501b50dfaad240cccb905dbf89d65c7a84a4a48e"], + "transactionsRoot" => "0x0", + "uncles" => [] + } + } + ]} end) Application.put_env(:ethereum_jsonrpc, :disable_archive_balances?, "true") + Application.put_env(:ethereum_jsonrpc, :archive_balances_window, 1) assert EthereumJSONRPC.fetch_balances( [ @@ -1032,6 +1078,11 @@ defmodule EthereumJSONRPCSyncTest do address_hash: hash, block_number: nil, value: expected_fetched_balance + }, + %{ + address_hash: hash, + block_number: 4, + value: expected_fetched_balance } ] }} diff --git a/config/runtime.exs b/config/runtime.exs index 2133d2ee1a..8af8e6f70f 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -150,7 +150,8 @@ config :ueberauth, Ueberauth, logout_url: "https://#{System.get_env("ACCOUNT_AUT config :ethereum_jsonrpc, rpc_transport: if(System.get_env("ETHEREUM_JSONRPC_TRANSPORT", "http") == "http", do: :http, else: :ipc), ipc_path: System.get_env("IPC_PATH"), - disable_archive_balances?: ConfigHelper.parse_bool_env_var("ETHEREUM_JSONRPC_DISABLE_ARCHIVE_BALANCES") + disable_archive_balances?: ConfigHelper.parse_bool_env_var("ETHEREUM_JSONRPC_DISABLE_ARCHIVE_BALANCES"), + archive_balances_window: ConfigHelper.parse_integer_env_var("ETHEREUM_JSONRPC_ARCHIVE_BALANCES_WINDOW", 200) config :ethereum_jsonrpc, EthereumJSONRPC.HTTP, headers: diff --git a/docker-compose/envs/common-blockscout.env b/docker-compose/envs/common-blockscout.env index 08ae57c7a9..d2bbf877ff 100644 --- a/docker-compose/envs/common-blockscout.env +++ b/docker-compose/envs/common-blockscout.env @@ -13,6 +13,7 @@ LOGO=/images/blockscout_logo.svg # ETHEREUM_JSONRPC_WS_URL= ETHEREUM_JSONRPC_TRANSPORT=http ETHEREUM_JSONRPC_DISABLE_ARCHIVE_BALANCES=false +#ETHEREUM_JSONRPC_ARCHIVE_BALANCES_WINDOW=200 # ETHEREUM_JSONRPC_HTTP_HEADERS= # ETHEREUM_JSONRPC_WAIT_PER_TIMEOUT= IPC_PATH=