<%= render BlockScoutWeb.TransactionView, "_link.html", transaction_hash: @transaction.hash %>
- <%= render BlockScoutWeb.AddressView, "_link.html", address: @transaction.from_address, contract: BlockScoutWeb.AddressView.contract?(@transaction.from_address) %>
+ <%= render BlockScoutWeb.AddressView, "_link.html", address: @transaction.from_address, contract: BlockScoutWeb.AddressView.contract?(@transaction.from_address), use_custom_tooltip: false %>
→
<%= if @transaction.to_address_hash do %>
- <%= render BlockScoutWeb.AddressView, "_link.html", address: @transaction.to_address, contract: BlockScoutWeb.AddressView.contract?(@transaction.to_address) %>
+ <%= render BlockScoutWeb.AddressView, "_link.html", address: @transaction.to_address, contract: BlockScoutWeb.AddressView.contract?(@transaction.to_address), use_custom_tooltip: false %>
<% else %>
<%= gettext("Contract Address Pending") %>
<% end %>
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/transaction_token_transfer/_token_transfer.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/transaction_token_transfer/_token_transfer.html.eex
index 18d8bebed4..1bc1b34dc7 100644
--- a/apps/block_scout_web/lib/block_scout_web/templates/transaction_token_transfer/_token_transfer.html.eex
+++ b/apps/block_scout_web/lib/block_scout_web/templates/transaction_token_transfer/_token_transfer.html.eex
@@ -7,9 +7,9 @@
<%= render BlockScoutWeb.TransactionView, "_link.html", transaction_hash: @token_transfer.transaction_hash %>
- <%= render BlockScoutWeb.AddressView, "_link.html", address: @token_transfer.from_address, contract: BlockScoutWeb.AddressView.contract?(@token_transfer.from_address) %>
+ <%= render BlockScoutWeb.AddressView, "_link.html", address: @token_transfer.from_address, contract: BlockScoutWeb.AddressView.contract?(@token_transfer.from_address), use_custom_tooltip: false %>
→
- <%= render BlockScoutWeb.AddressView, "_link.html", address: @token_transfer.to_address, contract: BlockScoutWeb.AddressView.contract?(@token_transfer.to_address) %>
+ <%= render BlockScoutWeb.AddressView, "_link.html", address: @token_transfer.to_address, contract: BlockScoutWeb.AddressView.contract?(@token_transfer.to_address), use_custom_tooltip: false %>
diff --git a/apps/block_scout_web/lib/block_scout_web/views/address_view.ex b/apps/block_scout_web/lib/block_scout_web/views/address_view.ex
index 15405beecb..4e86dc00df 100644
--- a/apps/block_scout_web/lib/block_scout_web/views/address_view.ex
+++ b/apps/block_scout_web/lib/block_scout_web/views/address_view.ex
@@ -271,7 +271,8 @@ defmodule BlockScoutWeb.AddressView do
partial: "_responsive_hash.html",
address: current_address,
contract: contract?,
- truncate: truncate
+ truncate: truncate,
+ use_custom_tooltip: false
]
end
@@ -281,7 +282,8 @@ defmodule BlockScoutWeb.AddressView do
partial: "_link.html",
address: address,
contract: contract?,
- truncate: truncate
+ truncate: truncate,
+ use_custom_tooltip: false
]
end
diff --git a/apps/block_scout_web/lib/block_scout_web/views/error_422.ex b/apps/block_scout_web/lib/block_scout_web/views/error_422.ex
new file mode 100644
index 0000000000..b813dc9383
--- /dev/null
+++ b/apps/block_scout_web/lib/block_scout_web/views/error_422.ex
@@ -0,0 +1,5 @@
+defmodule BlockScoutWeb.Error422View do
+ use BlockScoutWeb, :view
+
+ @dialyzer :no_match
+end
diff --git a/apps/block_scout_web/lib/block_scout_web/views/layout_view.ex b/apps/block_scout_web/lib/block_scout_web/views/layout_view.ex
index b2d80f28f9..51763750d5 100644
--- a/apps/block_scout_web/lib/block_scout_web/views/layout_view.ex
+++ b/apps/block_scout_web/lib/block_scout_web/views/layout_view.ex
@@ -19,45 +19,16 @@ defmodule BlockScoutWeb.LayoutView do
title: "xDai Chain",
url: "https://blockscout.com/poa/dai"
},
- %{
- title: "Ethereum Mainnet",
- url: "https://blockscout.com/eth/mainnet"
- },
%{
title: "Kovan Testnet",
url: "https://blockscout.com/eth/kovan",
test_net?: true
},
- %{
- title: "Ropsten Testnet",
- url: "https://blockscout.com/eth/ropsten",
- test_net?: true
- },
- %{
- title: "Goerli Testnet",
- url: "https://blockscout.com/eth/goerli",
- test_net?: true
- },
- %{
- title: "Rinkeby Testnet",
- url: "https://blockscout.com/eth/rinkeby",
- test_net?: true
- },
%{
title: "Ethereum Classic",
url: "https://blockscout.com/etc/mainnet",
other?: true
},
- %{
- title: "Aerum Mainnet",
- url: "https://blockscout.com/aerum/mainnet",
- other?: true
- },
- %{
- title: "Callisto Mainnet",
- url: "https://blockscout.com/callisto/mainnet",
- other?: true
- },
%{
title: "RSK Mainnet",
url: "https://blockscout.com/rsk/mainnet",
diff --git a/apps/block_scout_web/priv/gettext/default.pot b/apps/block_scout_web/priv/gettext/default.pot
index 4864cce5c7..71e0ebedab 100644
--- a/apps/block_scout_web/priv/gettext/default.pot
+++ b/apps/block_scout_web/priv/gettext/default.pot
@@ -186,7 +186,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/block/_link.html.eex:2
#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:28
-#: lib/block_scout_web/templates/tokens/transfer/_token_transfer.html.eex:46
+#: lib/block_scout_web/templates/tokens/transfer/_token_transfer.html.eex:48
msgid "Block #%{number}"
msgstr ""
@@ -251,7 +251,7 @@ msgstr ""
#: lib/block_scout_web/templates/address/_tabs.html.eex:32
#: lib/block_scout_web/templates/address/overview.html.eex:97
#: lib/block_scout_web/templates/address_validation/index.html.eex:13
-#: lib/block_scout_web/views/address_view.ex:311
+#: lib/block_scout_web/views/address_view.ex:313
msgid "Blocks Validated"
msgstr ""
@@ -305,13 +305,13 @@ msgstr ""
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:187
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:126
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:149
-#: lib/block_scout_web/views/address_view.ex:307
+#: lib/block_scout_web/views/address_view.ex:309
msgid "Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:20
-#: lib/block_scout_web/views/address_view.ex:310
+#: lib/block_scout_web/views/address_view.ex:312
msgid "Coin Balance History"
msgstr ""
@@ -526,7 +526,7 @@ msgid "Decoded"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/views/address_view.ex:308
+#: lib/block_scout_web/views/address_view.ex:310
msgid "Decompiled Code"
msgstr ""
@@ -546,16 +546,16 @@ msgid "Decompiler version"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/block/_tile.html.eex:56
+#: lib/block_scout_web/templates/block/_tile.html.eex:57
#: lib/block_scout_web/templates/block/overview.html.eex:108
-#: lib/block_scout_web/templates/block/overview.html.eex:158
+#: lib/block_scout_web/templates/block/overview.html.eex:159
msgid "Gas Limit"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/block/_tile.html.eex:61
+#: lib/block_scout_web/templates/block/_tile.html.eex:62
#: lib/block_scout_web/templates/block/overview.html.eex:101
-#: lib/block_scout_web/templates/block/overview.html.eex:152
+#: lib/block_scout_web/templates/block/overview.html.eex:153
msgid "Gas Used"
msgstr ""
@@ -934,7 +934,7 @@ msgstr ""
#: lib/block_scout_web/templates/address/_tabs.html.eex:8
#: lib/block_scout_web/templates/address_token/index.html.eex:8
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:9
-#: lib/block_scout_web/views/address_view.ex:304
+#: lib/block_scout_web/views/address_view.ex:306
msgid "Tokens"
msgstr ""
@@ -987,7 +987,7 @@ msgstr ""
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:19
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:11
#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:6
-#: lib/block_scout_web/views/address_view.ex:306
+#: lib/block_scout_web/views/address_view.ex:308
#: lib/block_scout_web/views/transaction_view.ex:314
msgid "Internal Transactions"
msgstr ""
@@ -1076,7 +1076,7 @@ msgstr ""
#: lib/block_scout_web/templates/address_logs/index.html.eex:8
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:17
#: lib/block_scout_web/templates/transaction_log/index.html.eex:8
-#: lib/block_scout_web/views/address_view.ex:312
+#: lib/block_scout_web/views/address_view.ex:314
#: lib/block_scout_web/views/transaction_view.ex:315
msgid "Logs"
msgstr ""
@@ -1267,7 +1267,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:58
#: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:25
-#: lib/block_scout_web/views/address_view.ex:309
+#: lib/block_scout_web/views/address_view.ex:311
#: lib/block_scout_web/views/tokens/overview_view.ex:37
msgid "Read Contract"
msgstr ""
@@ -1301,8 +1301,8 @@ msgid "Responses"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/block/_tile.html.eex:47
-#: lib/block_scout_web/templates/chain/_block.html.eex:23
+#: lib/block_scout_web/templates/block/_tile.html.eex:48
+#: lib/block_scout_web/templates/chain/_block.html.eex:24
#: lib/block_scout_web/views/internal_transaction_view.ex:28
msgid "Reward"
msgstr ""
@@ -1366,7 +1366,7 @@ msgid "Show Validator Info"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/block/overview.html.eex:145
+#: lib/block_scout_web/templates/block/overview.html.eex:146
msgid "Block Rewards"
msgstr ""
@@ -1559,7 +1559,7 @@ msgstr ""
#: lib/block_scout_web/templates/block_transaction/index.html.eex:18
#: lib/block_scout_web/templates/chain/show.html.eex:145
#: lib/block_scout_web/templates/layout/_topnav.html.eex:64
-#: lib/block_scout_web/views/address_view.ex:305
+#: lib/block_scout_web/views/address_view.ex:307
msgid "Transactions"
msgstr ""
diff --git a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
index 4864cce5c7..71e0ebedab 100644
--- a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
+++ b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
@@ -186,7 +186,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/block/_link.html.eex:2
#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:28
-#: lib/block_scout_web/templates/tokens/transfer/_token_transfer.html.eex:46
+#: lib/block_scout_web/templates/tokens/transfer/_token_transfer.html.eex:48
msgid "Block #%{number}"
msgstr ""
@@ -251,7 +251,7 @@ msgstr ""
#: lib/block_scout_web/templates/address/_tabs.html.eex:32
#: lib/block_scout_web/templates/address/overview.html.eex:97
#: lib/block_scout_web/templates/address_validation/index.html.eex:13
-#: lib/block_scout_web/views/address_view.ex:311
+#: lib/block_scout_web/views/address_view.ex:313
msgid "Blocks Validated"
msgstr ""
@@ -305,13 +305,13 @@ msgstr ""
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:187
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:126
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:149
-#: lib/block_scout_web/views/address_view.ex:307
+#: lib/block_scout_web/views/address_view.ex:309
msgid "Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:20
-#: lib/block_scout_web/views/address_view.ex:310
+#: lib/block_scout_web/views/address_view.ex:312
msgid "Coin Balance History"
msgstr ""
@@ -526,7 +526,7 @@ msgid "Decoded"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/views/address_view.ex:308
+#: lib/block_scout_web/views/address_view.ex:310
msgid "Decompiled Code"
msgstr ""
@@ -546,16 +546,16 @@ msgid "Decompiler version"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/block/_tile.html.eex:56
+#: lib/block_scout_web/templates/block/_tile.html.eex:57
#: lib/block_scout_web/templates/block/overview.html.eex:108
-#: lib/block_scout_web/templates/block/overview.html.eex:158
+#: lib/block_scout_web/templates/block/overview.html.eex:159
msgid "Gas Limit"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/block/_tile.html.eex:61
+#: lib/block_scout_web/templates/block/_tile.html.eex:62
#: lib/block_scout_web/templates/block/overview.html.eex:101
-#: lib/block_scout_web/templates/block/overview.html.eex:152
+#: lib/block_scout_web/templates/block/overview.html.eex:153
msgid "Gas Used"
msgstr ""
@@ -934,7 +934,7 @@ msgstr ""
#: lib/block_scout_web/templates/address/_tabs.html.eex:8
#: lib/block_scout_web/templates/address_token/index.html.eex:8
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:9
-#: lib/block_scout_web/views/address_view.ex:304
+#: lib/block_scout_web/views/address_view.ex:306
msgid "Tokens"
msgstr ""
@@ -987,7 +987,7 @@ msgstr ""
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:19
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:11
#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:6
-#: lib/block_scout_web/views/address_view.ex:306
+#: lib/block_scout_web/views/address_view.ex:308
#: lib/block_scout_web/views/transaction_view.ex:314
msgid "Internal Transactions"
msgstr ""
@@ -1076,7 +1076,7 @@ msgstr ""
#: lib/block_scout_web/templates/address_logs/index.html.eex:8
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:17
#: lib/block_scout_web/templates/transaction_log/index.html.eex:8
-#: lib/block_scout_web/views/address_view.ex:312
+#: lib/block_scout_web/views/address_view.ex:314
#: lib/block_scout_web/views/transaction_view.ex:315
msgid "Logs"
msgstr ""
@@ -1267,7 +1267,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:58
#: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:25
-#: lib/block_scout_web/views/address_view.ex:309
+#: lib/block_scout_web/views/address_view.ex:311
#: lib/block_scout_web/views/tokens/overview_view.ex:37
msgid "Read Contract"
msgstr ""
@@ -1301,8 +1301,8 @@ msgid "Responses"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/block/_tile.html.eex:47
-#: lib/block_scout_web/templates/chain/_block.html.eex:23
+#: lib/block_scout_web/templates/block/_tile.html.eex:48
+#: lib/block_scout_web/templates/chain/_block.html.eex:24
#: lib/block_scout_web/views/internal_transaction_view.ex:28
msgid "Reward"
msgstr ""
@@ -1366,7 +1366,7 @@ msgid "Show Validator Info"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/block/overview.html.eex:145
+#: lib/block_scout_web/templates/block/overview.html.eex:146
msgid "Block Rewards"
msgstr ""
@@ -1559,7 +1559,7 @@ msgstr ""
#: lib/block_scout_web/templates/block_transaction/index.html.eex:18
#: lib/block_scout_web/templates/chain/show.html.eex:145
#: lib/block_scout_web/templates/layout/_topnav.html.eex:64
-#: lib/block_scout_web/views/address_view.ex:305
+#: lib/block_scout_web/views/address_view.ex:307
msgid "Transactions"
msgstr ""
diff --git a/apps/block_scout_web/test/block_scout_web/views/address_view_test.exs b/apps/block_scout_web/test/block_scout_web/views/address_view_test.exs
index 6522f20459..97544754ec 100644
--- a/apps/block_scout_web/test/block_scout_web/views/address_view_test.exs
+++ b/apps/block_scout_web/test/block_scout_web/views/address_view_test.exs
@@ -32,7 +32,8 @@ defmodule BlockScoutWeb.AddressViewTest do
partial: "_link.html",
address: ^to_address,
contract: false,
- truncate: true
+ truncate: true,
+ use_custom_tooltip: false
] = AddressView.address_partial_selector(transaction, :to, nil, true)
end
@@ -44,7 +45,8 @@ defmodule BlockScoutWeb.AddressViewTest do
partial: "_link.html",
address: ^to_address,
contract: false,
- truncate: false
+ truncate: false,
+ use_custom_tooltip: false
] = AddressView.address_partial_selector(transaction, :to, nil)
end
@@ -56,7 +58,8 @@ defmodule BlockScoutWeb.AddressViewTest do
partial: "_link.html",
address: ^to_address,
contract: false,
- truncate: false
+ truncate: false,
+ use_custom_tooltip: false
] = AddressView.address_partial_selector(transaction, :to, nil)
end
@@ -68,7 +71,8 @@ defmodule BlockScoutWeb.AddressViewTest do
partial: "_responsive_hash.html",
address: ^to_address,
contract: false,
- truncate: false
+ truncate: false,
+ use_custom_tooltip: false
] = AddressView.address_partial_selector(transaction, :to, transaction.to_address)
end
@@ -81,7 +85,8 @@ defmodule BlockScoutWeb.AddressViewTest do
partial: "_link.html",
address: ^contract_address,
contract: true,
- truncate: false
+ truncate: false,
+ use_custom_tooltip: false
] = AddressView.address_partial_selector(transaction, :to, transaction.to_address)
end
@@ -94,7 +99,8 @@ defmodule BlockScoutWeb.AddressViewTest do
partial: "_responsive_hash.html",
address: ^contract_address,
contract: true,
- truncate: false
+ truncate: false,
+ use_custom_tooltip: false
] = AddressView.address_partial_selector(transaction, :to, contract_address)
end
@@ -106,7 +112,8 @@ defmodule BlockScoutWeb.AddressViewTest do
partial: "_link.html",
address: ^to_address,
contract: false,
- truncate: false
+ truncate: false,
+ use_custom_tooltip: false
] = AddressView.address_partial_selector(transaction, :to, nil)
end
@@ -118,7 +125,8 @@ defmodule BlockScoutWeb.AddressViewTest do
partial: "_responsive_hash.html",
address: ^from_address,
contract: false,
- truncate: false
+ truncate: false,
+ use_custom_tooltip: false
] = AddressView.address_partial_selector(transaction, :from, transaction.from_address)
end
end
diff --git a/apps/ethereum_jsonrpc/config/config.exs b/apps/ethereum_jsonrpc/config/config.exs
index aa5ec08b49..f7cf34afc9 100644
--- a/apps/ethereum_jsonrpc/config/config.exs
+++ b/apps/ethereum_jsonrpc/config/config.exs
@@ -9,6 +9,10 @@ config :ethereum_jsonrpc, EthereumJSONRPC.RequestCoordinator,
wait_per_timeout: :timer.seconds(20),
max_jitter: :timer.seconds(2)
+config :ethereum_jsonrpc,
+ rpc_transport: if(System.get_env("ETHEREUM_JSONRPC_JSON_RPC_TRANSPORT", "http") == "http", do: :http, else: :ipc),
+ ipc_path: System.get_env("IPC_PATH")
+
# Add this configuration to add global RPC request throttling.
# throttle_rate_limit: 250,
# throttle_rolling_window_opts: [
diff --git a/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/application.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/application.ex
index 8c902e8f26..6c9915f1cd 100644
--- a/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/application.ex
+++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/application.ex
@@ -5,7 +5,7 @@ defmodule EthereumJSONRPC.Application do
use Application
- alias EthereumJSONRPC.{RequestCoordinator, RollingWindow}
+ alias EthereumJSONRPC.{IPC, RequestCoordinator, RollingWindow}
@impl Application
def start(_type, _args) do
@@ -18,6 +18,7 @@ defmodule EthereumJSONRPC.Application do
Supervisor.child_spec({RollingWindow, [rolling_window_opts]}, id: RollingWindow.ErrorThrottle)
]
|> add_throttle_rolling_window(config)
+ |> add_ipc_client()
|> Supervisor.start_link(strategy: :one_for_one, name: EthereumJSONRPC.Supervisor)
end
@@ -37,4 +38,26 @@ defmodule EthereumJSONRPC.Application do
children
end
end
+
+ defp add_ipc_client(children) do
+ case Application.get_env(:ethereum_jsonrpc, :rpc_transport) do
+ :ipc ->
+ [
+ :poolboy.child_spec(:worker, poolboy_config(), path: Application.get_env(:ethereum_jsonrpc, :ipc_path))
+ | children
+ ]
+
+ _ ->
+ children
+ end
+ end
+
+ defp poolboy_config do
+ [
+ {:name, {:local, :ipc_worker}},
+ {:worker_module, IPC},
+ {:size, 10},
+ {:max_overflow, 5}
+ ]
+ end
end
diff --git a/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/http.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/http.ex
index 6d9f946554..8e2c47dd0a 100644
--- a/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/http.ex
+++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/http.ex
@@ -132,7 +132,7 @@ defmodule EthereumJSONRPC.HTTP do
# restrict response to only those fields supported by the JSON-RPC 2.0 standard, which means that level of keys is
# validated, so we can indicate that with switch to atom keys.
- defp standardize_response(%{"jsonrpc" => "2.0" = jsonrpc, "id" => id} = unstandardized) do
+ def standardize_response(%{"jsonrpc" => "2.0" = jsonrpc, "id" => id} = unstandardized) do
# Nethermind return string ids
id = quantity_to_integer(id)
@@ -155,8 +155,8 @@ defmodule EthereumJSONRPC.HTTP do
# restrict error to only those fields supported by the JSON-RPC 2.0 standard, which means that level of keys is
# validated, so we can indicate that with switch to atom keys.
- defp standardize_error(%{"code" => code, "message" => message} = unstandardized)
- when is_integer(code) and is_binary(message) do
+ def standardize_error(%{"code" => code, "message" => message} = unstandardized)
+ when is_integer(code) and is_binary(message) do
standardized = %{code: code, message: message}
case Map.fetch(unstandardized, "data") do
diff --git a/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/ipc.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/ipc.ex
new file mode 100644
index 0000000000..7f1ff401b0
--- /dev/null
+++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/ipc.ex
@@ -0,0 +1,94 @@
+defmodule EthereumJSONRPC.IPC do
+ use GenServer
+ @moduledoc false
+
+ import EthereumJSONRPC.HTTP, only: [standardize_response: 1]
+
+ # Server
+
+ def start_link(opts) do
+ GenServer.start_link(__MODULE__, Keyword.merge(opts, socket: nil))
+ end
+
+ def init(state) do
+ opts = [:binary, active: false, reuseaddr: true]
+
+ response = :gen_tcp.connect({:local, state[:path]}, 0, opts)
+
+ case response do
+ {:ok, socket} -> {:ok, Keyword.put(state, :socket, socket)}
+ {:error, reason} -> {:error, reason}
+ end
+ end
+
+ def post(pid, request) do
+ GenServer.call(pid, {:request, request})
+ end
+
+ def receive_response(data, socket, timeout, result \\ <<>>)
+
+ def receive_response({:error, reason}, _socket, _timeout, _result) do
+ {:error, reason}
+ end
+
+ def receive_response(:ok, socket, timeout, result) do
+ with {:ok, response} <- :gen_tcp.recv(socket, 0, timeout) do
+ new_result = result <> response
+
+ if String.ends_with?(response, "\n") do
+ {:ok, new_result}
+ else
+ receive_response(:ok, socket, timeout, new_result)
+ end
+ end
+ end
+
+ def receive_response(data, _socket, _timeout, _result) do
+ {:error, data}
+ end
+
+ def handle_call(
+ {:request, request},
+ _from,
+ [socket: socket, path: _] = state
+ ) do
+ response =
+ socket
+ |> :gen_tcp.send(request)
+ |> receive_response(socket, 500_000)
+
+ {:reply, response, state}
+ end
+
+ # Client
+
+ def request(pid, payload) do
+ with {:ok, response} <- post(pid, Jason.encode!(payload)),
+ {:ok, decoded_body} <- Jason.decode(response) do
+ case decoded_body do
+ %{"error" => error} ->
+ {:error, error}
+
+ result = [%{} | _] ->
+ list =
+ result
+ |> Enum.reverse()
+ |> List.flatten()
+ |> Enum.map(&standardize_response/1)
+
+ {:ok, list}
+
+ result ->
+ {:ok, Map.get(result, "result")}
+ end
+ else
+ {:error, %Jason.DecodeError{data: ""}} -> {:error, :empty_response}
+ {:error, error} -> {:error, {:invalid_json, error}}
+ {:error, error} -> {:error, error}
+ end
+ end
+
+ def json_rpc(payload, _opts) do
+ :poolboy.transaction(:ipc_worker, fn pid -> request(pid, payload) end, 600_000)
+ end
+end
diff --git a/apps/ethereum_jsonrpc/mix.exs b/apps/ethereum_jsonrpc/mix.exs
index 240a3aca52..2f5e58dc79 100644
--- a/apps/ethereum_jsonrpc/mix.exs
+++ b/apps/ethereum_jsonrpc/mix.exs
@@ -91,7 +91,8 @@ defmodule EthereumJsonrpc.MixProject do
{:websocket_client, "~> 1.3"},
{:decimal, "~> 1.0"},
{:decorator, "~> 1.2"},
- {:hackney, "~> 1.15.2"}
+ {:hackney, "~> 1.15.2"},
+ {:poolboy, "~> 1.5.2"}
]
end
end
diff --git a/apps/explorer/lib/explorer/chain/token_transfer.ex b/apps/explorer/lib/explorer/chain/token_transfer.ex
index ef0cb4e876..900a57e759 100644
--- a/apps/explorer/lib/explorer/chain/token_transfer.ex
+++ b/apps/explorer/lib/explorer/chain/token_transfer.ex
@@ -280,7 +280,7 @@ defmodule Explorer.Chain.TokenTransfer do
tt in TokenTransfer,
left_join: instance in Instance,
on: tt.token_contract_address_hash == instance.token_contract_address_hash and tt.token_id == instance.token_id,
- where: tt.token_contract_address_hash == ^contract_address_hash and tt.token_id == tt.token_id,
+ where: tt.token_contract_address_hash == ^contract_address_hash,
order_by: [desc: tt.block_number],
distinct: tt.token_id,
preload: [:to_address],
diff --git a/apps/indexer/config/dev/ganache.exs b/apps/indexer/config/dev/ganache.exs
index 337c2317c6..5ffdb90cf7 100644
--- a/apps/indexer/config/dev/ganache.exs
+++ b/apps/indexer/config/dev/ganache.exs
@@ -3,7 +3,11 @@ use Mix.Config
config :indexer,
block_interval: :timer.seconds(5),
json_rpc_named_arguments: [
- transport: EthereumJSONRPC.HTTP,
+ transport:
+ if(System.get_env("ETHEREUM_JSONRPC_JSON_RPC_TRANSPORT", "http") == "http",
+ do: EthereumJSONRPC.HTTP,
+ else: EthereumJSONRPC.IPC
+ ),
transport_options: [
http: EthereumJSONRPC.HTTP.HTTPoison,
url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "http://localhost:7545",
diff --git a/apps/indexer/config/dev/geth.exs b/apps/indexer/config/dev/geth.exs
index cf1113119d..a2fb7c8820 100644
--- a/apps/indexer/config/dev/geth.exs
+++ b/apps/indexer/config/dev/geth.exs
@@ -3,7 +3,11 @@ use Mix.Config
config :indexer,
block_interval: :timer.seconds(5),
json_rpc_named_arguments: [
- transport: EthereumJSONRPC.HTTP,
+ transport:
+ if(System.get_env("ETHEREUM_JSONRPC_JSON_RPC_TRANSPORT", "http") == "http",
+ do: EthereumJSONRPC.HTTP,
+ else: EthereumJSONRPC.IPC
+ ),
transport_options: [
http: EthereumJSONRPC.HTTP.HTTPoison,
url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "https://mainnet.infura.io/8lTvJTKmHPCHazkneJsY",
diff --git a/apps/indexer/config/dev/parity.exs b/apps/indexer/config/dev/parity.exs
index 7a5b31a424..4526a76a5b 100644
--- a/apps/indexer/config/dev/parity.exs
+++ b/apps/indexer/config/dev/parity.exs
@@ -3,7 +3,12 @@ use Mix.Config
config :indexer,
block_interval: :timer.seconds(5),
json_rpc_named_arguments: [
- transport: EthereumJSONRPC.HTTP,
+ transport:
+ if(System.get_env("ETHEREUM_JSONRPC_JSON_RPC_TRANSPORT", "http") == "http",
+ do: EthereumJSONRPC.HTTP,
+ else: EthereumJSONRPC.IPC
+ ),
+ else: EthereumJSONRPC.IPC,
transport_options: [
http: EthereumJSONRPC.HTTP.HTTPoison,
url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "http://localhost:8545",
diff --git a/apps/indexer/config/dev/rsk.exs b/apps/indexer/config/dev/rsk.exs
index 3f7399e892..8ed8d2badf 100644
--- a/apps/indexer/config/dev/rsk.exs
+++ b/apps/indexer/config/dev/rsk.exs
@@ -5,7 +5,11 @@ config :indexer,
blocks_concurrency: 1,
receipts_concurrency: 1,
json_rpc_named_arguments: [
- transport: EthereumJSONRPC.HTTP,
+ transport:
+ if(System.get_env("ETHEREUM_JSONRPC_JSON_RPC_TRANSPORT", "http") == "http",
+ do: EthereumJSONRPC.HTTP,
+ else: EthereumJSONRPC.IPC
+ ),
transport_options: [
http: EthereumJSONRPC.HTTP.HTTPoison,
url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "http://localhost:8545",
diff --git a/apps/indexer/config/prod/ganache.exs b/apps/indexer/config/prod/ganache.exs
index 337c2317c6..5ffdb90cf7 100644
--- a/apps/indexer/config/prod/ganache.exs
+++ b/apps/indexer/config/prod/ganache.exs
@@ -3,7 +3,11 @@ use Mix.Config
config :indexer,
block_interval: :timer.seconds(5),
json_rpc_named_arguments: [
- transport: EthereumJSONRPC.HTTP,
+ transport:
+ if(System.get_env("ETHEREUM_JSONRPC_JSON_RPC_TRANSPORT", "http") == "http",
+ do: EthereumJSONRPC.HTTP,
+ else: EthereumJSONRPC.IPC
+ ),
transport_options: [
http: EthereumJSONRPC.HTTP.HTTPoison,
url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "http://localhost:7545",
diff --git a/apps/indexer/config/prod/geth.exs b/apps/indexer/config/prod/geth.exs
index 859d94319c..93af21654b 100644
--- a/apps/indexer/config/prod/geth.exs
+++ b/apps/indexer/config/prod/geth.exs
@@ -3,7 +3,11 @@ use Mix.Config
config :indexer,
block_interval: :timer.seconds(5),
json_rpc_named_arguments: [
- transport: EthereumJSONRPC.HTTP,
+ transport:
+ if(System.get_env("ETHEREUM_JSONRPC_JSON_RPC_TRANSPORT", "http") == "http",
+ do: EthereumJSONRPC.HTTP,
+ else: EthereumJSONRPC.IPC
+ ),
transport_options: [
http: EthereumJSONRPC.HTTP.HTTPoison,
url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "https://mainnet.infura.io/8lTvJTKmHPCHazkneJsY",
diff --git a/apps/indexer/config/prod/parity.exs b/apps/indexer/config/prod/parity.exs
index dc9da031d5..38f662598e 100644
--- a/apps/indexer/config/prod/parity.exs
+++ b/apps/indexer/config/prod/parity.exs
@@ -3,7 +3,11 @@ use Mix.Config
config :indexer,
block_interval: :timer.seconds(5),
json_rpc_named_arguments: [
- transport: EthereumJSONRPC.HTTP,
+ transport:
+ if(System.get_env("ETHEREUM_JSONRPC_JSON_RPC_TRANSPORT", "http") == "http",
+ do: EthereumJSONRPC.HTTP,
+ else: EthereumJSONRPC.IPC
+ ),
transport_options: [
http: EthereumJSONRPC.HTTP.HTTPoison,
url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL"),
diff --git a/apps/indexer/config/prod/rsk.exs b/apps/indexer/config/prod/rsk.exs
index 81c8c4ac8a..4d90a5b4a3 100644
--- a/apps/indexer/config/prod/rsk.exs
+++ b/apps/indexer/config/prod/rsk.exs
@@ -5,7 +5,11 @@ config :indexer,
blocks_concurrency: 1,
receipts_concurrency: 1,
json_rpc_named_arguments: [
- transport: EthereumJSONRPC.HTTP,
+ transport:
+ if(System.get_env("ETHEREUM_JSONRPC_JSON_RPC_TRANSPORT", "http") == "http",
+ do: EthereumJSONRPC.HTTP,
+ else: EthereumJSONRPC.IPC
+ ),
transport_options: [
http: EthereumJSONRPC.HTTP.HTTPoison,
url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL"),
diff --git a/docker/README.md b/docker/README.md
index ba3458883d..03df272c4a 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -1,77 +1,5 @@
-# BlockScout Docker integration
+# BlockScout Docker Integration
-For now this integration is not production ready. It made only for local usage only !
-
-## How to use ?
-First of all, blockscout requires `PostgreSQL` server for working.
-It will be provided by starting script (new docker image will be created named `postgres`)
-
-**Starting command**
-`make start` - will set everything up and start blockscout in container.
-To connect it to your local environment you will have to configure it using [env variables](#env-variables)
-
-Example connecting to local `ganache` instance running on port `2000` on Mac/Windows:
-```bash
-COIN=DAI \
-ETHEREUM_JSONRPC_VARIANT=ganache \
-ETHEREUM_JSONRPC_HTTP_URL=http://host.docker.internal:2000 \
-ETHEREUM_JSONRPC_WS_URL=ws://host.docker.internal:2000 \
-make start
-```
-
-Blockscout will be available on `localhost:4000`
-
-**Note**
-On mac/Windows Docker provides with a special URL `host.docker.internal` that will be available into container and routed to your local machine.
-On Linux docker is starting using `--network=host` and all services should be available on `localhost`
-
-### Migrations
-
-By default, `Makefile` will do migrations for you on `PostgreSQL` creation.
-But you could run migrations manually using `make migrate` command.
-
-**WARNING** Migrations will clean up your local database !
-
-## Env variables
-
-BlockScout supports 3 different JSON RPC Variants.
-Variant could be configured using `ETHEREUM_JSONRPC_VARIANT` environment variable.
-
-Example:
-```bash
-ETHEREUM_JSONRPC_VARIANT=ganache make start
-```
-
-Available options are:
-
- * `parity` - Parity JSON RPC (**Default one**)
- * `geth` - Geth JSON RPC
- * `ganache` - Ganache JSON RPC
-
-
-| Variable | Description | Default value |
-| -------- | ----------- | ------------- |
-| `ETHEREUM_JSONRPC_VARIANT` | Variant of your JSON RPC service: `parity`, `geth` or `ganache` | `parity` |
-| `ETHEREUM_JSONRPC_HTTP_URL` | HTTP JSON RPC URL Only for `geth` or `ganache` variant | Different per JSONRPC variant |
-| `ETHEREUM_JSONRPC_WS_URL` | WS JSON RPC url | Different per JSONRPC variant |
-| `ETHEREUM_JSONRPC_TRACE_URL` | Trace URL **Only for `parity` variant** | `http://localhost:8545` |
-| `COIN` | Default Coin | `POA` |
-| `LOGO` | Coin logo | Empty |
-| `NETWORK` | Network | Empty |
-| `SUBNETWORK` | Subnetwork | Empty |
-| `NETWORK_ICON` | Network icon | Empty |
-| `NETWORK_PATH` | Network path | `/` |
-
-
-`ETHEREUM_JSONRPC_HTTP_URL` default values:
-
- * For `parity` - `http://localhost:8545`
- * For `geth` - `https://mainnet.infura.io/8lTvJTKmHPCHazkneJsY`
- * For `ganache` - `http://localhost:7545`
-
-`ETHEREUM_JSONRPC_WS_URL` default values:
-
- * For `parity` - `ws://localhost:8546`
- * For `geth` - `wss://mainnet.infura.io/8lTvJTKmHPCHazkneJsY/ws`
- * For `ganache` - `ws://localhost:7545`
+This integration is not production ready, and should be used for local BlockScout deployment only.
+For usage instructions and ENV variables, see the [docker integration documentation](https://docs.blockscout.com/for-developers/information-and-settings/docker-integration-local-use-only).
\ No newline at end of file