Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/blockscout/blockscout int…
Browse files Browse the repository at this point in the history
…o sync-11-25-24
  • Loading branch information
pustovalov committed Nov 27, 2024
2 parents 0e47b46 + cacbf60 commit 74db7c0
Show file tree
Hide file tree
Showing 20 changed files with 193 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@
<%= if session && !session[:email_verified] do %>
<p class="alert alert-warning" role="alert" style="margin-bottom: 0"><%= gettext("Please confirm your email address to use the My Account feature.") %> <%= gettext("A confirmation email was sent to") %> <a href="mailto:<%= session[:email] %>"><%=session[:email] %></a> <%= gettext "on sign up. Didn’t receive?" %> <a href="/api/account/v2/email/resend" class="ajax"><%= gettext "Resend verification email" %></a>.</p>
<% else %>
<p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p>
<p class="alert alert-info" role="alert"><%= Map.get(@conn.private, :phoenix_flash) && get_flash(@conn, :info) %></p>
<% end %>
<p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
<p class="alert alert-danger" role="alert"><%= Map.get(@conn.private, :phoenix_flash) && get_flash(@conn, :error) %></p>
<main class="js-ad-dependant-pt pt-5">
<%= @inner_content %>
</main>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -768,10 +768,10 @@ defmodule BlockScoutWeb.Account.Api.V2.UserControllerTest do
)
|> Repo.preload([:token])

Decimal.div(
Decimal.mult(ctb.value, ctb.token.fiat_value),
Decimal.new(10 ** Decimal.to_integer(ctb.token.decimals))
)
ctb.value
|> Decimal.mult(ctb.token.fiat_value)
|> Decimal.div(Decimal.new(10 ** Decimal.to_integer(ctb.token.decimals)))
|> Decimal.round(16)
end

values_1 =
Expand All @@ -782,24 +782,24 @@ defmodule BlockScoutWeb.Account.Api.V2.UserControllerTest do
)
|> Repo.preload([:token])

Decimal.div(
Decimal.mult(ctb.value, ctb.token.fiat_value),
Decimal.new(10 ** Decimal.to_integer(ctb.token.decimals))
)
ctb.value
|> Decimal.mult(ctb.token.fiat_value)
|> Decimal.div(Decimal.new(10 ** Decimal.to_integer(ctb.token.decimals)))
|> Decimal.round(16)
end
|> Enum.sort(fn x1, x2 -> Decimal.compare(x1, x2) in [:gt, :eq] end)
|> Enum.take(150)

[wa2, wa1] = conn |> get("/api/account/v2/user/watchlist") |> json_response(200) |> Map.get("items")

assert wa1["tokens_fiat_value"] |> Decimal.new() |> Decimal.round(13) ==
values |> Enum.reduce(Decimal.new(0), fn x, acc -> Decimal.add(x, acc) end) |> Decimal.round(13)
assert wa1["tokens_fiat_value"] |> Decimal.new() ==
values |> Enum.reduce(Decimal.new(0), fn x, acc -> Decimal.add(x, acc) end)

assert wa1["tokens_count"] == 150
assert wa1["tokens_overflow"] == false

assert wa2["tokens_fiat_value"] |> Decimal.new() |> Decimal.round(13) ==
values_1 |> Enum.reduce(Decimal.new(0), fn x, acc -> Decimal.add(x, acc) end) |> Decimal.round(13)
assert wa2["tokens_fiat_value"] |> Decimal.new() ==
values_1 |> Enum.reduce(Decimal.new(0), fn x, acc -> Decimal.add(x, acc) end)

assert wa2["tokens_count"] == 150
assert wa2["tokens_overflow"] == true
Expand All @@ -824,10 +824,10 @@ defmodule BlockScoutWeb.Account.Api.V2.UserControllerTest do
)
|> Repo.preload([:token])

Decimal.div(
Decimal.mult(ctb.value, ctb.token.fiat_value),
Decimal.new(10 ** Decimal.to_integer(ctb.token.decimals))
)
ctb.value
|> Decimal.mult(ctb.token.fiat_value)
|> Decimal.div(Decimal.new(10 ** Decimal.to_integer(ctb.token.decimals)))
|> Decimal.round(16)
end

token = insert(:token, fiat_value: nil)
Expand All @@ -840,8 +840,8 @@ defmodule BlockScoutWeb.Account.Api.V2.UserControllerTest do

[wa1] = conn |> get("/api/account/v2/user/watchlist") |> json_response(200) |> Map.get("items")

assert wa1["tokens_fiat_value"] |> Decimal.new() |> Decimal.round(13) ==
values |> Enum.reduce(Decimal.new(0), fn x, acc -> Decimal.add(x, acc) end) |> Decimal.round(13)
assert wa1["tokens_fiat_value"] |> Decimal.new() ==
values |> Enum.reduce(Decimal.new(0), fn x, acc -> Decimal.add(x, acc) end)

assert wa1["tokens_count"] == 150
assert wa1["tokens_overflow"] == false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,19 @@ defmodule BlockScoutWeb.API.RPC.EthControllerTest do
topic
end

test "handles request without params if possible", %{conn: conn} do
assert response =
conn
|> post("/api/eth-rpc", %{
"method" => "eth_blockNumber",
"jsonrpc" => "2.0",
"id" => 0
})
|> json_response(200)

assert %{"id" => 0, "jsonrpc" => "2.0", "result" => "0x0"} == response
end

describe "eth_get_logs" do
setup do
%{
Expand Down
26 changes: 2 additions & 24 deletions apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/http.ex
Original file line number Diff line number Diff line change
Expand Up @@ -240,35 +240,13 @@ defmodule EthereumJSONRPC.HTTP do
with {:ok, method_to_url} <- Keyword.fetch(options, :method_to_url),
{:ok, method_atom} <- to_existing_atom(method),
{:ok, url_type} <- Keyword.fetch(method_to_url, method_atom) do
fallback_urls = CommonHelper.url_type_to_urls(url_type, options, :fallback)

url =
url_type
|> CommonHelper.url_type_to_urls(options)
|> EndpointAvailabilityObserver.maybe_replace_urls(fallback_urls, url_type)
|> select_single_url()

{url_type, url}
{url_type, CommonHelper.get_available_url(options, url_type)}
else
_ ->
url_type = :http

url =
url_type
|> CommonHelper.url_type_to_urls(options)
|> EndpointAvailabilityObserver.maybe_replace_urls(options[:fallback_urls], url_type)
|> select_single_url()

{url_type, url}
{:http, CommonHelper.get_available_url(options, :http)}
end
end

defp select_single_url([]), do: nil

defp select_single_url(urls) do
Enum.random(urls)
end

defp to_existing_atom(string) do
{:ok, String.to_existing_atom(string)}
rescue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ defmodule EthereumJSONRPC.Utility.CommonHelper do
Common helper functions
"""

alias EthereumJSONRPC.Utility.EndpointAvailabilityObserver

# converts duration like "5s", "2m", "1h5m" to milliseconds
@duration_regex ~r/(\d+)([smhSMH]?)/
def parse_duration(duration) do
Expand Down Expand Up @@ -30,6 +32,23 @@ defmodule EthereumJSONRPC.Utility.CommonHelper do
Keyword.put(keyword || [], nearest_path, put_in_keyword_nested(keyword[nearest_path], rest_path, value))
end

@doc """
Get available json rpc url from `json_rpc_transport_options` (or global `json_rpc_named_arguments`) of `url_type` type
based on `EthereumJSONRPC.Utility.EndpointAvailabilityObserver`.
"""
@spec get_available_url(Keyword.t() | nil, atom()) :: String.t() | nil
def get_available_url(json_rpc_transport_options \\ nil, url_type \\ :http) do
transport_options =
json_rpc_transport_options || Application.get_env(:explorer, :json_rpc_named_arguments)[:transport_options]

fallback_urls = url_type_to_urls(url_type, transport_options, :fallback)

url_type
|> url_type_to_urls(transport_options)
|> EndpointAvailabilityObserver.maybe_replace_urls(fallback_urls, url_type)
|> select_single_url()
end

@doc """
Extracts urls corresponding to `url_type` from json rpc transport options
"""
Expand All @@ -41,6 +60,12 @@ defmodule EthereumJSONRPC.Utility.CommonHelper do
json_rpc_transport_options[urls_key]
end

defp select_single_url([]), do: nil

defp select_single_url(urls) do
Enum.random(urls)
end

defp convert_to_ms(number, "s"), do: :timer.seconds(number)
defp convert_to_ms(number, "m"), do: :timer.minutes(number)
defp convert_to_ms(number, "h"), do: :timer.hours(number)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ defmodule EthereumJSONRPC.Utility.EndpointAvailabilityChecker do
Enum.reduce(unavailable_endpoints_arguments, [], fn {json_rpc_named_arguments, url_type}, acc ->
case fetch_latest_block_number(json_rpc_named_arguments) do
{:ok, _number} ->
url = json_rpc_named_arguments[:transport_options][:url]
[url] = json_rpc_named_arguments[:transport_options][:urls]

EndpointAvailabilityObserver.enable_endpoint(url, url_type, json_rpc_named_arguments)
acc
Expand Down
4 changes: 2 additions & 2 deletions apps/ethereum_jsonrpc/test/ethereum_jsonrpc/http/mox_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ defmodule EthereumJSONRPC.HTTP.MoxTest do
transport: EthereumJSONRPC.HTTP,
transport_options: [
http: EthereumJSONRPC.HTTP.Mox,
url: url(),
urls: [url()],
http_options: http_options()
],
# Which one does not matter, so pick one
Expand Down Expand Up @@ -289,7 +289,7 @@ defmodule EthereumJSONRPC.HTTP.MoxTest do
transport_options = Keyword.fetch!(json_rpc_named_arguments, :transport_options)

http = Keyword.fetch!(transport_options, :http)
url = Keyword.fetch!(transport_options, :url)
url = transport_options |> Keyword.fetch!(:urls) |> List.first()
json = Jason.encode_to_iodata!(payload)
http_options = Keyword.fetch!(transport_options, :http_options)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
defmodule EthereumJSONRPC.Utility.CommonHelperTest do
use ExUnit.Case, async: true

alias EthereumJSONRPC.Utility.{EndpointAvailabilityObserver, CommonHelper}

@options [
urls: ["url_1", "url_2"],
trace_urls: ["trace_url_1", "trace_url_2"],
eth_call_urls: ["eth_call_url_1", "eth_call_url_2"],
fallback_urls: ["fallback_url_1", "fallback_url_2"],
fallback_trace_urls: ["fallback_trace_url_1", "fallback_trace_url_2"],
fallback_eth_call_urls: ["fallback_ec_url_1", "fallback_ec_url_2"]
]

test "url_type_to_urls/3" do
assert ["url_1", "url_2"] = CommonHelper.url_type_to_urls(:http, @options)
assert ["trace_url_1", "trace_url_2"] = CommonHelper.url_type_to_urls(:trace, @options)
assert ["eth_call_url_1", "eth_call_url_2"] = CommonHelper.url_type_to_urls(:eth_call, @options)
assert ["fallback_url_1", "fallback_url_2"] = CommonHelper.url_type_to_urls(:http, @options, :fallback)
assert ["fallback_trace_url_1", "fallback_trace_url_2"] = CommonHelper.url_type_to_urls(:trace, @options, :fallback)
assert ["fallback_ec_url_1", "fallback_ec_url_2"] = CommonHelper.url_type_to_urls(:eth_call, @options, :fallback)
end

test "get_available_url/2" do
EndpointAvailabilityObserver.start_link([])

assert CommonHelper.get_available_url(@options, :http) in @options[:urls]
assert CommonHelper.get_available_url(@options, :trace) in @options[:trace_urls]
assert CommonHelper.get_available_url(@options, :eth_call) in @options[:eth_call_urls]

set_url_unavailable("url_1", :http)
set_url_unavailable("url_2", :http)

assert CommonHelper.get_available_url(@options, :http) in @options[:fallback_urls]

set_url_unavailable("trace_url_1", :trace)
set_url_unavailable("trace_url_2", :trace)

assert CommonHelper.get_available_url(@options, :trace) in @options[:fallback_trace_urls]

set_url_unavailable("eth_call_url_1", :eth_call)
set_url_unavailable("eth_call_url_2", :eth_call)

assert CommonHelper.get_available_url(@options, :eth_call) in @options[:fallback_eth_call_urls]
end

defp set_url_unavailable(url, url_type) do
Enum.each(1..3, fn _ ->
EndpointAvailabilityObserver.inc_error_count(url, [transport_options: @options], url_type)
end)
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ defmodule EthereumJSONRPC.Case.Geth.HTTPWebSocket do
transport_options: [
http: EthereumJSONRPC.HTTP.HTTPoison,
http_options: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]],
url: "https://mainnet.infura.io/8lTvJTKmHPCHazkneJsY"
urls: ["https://mainnet.infura.io/8lTvJTKmHPCHazkneJsY"]
],
variant: EthereumJSONRPC.Geth
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ defmodule EthereumJSONRPC.Case.Nethermind.HTTPWebSocket do
transport_options: [
http: EthereumJSONRPC.HTTP.HTTPoison,
http_options: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]],
url: "http://3.85.253.242:8545"
urls: ["http://3.85.253.242:8545"]
],
variant: EthereumJSONRPC.Nethermind
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ defmodule EthereumJSONRPC.HTTP.Case do
transport: EthereumJSONRPC.HTTP,
transport_options: [
http: http(),
url: url(),
urls: [url()],
http_options: http_options()
]
]
Expand Down
17 changes: 11 additions & 6 deletions apps/explorer/lib/explorer/chain/bridged_token.ex
Original file line number Diff line number Diff line change
Expand Up @@ -828,13 +828,18 @@ defmodule Explorer.Chain.BridgedToken do
end

defp update_transport_options_set_foreign_json_rpc(transport_options, foreign_json_rpc) do
Keyword.get_and_update(transport_options, :method_to_url, fn method_to_url ->
{_, updated_method_to_url} =
Keyword.get_and_update(method_to_url, :eth_call, fn eth_call ->
{eth_call, foreign_json_rpc}
end)
{_, updated_transport_options} =
Keyword.get_and_update(transport_options, :method_to_url, fn method_to_url ->
{_, updated_method_to_url} =
Keyword.get_and_update(method_to_url, :eth_call, fn eth_call ->
{eth_call, :eth_call}
end)

{method_to_url, updated_method_to_url}
end)

{method_to_url, updated_method_to_url}
Keyword.get_and_update(updated_transport_options, :eth_call_urls, fn eth_call_urls ->
{eth_call_urls, [foreign_json_rpc]}
end)
end

Expand Down
6 changes: 5 additions & 1 deletion apps/explorer/lib/explorer/eth_rpc.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1204,8 +1204,12 @@ defmodule Explorer.EthRPC do
{:error, "Invalid params. Params must be a list."}
end

defp do_eth_request(%{"jsonrpc" => jsonrpc, "method" => method}) do
do_eth_request(%{"jsonrpc" => jsonrpc, "method" => method, "params" => []})
end

defp do_eth_request(_) do
{:error, "Method, params, and jsonrpc, are all required parameters."}
{:error, "Method, and jsonrpc are required parameters."}
end

defp get_action(action) do
Expand Down
2 changes: 1 addition & 1 deletion apps/explorer/lib/explorer/etherscan/logs.ex
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ defmodule Explorer.Etherscan.Logs do
defp page_logs(query, %{block_number: block_number, log_index: log_index}) do
from(
data in query,
where: data.index > ^log_index and data.block_number >= ^block_number
where: {data.block_number, data.index} > {^block_number, ^log_index}
)
end

Expand Down
3 changes: 2 additions & 1 deletion apps/explorer/lib/explorer/smart_contract/stylus/verifier.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ defmodule Explorer.SmartContract.Stylus.Verifier do
- Compares the resulting bytecode against the deployed contract bytecode
- Returns verification details including ABI and contract metadata
"""
alias EthereumJSONRPC.Utility.CommonHelper
alias Explorer.Chain.{Hash, SmartContract}
alias Explorer.SmartContract.StylusVerifierInterface

Expand Down Expand Up @@ -68,7 +69,7 @@ defmodule Explorer.SmartContract.Stylus.Verifier do
{:ok, map()} | {:error, any()}
defp evaluate_authenticity_inner(true, address_hash, params) do
transaction_hash = fetch_data_for_stylus_verification(address_hash)
rpc_endpoint = Application.get_env(:explorer, :json_rpc_named_arguments)[:transport_options][:urls] |> List.first()
rpc_endpoint = CommonHelper.get_available_url()

params
|> Map.take(["cargo_stylus_version", "repository_url", "commit", "path_prefix"])
Expand Down
10 changes: 10 additions & 0 deletions apps/explorer/lib/explorer/third_party_integrations/auth0.ex
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,16 @@ defmodule Explorer.ThirdPartyIntegrations.Auth0 do
}} ->
{:error, "Wrong verification code."}

{:error,
%OAuth2.Response{
status_code: 403,
body: %{
"error" => "invalid_grant",
"error_description" => "You've reached the maximum number of attempts. Please try to login again."
}
}} ->
{:error, "Max attempts reached. Please resend code."}

other ->
Logger.error("Error while confirming otp: #{inspect(other)}")

Expand Down
Loading

0 comments on commit 74db7c0

Please sign in to comment.