From e01b3816803715d92583a1e817de5988785cc462 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Thu, 27 Jun 2019 16:18:17 +0300 Subject: [PATCH 01/39] add background smart contract verification --- .../v1/verified_smart_contract_controller.ex | 35 +++---------------- .../smart_contract/publisher_worker.ex | 21 +++++++++++ apps/explorer/mix.exs | 1 + mix.lock | 3 ++ 4 files changed, 29 insertions(+), 31 deletions(-) create mode 100644 apps/explorer/lib/explorer/smart_contract/publisher_worker.ex diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v1/verified_smart_contract_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v1/verified_smart_contract_controller.ex index 50334a1a45..616e67eb5f 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v1/verified_smart_contract_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v1/verified_smart_contract_controller.ex @@ -3,40 +3,17 @@ defmodule BlockScoutWeb.API.V1.VerifiedSmartContractController do alias Explorer.Chain alias Explorer.Chain.Hash.Address - alias Explorer.SmartContract.Publisher + alias Explorer.SmartContract.PublisherWorker def create(conn, params) do with {:ok, hash} <- validate_address_hash(params["address_hash"]), :ok <- smart_contract_exists?(hash), :ok <- verified_smart_contract_exists?(hash) do - external_libraries = fetch_external_libraries(params) + external_libraries = fetch_external_libraries(params) || %{} - case Publisher.publish(hash, params, external_libraries) do - {:ok, _} -> - send_resp(conn, :created, Jason.encode!(%{status: :success})) + PublisherWorker.perform({hash, params, external_libraries}) - {:error, changeset} -> - errors = - changeset.errors - |> Enum.into(%{}, fn {field, {message, _}} -> - {field, message} - end) - - send_resp(conn, :unprocessable_entity, encode(errors)) - end - else - :invalid_address -> - send_resp(conn, :unprocessable_entity, encode(%{error: "address_hash is invalid"})) - - :not_found -> - send_resp(conn, :unprocessable_entity, encode(%{error: "address is not found"})) - - :contract_exists -> - send_resp( - conn, - :unprocessable_entity, - encode(%{error: "verified code already exists for this address"}) - ) + send_resp(conn, :created, Jason.encode!(%{status: :started_processing})) end end @@ -62,10 +39,6 @@ defmodule BlockScoutWeb.API.V1.VerifiedSmartContractController do end end - defp encode(data) do - Jason.encode!(data) - end - defp fetch_external_libraries(params) do keys = Enum.flat_map(1..5, fn i -> ["library#{i}_name", "library#{i}_address"] end) diff --git a/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex b/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex new file mode 100644 index 0000000000..1a13a237a2 --- /dev/null +++ b/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex @@ -0,0 +1,21 @@ +defmodule Explorer.SmartContract.PublisherWorker do + use Que.Worker + + alias Explorer.SmartContract.Publisher + + def perform({address_hash, params, external_libraries}) do + case Publisher.publish(address_hash, params, external_libraries) do + {:ok, _} -> + :ok + + {:error, changeset} -> + errors = + changeset.errors + |> Enum.into(%{}, fn {field, {message, _}} -> + {field, message} + end) + + {:error, errors} + end + end +end diff --git a/apps/explorer/mix.exs b/apps/explorer/mix.exs index f224471740..6eb32b524e 100644 --- a/apps/explorer/mix.exs +++ b/apps/explorer/mix.exs @@ -105,6 +105,7 @@ defmodule Explorer.Mixfile do }, # bypass optional dependency {:plug_cowboy, "~> 2.0", only: [:dev, :test]}, + {:que, "~> 0.10.1"}, {:sobelow, ">= 0.7.0", only: [:dev, :test], runtime: false}, # Tracing {:spandex, github: "spandex-project/spandex", branch: "allow-setting-trace-key", override: true}, diff --git a/mix.lock b/mix.lock index 258c71f03f..f7d2c836cd 100644 --- a/mix.lock +++ b/mix.lock @@ -42,6 +42,7 @@ "ex_doc": {:hex, :ex_doc, "0.19.2", "6f4081ccd9ed081b6dc0bd5af97a41e87f5554de469e7d76025fba535180565f", [:mix], [{:earmark, "~> 1.2", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, "ex_machina": {:hex, :ex_machina, "2.2.2", "d84217a6fb7840ff771d2561b8aa6d74a0d8968e4b10ecc0d7e9890dc8fb1c6a", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm"}, "ex_rlp": {:hex, :ex_rlp, "0.5.2", "7f4ce7bd55e543c054ce6d49629b01e9833c3462e3d547952be89865f39f2c58", [:mix], [], "hexpm"}, + "ex_utils": {:hex, :ex_utils, "0.1.7", "2c133e0bcdc49a858cf8dacf893308ebc05bc5fba501dc3d2935e65365ec0bf3", [:mix], [], "hexpm"}, "exactor": {:hex, :exactor, "2.2.4", "5efb4ddeb2c48d9a1d7c9b465a6fffdd82300eb9618ece5d34c3334d5d7245b1", [:mix], []}, "excoveralls": {:git, "https://github.com/KronicDeth/excoveralls.git", "0a859b68851eeba9b43eba59fbc8f9098299cfe1", [branch: "circle-workflows"]}, "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, optional: false]}]}, @@ -66,6 +67,7 @@ "makeup_elixir": {:hex, :makeup_elixir, "0.13.0", "be7a477997dcac2e48a9d695ec730b2d22418292675c75aa2d34ba0909dcdeda", [:mix], [{:makeup, "~> 0.8", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"}, "math": {:hex, :math, "0.3.0", "e14e7291115201cb155a3567e66d196bf5088a6f55b030d598107d7ae934a11c", [:mix], []}, "meck": {:hex, :meck, "0.8.12", "1f7b1a9f5d12c511848fec26bbefd09a21e1432eadb8982d9a8aceb9891a3cf2", [:rebar3], [], "hexpm"}, + "memento": {:hex, :memento, "0.3.1", "b2909390820550d8b90b68ec96f9e15ff8a45a28b6f97fa4a62ef50e87c2f9d9", [:mix], [], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []}, "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm"}, @@ -97,6 +99,7 @@ "prometheus_plugs": {:hex, :prometheus_plugs, "1.1.5", "25933d48f8af3a5941dd7b621c889749894d8a1082a6ff7c67cc99dec26377c5", [:mix], [{:accept, "~> 0.1", [hex: :accept, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}, {:prometheus_process_collector, "~> 1.1", [hex: :prometheus_process_collector, repo: "hexpm", optional: true]}], "hexpm"}, "prometheus_process_collector": {:hex, :prometheus_process_collector, "1.4.0", "6dbd39e3165b9ef1c94a7a820e9ffe08479f949dcdd431ed4aaea7b250eebfde", [:rebar3], [{:prometheus, "~> 4.0", [hex: :prometheus, repo: "hexpm", optional: false]}], "hexpm"}, "qrcode": {:hex, :qrcode, "0.1.4", "544dc67ba42eed5ebce3d2a691d053387937740561d251f83f0a067917fae2dc", [:mix], [], "hexpm"}, + "que": {:hex, :que, "0.10.1", "788ed0ec92ed69bdf9cfb29bf41a94ca6355b8d44959bd0669cf706e557ac891", [:mix], [{:ex_utils, "~> 0.1.6", [hex: :ex_utils, repo: "hexpm", optional: false]}, {:memento, "~> 0.3.0", [hex: :memento, repo: "hexpm", optional: false]}], "hexpm"}, "ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm"}, "set_locale": {:git, "https://github.com/minifast/set_locale.git", "da9ae029642bc0fbd9212c2aaf86c0adca70c084", [branch: "master"]}, "sobelow": {:hex, :sobelow, "0.7.4", "228cc6185b448b63ecc88429b43e864e8dd570e8e09f2d04b3aa71894db1bdbb", [:mix], [], "hexpm"}, From b93da31b9778dc5b01b32f772facca2a21b5d60d Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Tue, 2 Jul 2019 12:56:03 +0300 Subject: [PATCH 02/39] fix adding a job to the processing queue --- .../address_contract_verification_controller.ex | 16 +++------------- .../explorer/smart_contract/publisher_worker.ex | 6 +++++- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_verification_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_verification_controller.ex index dad0ebaeaf..4aa57038a7 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_verification_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_verification_controller.ex @@ -2,7 +2,7 @@ defmodule BlockScoutWeb.AddressContractVerificationController do use BlockScoutWeb, :controller alias Explorer.Chain.SmartContract - alias Explorer.SmartContract.{Publisher, Solidity.CodeCompiler, Solidity.CompilerVersion} + alias Explorer.SmartContract.{PublisherWorker, Solidity.CodeCompiler, Solidity.CompilerVersion} def new(conn, %{"address_id" => address_hash_string}) do changeset = @@ -28,19 +28,9 @@ defmodule BlockScoutWeb.AddressContractVerificationController do "external_libraries" => external_libraries } ) do - case Publisher.publish(address_hash_string, smart_contract, external_libraries) do - {:ok, _smart_contract} -> - redirect(conn, to: address_contract_path(conn, :index, address_hash_string)) + Que.add(PublisherWorker, {address_hash_string, smart_contract, external_libraries}) - {:error, changeset} -> - {:ok, compiler_versions} = CompilerVersion.fetch_versions() - - render(conn, "new.html", - changeset: changeset, - compiler_versions: compiler_versions, - evm_versions: CodeCompiler.allowed_evm_versions() - ) - end + send_resp(conn, 204, "") end def parse_optimization_runs(%{"runs" => runs}) do diff --git a/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex b/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex index 1a13a237a2..16d4f5d37d 100644 --- a/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex +++ b/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex @@ -1,5 +1,9 @@ defmodule Explorer.SmartContract.PublisherWorker do - use Que.Worker + @moduledoc """ + Background smart contract verification worker. + """ + + use Que.Worker, concurrency: 5 alias Explorer.SmartContract.Publisher From 0230371deba6e408f3153624eae467cb4b24659b Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Tue, 2 Jul 2019 12:59:48 +0300 Subject: [PATCH 03/39] use sync processing in api --- .../v1/verified_smart_contract_controller.ex | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v1/verified_smart_contract_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v1/verified_smart_contract_controller.ex index 616e67eb5f..50334a1a45 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v1/verified_smart_contract_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v1/verified_smart_contract_controller.ex @@ -3,17 +3,40 @@ defmodule BlockScoutWeb.API.V1.VerifiedSmartContractController do alias Explorer.Chain alias Explorer.Chain.Hash.Address - alias Explorer.SmartContract.PublisherWorker + alias Explorer.SmartContract.Publisher def create(conn, params) do with {:ok, hash} <- validate_address_hash(params["address_hash"]), :ok <- smart_contract_exists?(hash), :ok <- verified_smart_contract_exists?(hash) do - external_libraries = fetch_external_libraries(params) || %{} + external_libraries = fetch_external_libraries(params) - PublisherWorker.perform({hash, params, external_libraries}) + case Publisher.publish(hash, params, external_libraries) do + {:ok, _} -> + send_resp(conn, :created, Jason.encode!(%{status: :success})) - send_resp(conn, :created, Jason.encode!(%{status: :started_processing})) + {:error, changeset} -> + errors = + changeset.errors + |> Enum.into(%{}, fn {field, {message, _}} -> + {field, message} + end) + + send_resp(conn, :unprocessable_entity, encode(errors)) + end + else + :invalid_address -> + send_resp(conn, :unprocessable_entity, encode(%{error: "address_hash is invalid"})) + + :not_found -> + send_resp(conn, :unprocessable_entity, encode(%{error: "address is not found"})) + + :contract_exists -> + send_resp( + conn, + :unprocessable_entity, + encode(%{error: "verified code already exists for this address"}) + ) end end @@ -39,6 +62,10 @@ defmodule BlockScoutWeb.API.V1.VerifiedSmartContractController do end end + defp encode(data) do + Jason.encode!(data) + end + defp fetch_external_libraries(params) do keys = Enum.flat_map(1..5, fn i -> ["library#{i}_name", "library#{i}_address"] end) From ca3abfc9eece9e55dd97d55031b956c762ee6cee Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Tue, 2 Jul 2019 13:10:16 +0300 Subject: [PATCH 04/39] fix dialyzer --- .dialyzer-ignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.dialyzer-ignore b/.dialyzer-ignore index 53e3554c6e..60465de4e8 100644 --- a/.dialyzer-ignore +++ b/.dialyzer-ignore @@ -4,4 +4,6 @@ apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex:400: Function timestamp_to_datetime/1 has no local return apps/explorer/lib/explorer/repo/prometheus_logger.ex:8: Function microseconds_time/1 has no local return apps/explorer/lib/explorer/repo/prometheus_logger.ex:8: The call 'Elixir.System':convert_time_unit(__@1::any(),'native','microseconds') breaks the contract (integer(),time_unit() | 'native',time_unit() | 'native') -> integer() -apps/block_scout_web/lib/block_scout_web/views/layout_view.ex:174: The call 'Elixir.Poison.Parser':'parse!'(any(),#{'keys':='atoms!'}) will never return since the success typing is (binary() | maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | []),[{atom(),_}]) -> 'false' | 'nil' | 'true' | binary() | ['false' | 'nil' | 'true' | binary() | [any()] | number() | map()] | number() | map() and the contract is (iodata(),'Elixir.Keyword':t()) -> t() \ No newline at end of file +apps/block_scout_web/lib/block_scout_web/views/layout_view.ex:174: The call 'Elixir.Poison.Parser':'parse!'(any(),#{'keys':='atoms!'}) will never return since the success typing is (binary() | maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | []),[{atom(),_}]) -> 'false' | 'nil' | 'true' | binary() | ['false' | 'nil' | 'true' | binary() | [any()] | number() | map()] | number() | map() and the contract is (iodata(),'Elixir.Keyword':t()) -> t() +pps/explorer/lib/explorer/smart_contract/publisher_worker.ex:6: The pattern 'false' can never match the type 'true' +apps/explorer/lib/explorer/smart_contract/publisher_worker.ex:6: The test 5 == 'infinity' can never evaluate to 'true' \ No newline at end of file From a464cee5177bfb3f600455198587ce58a526625c Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Tue, 2 Jul 2019 14:36:07 +0300 Subject: [PATCH 05/39] pass result through web socket --- .../channels/address_channel.ex | 15 ++++++++++- .../lib/block_scout_web/notifier.ex | 10 +++++++ .../block_scout_web/realtime_event_handler.ex | 1 + .../lib/explorer/chain/events/publisher.ex | 2 +- .../lib/explorer/chain/events/subscriber.ex | 4 +-- .../smart_contract/publisher_worker.ex | 26 +++++++++++-------- 6 files changed, 43 insertions(+), 15 deletions(-) diff --git a/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex b/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex index cbbaa7eba7..faecd3597a 100644 --- a/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex +++ b/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex @@ -11,7 +11,7 @@ defmodule BlockScoutWeb.AddressChannel do alias Explorer.ExchangeRates.Token alias Phoenix.View - intercept(["balance_update", "coin_balance", "count", "internal_transaction", "transaction"]) + intercept(["balance_update", "coin_balance", "count", "internal_transaction", "transaction", "verification_result"]) def join("addresses:" <> address_hash, _params, socket) do {:ok, %{}, assign(socket, :address_hash, address_hash)} @@ -58,6 +58,19 @@ defmodule BlockScoutWeb.AddressChannel do end end + def handle_out("verification_result", %{result: result}, socket) do + case result do + {:ok, _contract} -> + push(socket, "verification", %{verification_result: :ok}) + {:noreply, socket} + + _ -> + push(socket, "verification", %{verification_result: :error}) + {:noreply, socket} + end + |> IO.inspect() + end + def handle_out("count", %{count: count}, socket) do Gettext.put_locale(BlockScoutWeb.Gettext, socket.assigns.locale) diff --git a/apps/block_scout_web/lib/block_scout_web/notifier.ex b/apps/block_scout_web/lib/block_scout_web/notifier.ex index a5bc99e242..3a3c90f6e8 100644 --- a/apps/block_scout_web/lib/block_scout_web/notifier.ex +++ b/apps/block_scout_web/lib/block_scout_web/notifier.ex @@ -23,6 +23,16 @@ defmodule BlockScoutWeb.Notifier do Enum.each(address_coin_balances, &broadcast_address_coin_balance/1) end + def handle_event( + {:chain_event, :contract_verification_result, :on_demand, {address_hash, _contract_verification_result}} + ) do + Endpoint.broadcast( + "addresses:#{address_hash}", + "verification_result", + %{} + ) + end + def handle_event({:chain_event, :block_rewards, :realtime, rewards}) do if Application.get_env(:block_scout_web, BlockScoutWeb.Chain)[:has_emission_funds] do broadcast_rewards(rewards) diff --git a/apps/block_scout_web/lib/block_scout_web/realtime_event_handler.ex b/apps/block_scout_web/lib/block_scout_web/realtime_event_handler.ex index f0f73f402c..8357878efe 100644 --- a/apps/block_scout_web/lib/block_scout_web/realtime_event_handler.ex +++ b/apps/block_scout_web/lib/block_scout_web/realtime_event_handler.ex @@ -23,6 +23,7 @@ defmodule BlockScoutWeb.RealtimeEventHandler do Subscriber.to(:transactions, :realtime) Subscriber.to(:addresses, :on_demand) Subscriber.to(:address_coin_balances, :on_demand) + Subscriber.to(:contract_verification_result, :on_demand) # Does not come from the indexer Subscriber.to(:exchange_rate) {:ok, []} diff --git a/apps/explorer/lib/explorer/chain/events/publisher.ex b/apps/explorer/lib/explorer/chain/events/publisher.ex index 7077fdfeab..c7e01eef3a 100644 --- a/apps/explorer/lib/explorer/chain/events/publisher.ex +++ b/apps/explorer/lib/explorer/chain/events/publisher.ex @@ -3,7 +3,7 @@ defmodule Explorer.Chain.Events.Publisher do Publishes events related to the Chain context. """ - @allowed_events ~w(addresses address_coin_balances blocks block_rewards internal_transactions token_transfers transactions)a + @allowed_events ~w(addresses address_coin_balances blocks block_rewards internal_transactions token_transfers transactions contract_verification_result)a def broadcast(_data, false), do: :ok diff --git a/apps/explorer/lib/explorer/chain/events/subscriber.ex b/apps/explorer/lib/explorer/chain/events/subscriber.ex index 6a9df99438..7d24ce4cd5 100644 --- a/apps/explorer/lib/explorer/chain/events/subscriber.ex +++ b/apps/explorer/lib/explorer/chain/events/subscriber.ex @@ -3,9 +3,9 @@ defmodule Explorer.Chain.Events.Subscriber do Subscribes to events related to the Chain context. """ - @allowed_broadcast_events ~w(addresses address_coin_balances blocks block_rewards internal_transactions token_transfers transactions)a + @allowed_broadcast_events ~w(addresses address_coin_balances blocks block_rewards internal_transactions token_transfers transactions contract_verification_result)a - @allowed_broadcast_types ~w(catchup realtime on_demand)a + @allowed_broadcast_types ~w(catchup realtime on_demand contract_verification_result)a @allowed_events ~w(exchange_rate)a diff --git a/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex b/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex index 16d4f5d37d..1671633d45 100644 --- a/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex +++ b/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex @@ -6,20 +6,24 @@ defmodule Explorer.SmartContract.PublisherWorker do use Que.Worker, concurrency: 5 alias Explorer.SmartContract.Publisher + alias Explorer.Chain.Events.Publisher, as: EventsPublisher def perform({address_hash, params, external_libraries}) do - case Publisher.publish(address_hash, params, external_libraries) do - {:ok, _} -> - :ok + result = + case Publisher.publish(address_hash, params, external_libraries) do + {:ok, _contract} = result -> + result - {:error, changeset} -> - errors = - changeset.errors - |> Enum.into(%{}, fn {field, {message, _}} -> - {field, message} - end) + {:error, changeset} -> + errors = + changeset.errors + |> Enum.into(%{}, fn {field, {message, _}} -> + {field, message} + end) - {:error, errors} - end + {:error, errors} + end + + EventsPublisher.broadcast([{:contract_verification_result, {address_hash, result}}], :on_demand) end end From 1b9120862378ef2c6d70865766fa389d9b2dbbaf Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Tue, 2 Jul 2019 14:59:15 +0300 Subject: [PATCH 06/39] fix event name --- apps/block_scout_web/assets/js/pages/address.js | 7 +++++++ .../lib/block_scout_web/channels/address_channel.ex | 3 +-- .../templates/address_contract_verification/new.html.eex | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/block_scout_web/assets/js/pages/address.js b/apps/block_scout_web/assets/js/pages/address.js index 5b35a0b9d7..d6add5f6d7 100644 --- a/apps/block_scout_web/assets/js/pages/address.js +++ b/apps/block_scout_web/assets/js/pages/address.js @@ -40,6 +40,9 @@ export function reducer (state = initialState, action) { const validationCount = state.validationCount + 1 return Object.assign({}, state, { validationCount }) } + case 'RECEIVED_VERIFICATION_RESULT': { + console.log('verified') + } case 'RECEIVED_NEW_TRANSACTION': { if (state.channelDisconnected) return state @@ -127,6 +130,10 @@ if ($addressDetailsPage.length) { type: 'RECEIVED_UPDATED_BALANCE', msg: humps.camelizeKeys(msg) })) + addressChannel.on("verification", (msg) => store.dispatch({ + type: 'RECEIVED_VERIFICATION_RESULT', + msg: humps.camelizeKeys(msg) + })) addressChannel.on('transaction', (msg) => { store.dispatch({ type: 'RECEIVED_NEW_TRANSACTION', diff --git a/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex b/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex index faecd3597a..a91ca5cec4 100644 --- a/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex +++ b/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex @@ -58,7 +58,7 @@ defmodule BlockScoutWeb.AddressChannel do end end - def handle_out("verification_result", %{result: result}, socket) do + def handle_out("verification_result", result, socket) do case result do {:ok, _contract} -> push(socket, "verification", %{verification_result: :ok}) @@ -68,7 +68,6 @@ defmodule BlockScoutWeb.AddressChannel do push(socket, "verification", %{verification_result: :error}) {:noreply, socket} end - |> IO.inspect() end def handle_out("count", %{count: count}, socket) do diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex index 7214af2eee..1ddc6cc870 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex @@ -1,4 +1,4 @@ -
+

<%= gettext "New Smart Contract Verification" %>

From cd2e9878de06b22cab6b4d95381a940e36c8f6f3 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Wed, 3 Jul 2019 13:55:32 +0300 Subject: [PATCH 07/39] redirect on successful verification --- apps/block_scout_web/assets/js/app.js | 1 + .../assets/js/pages/address.js | 7 -- .../assets/js/pages/verification_form.js | 114 ++++++++++++++++++ .../channels/address_channel.ex | 6 +- .../lib/block_scout_web/notifier.ex | 7 +- 5 files changed, 123 insertions(+), 12 deletions(-) create mode 100644 apps/block_scout_web/assets/js/pages/verification_form.js diff --git a/apps/block_scout_web/assets/js/app.js b/apps/block_scout_web/assets/js/app.js index cd690f31db..ea3e2b1afd 100644 --- a/apps/block_scout_web/assets/js/app.js +++ b/apps/block_scout_web/assets/js/app.js @@ -34,6 +34,7 @@ import './pages/transactions' import './pages/favorites' import './pages/network-search' import './pages/layout' +import './pages/verification_form' import './pages/admin/tasks.js' diff --git a/apps/block_scout_web/assets/js/pages/address.js b/apps/block_scout_web/assets/js/pages/address.js index d6add5f6d7..5b35a0b9d7 100644 --- a/apps/block_scout_web/assets/js/pages/address.js +++ b/apps/block_scout_web/assets/js/pages/address.js @@ -40,9 +40,6 @@ export function reducer (state = initialState, action) { const validationCount = state.validationCount + 1 return Object.assign({}, state, { validationCount }) } - case 'RECEIVED_VERIFICATION_RESULT': { - console.log('verified') - } case 'RECEIVED_NEW_TRANSACTION': { if (state.channelDisconnected) return state @@ -130,10 +127,6 @@ if ($addressDetailsPage.length) { type: 'RECEIVED_UPDATED_BALANCE', msg: humps.camelizeKeys(msg) })) - addressChannel.on("verification", (msg) => store.dispatch({ - type: 'RECEIVED_VERIFICATION_RESULT', - msg: humps.camelizeKeys(msg) - })) addressChannel.on('transaction', (msg) => { store.dispatch({ type: 'RECEIVED_NEW_TRANSACTION', diff --git a/apps/block_scout_web/assets/js/pages/verification_form.js b/apps/block_scout_web/assets/js/pages/verification_form.js new file mode 100644 index 0000000000..86f38c3ba8 --- /dev/null +++ b/apps/block_scout_web/assets/js/pages/verification_form.js @@ -0,0 +1,114 @@ +import $ from 'jquery' +import _ from 'lodash' +import URI from 'urijs' +import humps from 'humps' +import numeral from 'numeral' +import socket, { subscribeChannel } from '../socket' +import { createStore, connectElements } from '../lib/redux_helpers.js' + +export const initialState = { + channelDisconnected: false, + + addressHash: null, + filter: null, + + balance: null, + balanceCard: null, + fetchedCoinBalanceBlockNumber: null, + transactionCount: null, + validationCount: null +} + +export function reducer (state = initialState, action) { + switch (action.type) { + case 'PAGE_LOAD': + case 'ELEMENTS_LOAD': { + return Object.assign({}, state, _.omit(action, 'type')) + } + case 'CHANNEL_DISCONNECTED': { + if (state.beyondPageOne) return state + + return Object.assign({}, state, { + channelDisconnected: true + }) + } + case 'RECEIVED_VERIFICATION_RESULT': { + if (action.msg.verificationResult === "ok") { + window.location.replace(window.location.href.split('/contract_verifications')[0] + '/contracts') + } + } + default: + return state + } +} + +const elements = { + '[data-selector="channel-disconnected-message"]': { + render ($el, state) { + if (state.channelDisconnected) $el.show() + } + }, + '[data-selector="balance-card"]': { + load ($el) { + return { balanceCard: $el.html(), balance: parseFloat($el.find('.current-balance-in-wei').attr('data-wei-value')) } + }, + render ($el, state, oldState) { + if (oldState.balance === state.balance) return + $el.empty().append(state.balanceCard) + loadTokenBalanceDropdown() + updateAllCalculatedUsdValues() + } + }, + '[data-selector="transaction-count"]': { + load ($el) { + return { transactionCount: numeral($el.text()).value() } + }, + render ($el, state, oldState) { + if (oldState.transactionCount === state.transactionCount) return + $el.empty().append(numeral(state.transactionCount).format()) + } + }, + '[data-selector="fetched-coin-balance-block-number"]': { + load ($el) { + return {fetchedCoinBalanceBlockNumber: numeral($el.text()).value()} + }, + render ($el, state, oldState) { + if (oldState.fetchedCoinBalanceBlockNumber === state.fetchedCoinBalanceBlockNumber) return + $el.empty().append(numeral(state.fetchedCoinBalanceBlockNumber).format()) + } + }, + '[data-selector="validation-count"]': { + load ($el) { + return { validationCount: numeral($el.text()).value() } + }, + render ($el, state, oldState) { + if (oldState.validationCount === state.validationCount) return + $el.empty().append(numeral(state.validationCount).format()) + } + } +} + +const $contractVerificationPage = $('[data-page="contract-verification"]') + +if ($contractVerificationPage.length) { + const store = createStore(reducer) + const addressHash = $('#smart_contract_address_hash').val() + const { filter, blockNumber } = humps.camelizeKeys(URI(window.location).query(true)) + store.dispatch({ + type: 'PAGE_LOAD', + addressHash, + filter, + beyondPageOne: !!blockNumber + }) + connectElements({ store, elements }) + + const addressChannel = subscribeChannel(`addresses:${addressHash}`) + + addressChannel.onError(() => store.dispatch({ + type: 'CHANNEL_DISCONNECTED' + })) + addressChannel.on("verification", (msg) => store.dispatch({ + type: 'RECEIVED_VERIFICATION_RESULT', + msg: humps.camelizeKeys(msg) + })) +} diff --git a/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex b/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex index a91ca5cec4..4009d4f461 100644 --- a/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex +++ b/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex @@ -59,13 +59,13 @@ defmodule BlockScoutWeb.AddressChannel do end def handle_out("verification_result", result, socket) do - case result do + case result[:result] do {:ok, _contract} -> push(socket, "verification", %{verification_result: :ok}) {:noreply, socket} - _ -> - push(socket, "verification", %{verification_result: :error}) + {:error, result} -> + push(socket, "verification", %{verification_result: result}) {:noreply, socket} end end diff --git a/apps/block_scout_web/lib/block_scout_web/notifier.ex b/apps/block_scout_web/lib/block_scout_web/notifier.ex index 3a3c90f6e8..9845982834 100644 --- a/apps/block_scout_web/lib/block_scout_web/notifier.ex +++ b/apps/block_scout_web/lib/block_scout_web/notifier.ex @@ -24,12 +24,15 @@ defmodule BlockScoutWeb.Notifier do end def handle_event( - {:chain_event, :contract_verification_result, :on_demand, {address_hash, _contract_verification_result}} + {:chain_event, :contract_verification_result, :on_demand, {address_hash, contract_verification_result}} ) do Endpoint.broadcast( "addresses:#{address_hash}", "verification_result", - %{} + %{ + address_hash: address_hash, + result: contract_verification_result + } ) end From d785535bc251984e226d7714f7a347bfe35fdcd9 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Wed, 3 Jul 2019 15:26:54 +0300 Subject: [PATCH 08/39] render errors --- .../assets/js/pages/verification_form.js | 59 ++++--------------- ...ddress_contract_verification_controller.ex | 3 +- .../lib/block_scout_web/notifier.ex | 23 +++++++- .../new.html.eex | 10 +++- .../smart_contract/publisher_worker.ex | 8 +-- 5 files changed, 46 insertions(+), 57 deletions(-) diff --git a/apps/block_scout_web/assets/js/pages/verification_form.js b/apps/block_scout_web/assets/js/pages/verification_form.js index 86f38c3ba8..b749f24b64 100644 --- a/apps/block_scout_web/assets/js/pages/verification_form.js +++ b/apps/block_scout_web/assets/js/pages/verification_form.js @@ -8,15 +8,8 @@ import { createStore, connectElements } from '../lib/redux_helpers.js' export const initialState = { channelDisconnected: false, - addressHash: null, - filter: null, - - balance: null, - balanceCard: null, - fetchedCoinBalanceBlockNumber: null, - transactionCount: null, - validationCount: null + newForm: null } export function reducer (state = initialState, action) { @@ -32,9 +25,14 @@ export function reducer (state = initialState, action) { channelDisconnected: true }) } - case 'RECEIVED_VERIFICATION_RESULT': { + case 'RECEIVED_VERIFICATION_RESULT': { + console.log(action.msg) if (action.msg.verificationResult === "ok") { - window.location.replace(window.location.href.split('/contract_verifications')[0] + '/contracts') + return window.location.replace(window.location.href.split('/contract_verifications')[0] + '/contracts') + } else { + return Object.assign({}, state, { + newForm: action.msg.verificationResult + }) } } default: @@ -48,42 +46,11 @@ const elements = { if (state.channelDisconnected) $el.show() } }, - '[data-selector="balance-card"]': { - load ($el) { - return { balanceCard: $el.html(), balance: parseFloat($el.find('.current-balance-in-wei').attr('data-wei-value')) } - }, - render ($el, state, oldState) { - if (oldState.balance === state.balance) return - $el.empty().append(state.balanceCard) - loadTokenBalanceDropdown() - updateAllCalculatedUsdValues() - } - }, - '[data-selector="transaction-count"]': { - load ($el) { - return { transactionCount: numeral($el.text()).value() } - }, - render ($el, state, oldState) { - if (oldState.transactionCount === state.transactionCount) return - $el.empty().append(numeral(state.transactionCount).format()) - } - }, - '[data-selector="fetched-coin-balance-block-number"]': { - load ($el) { - return {fetchedCoinBalanceBlockNumber: numeral($el.text()).value()} - }, - render ($el, state, oldState) { - if (oldState.fetchedCoinBalanceBlockNumber === state.fetchedCoinBalanceBlockNumber) return - $el.empty().append(numeral(state.fetchedCoinBalanceBlockNumber).format()) - } - }, - '[data-selector="validation-count"]': { - load ($el) { - return { validationCount: numeral($el.text()).value() } - }, - render ($el, state, oldState) { - if (oldState.validationCount === state.validationCount) return - $el.empty().append(numeral(state.validationCount).format()) + '[data-page="contract-verification"]': { + render ($el, state) { + if (state.newForm) { + return $el.replaceWith(state.newForm) + } } } } diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_verification_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_verification_controller.ex index 4aa57038a7..ee8ef7b635 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_verification_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_verification_controller.ex @@ -16,7 +16,8 @@ defmodule BlockScoutWeb.AddressContractVerificationController do render(conn, "new.html", changeset: changeset, compiler_versions: compiler_versions, - evm_versions: CodeCompiler.allowed_evm_versions() + evm_versions: CodeCompiler.allowed_evm_versions(), + address_hash: address_hash_string ) end diff --git a/apps/block_scout_web/lib/block_scout_web/notifier.ex b/apps/block_scout_web/lib/block_scout_web/notifier.ex index 9845982834..eb7149e299 100644 --- a/apps/block_scout_web/lib/block_scout_web/notifier.ex +++ b/apps/block_scout_web/lib/block_scout_web/notifier.ex @@ -4,11 +4,13 @@ defmodule BlockScoutWeb.Notifier do """ alias Absinthe.Subscription - alias BlockScoutWeb.Endpoint + alias BlockScoutWeb.{AddressContractVerificationView, Endpoint} alias Explorer.{Chain, Market, Repo} alias Explorer.Chain.{Address, InternalTransaction, Transaction} alias Explorer.Counters.AverageBlockTime + alias Explorer.SmartContract.{Solidity.CodeCompiler, Solidity.CompilerVersion} alias Explorer.ExchangeRates.Token + alias Phoenix.View def handle_event({:chain_event, :addresses, type, addresses}) when type in [:realtime, :on_demand] do Endpoint.broadcast("addresses:new_address", "count", %{count: Chain.count_addresses_with_balance_from_cache()}) @@ -26,6 +28,25 @@ defmodule BlockScoutWeb.Notifier do def handle_event( {:chain_event, :contract_verification_result, :on_demand, {address_hash, contract_verification_result}} ) do + contract_verification_result = + case contract_verification_result do + {:ok, _} = result -> + result + + {:error, changeset} -> + {:ok, compiler_versions} = CompilerVersion.fetch_versions() + + result = + View.render_to_string(AddressContractVerificationView, "new.html", + changeset: changeset, + compiler_versions: compiler_versions, + evm_versions: CodeCompiler.allowed_evm_versions(), + address_hash: address_hash + ) + + {:error, result} + end + Endpoint.broadcast( "addresses:#{address_hash}", "verification_result", diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex index 1ddc6cc870..2f00c515ea 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex @@ -1,9 +1,15 @@
+ +

<%= gettext "New Smart Contract Verification" %>

<%= form_for @changeset, - address_verify_contract_path(@conn, :create, @conn.params["address_id"]), + "/address/#{@address_hash}/contract_verifications", [], fn f -> %> @@ -246,7 +252,7 @@ link( gettext("Cancel"), class: "btn-no-border", - to: address_contract_path(@conn, :index, @conn.params["address_id"]) + to: "/address/#{@address_hash}/contracts" ) %>
diff --git a/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex b/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex index 1671633d45..0dcb878f28 100644 --- a/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex +++ b/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex @@ -15,13 +15,7 @@ defmodule Explorer.SmartContract.PublisherWorker do result {:error, changeset} -> - errors = - changeset.errors - |> Enum.into(%{}, fn {field, {message, _}} -> - {field, message} - end) - - {:error, errors} + {:error, changeset} end EventsPublisher.broadcast([{:contract_verification_result, {address_hash, result}}], :on_demand) From d000a51c6affe844c51eed80be36daf5c7f426b9 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Wed, 3 Jul 2019 15:37:09 +0300 Subject: [PATCH 09/39] fix gettext --- apps/block_scout_web/priv/gettext/default.pot | 55 ++++++++++-------- .../priv/gettext/en/LC_MESSAGES/default.po | 57 ++++++++++--------- 2 files changed, 61 insertions(+), 51 deletions(-) diff --git a/apps/block_scout_web/priv/gettext/default.pot b/apps/block_scout_web/priv/gettext/default.pot index c263d8a6ce..b0fd95a641 100644 --- a/apps/block_scout_web/priv/gettext/default.pot +++ b/apps/block_scout_web/priv/gettext/default.pot @@ -197,7 +197,7 @@ msgid "Blocks Validated" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:247 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:253 #: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:47 msgid "Cancel" msgstr "" @@ -225,7 +225,7 @@ msgid "Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:34 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:40 msgid "Compiler" msgstr "" @@ -263,7 +263,7 @@ msgid "Contract ABI" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:12 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:18 #: lib/block_scout_web/views/address_view.ex:97 msgid "Contract Address" msgstr "" @@ -286,7 +286,7 @@ msgid "Contract Creation" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:23 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:29 msgid "Contract Name" msgstr "" @@ -560,7 +560,7 @@ msgid "Name" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:61 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:67 msgid "No" msgstr "" @@ -651,7 +651,7 @@ msgid "Request URL" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:244 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:250 msgid "Reset" msgstr "" @@ -939,7 +939,7 @@ msgid "Verify & Publish" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:243 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:249 msgid "Verify & publish" msgstr "" @@ -989,7 +989,7 @@ msgid "Wei" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:66 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:72 msgid "Yes" msgstr "" @@ -1062,7 +1062,7 @@ msgid "Loading..." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:241 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:247 msgid "Loading...." msgstr "" @@ -1425,7 +1425,7 @@ msgid "Genesis Block" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:112 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:118 msgid "Contract Libraries" msgstr "" @@ -1488,7 +1488,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_contract/index.html.eex:35 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:45 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:51 msgid "EVM Version" msgstr "" @@ -1519,7 +1519,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_contract/index.html.eex:45 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:77 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:83 msgid "Optimization runs" msgstr "" @@ -1655,35 +1655,35 @@ msgid "Topic" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:98 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:104 msgid "ABI-encoded Constructor Arguments (if required by the contract)" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:87 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:93 msgid "Enter the Solidity Contract Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:127 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:149 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:171 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:193 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:215 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:133 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:155 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:177 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:199 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:221 msgid "Library Address" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:117 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:139 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:161 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:183 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:205 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:123 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:145 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:167 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:189 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:211 msgid "Library Name" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:3 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:9 msgid "New Smart Contract Verification" msgstr "" @@ -1797,3 +1797,8 @@ msgstr "" #: lib/block_scout_web/templates/layout/_network_selector.html.eex:12 msgid "Use the search box to find a hosted network, or select from the list of available networks below." msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:4 +msgid "Connection Lost" +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 2a85e8470d..efe9a56ff0 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 @@ -197,7 +197,7 @@ msgid "Blocks Validated" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:247 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:253 #: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:47 msgid "Cancel" msgstr "" @@ -225,7 +225,7 @@ msgid "Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:34 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:40 msgid "Compiler" msgstr "" @@ -263,7 +263,7 @@ msgid "Contract ABI" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:12 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:18 #: lib/block_scout_web/views/address_view.ex:97 msgid "Contract Address" msgstr "" @@ -286,7 +286,7 @@ msgid "Contract Creation" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:23 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:29 msgid "Contract Name" msgstr "" @@ -560,7 +560,7 @@ msgid "Name" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:61 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:67 msgid "No" msgstr "" @@ -651,7 +651,7 @@ msgid "Request URL" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:244 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:250 msgid "Reset" msgstr "" @@ -674,7 +674,7 @@ msgstr "" #, elixir-format #: -#: lib/block_scout_web/templates/address_token_balance/_token_balances.html.eex:28 +#: lib/block_scout_web/templates/address_token_balance/_token_balances.html.eex:30 msgid "Search tokens" msgstr "" @@ -939,7 +939,7 @@ msgid "Verify & Publish" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:243 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:249 msgid "Verify & publish" msgstr "" @@ -989,7 +989,7 @@ msgid "Wei" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:66 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:72 msgid "Yes" msgstr "" @@ -1062,7 +1062,7 @@ msgid "Loading..." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:241 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:247 msgid "Loading...." msgstr "" @@ -1425,7 +1425,7 @@ msgid "Genesis Block" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:112 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:118 msgid "Contract Libraries" msgstr "" @@ -1488,7 +1488,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_contract/index.html.eex:35 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:45 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:51 msgid "EVM Version" msgstr "" @@ -1519,7 +1519,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_contract/index.html.eex:45 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:77 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:83 msgid "Optimization runs" msgstr "" @@ -1655,35 +1655,35 @@ msgid "Topic" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:98 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:104 msgid "ABI-encoded Constructor Arguments (if required by the contract)" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:87 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:93 msgid "Enter the Solidity Contract Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:127 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:149 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:171 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:193 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:215 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:133 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:155 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:177 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:199 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:221 msgid "Library Address" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:117 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:139 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:161 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:183 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:205 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:123 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:145 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:167 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:189 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:211 msgid "Library Name" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:3 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:9 msgid "New Smart Contract Verification" msgstr "" @@ -1797,3 +1797,8 @@ msgstr "" #: lib/block_scout_web/templates/layout/_network_selector.html.eex:12 msgid "Use the search box to find a hosted network, or select from the list of available networks below." msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:4 +msgid "Connection Lost" +msgstr "" From 3e045a8eb5ae134c18772a1babb1a54a8e32f948 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Wed, 3 Jul 2019 15:41:53 +0300 Subject: [PATCH 10/39] fix credo --- apps/block_scout_web/lib/block_scout_web/notifier.ex | 2 +- apps/explorer/lib/explorer/smart_contract/publisher_worker.ex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/block_scout_web/lib/block_scout_web/notifier.ex b/apps/block_scout_web/lib/block_scout_web/notifier.ex index eb7149e299..1002f51eac 100644 --- a/apps/block_scout_web/lib/block_scout_web/notifier.ex +++ b/apps/block_scout_web/lib/block_scout_web/notifier.ex @@ -8,8 +8,8 @@ defmodule BlockScoutWeb.Notifier do alias Explorer.{Chain, Market, Repo} alias Explorer.Chain.{Address, InternalTransaction, Transaction} alias Explorer.Counters.AverageBlockTime - alias Explorer.SmartContract.{Solidity.CodeCompiler, Solidity.CompilerVersion} alias Explorer.ExchangeRates.Token + alias Explorer.SmartContract.{Solidity.CodeCompiler, Solidity.CompilerVersion} alias Phoenix.View def handle_event({:chain_event, :addresses, type, addresses}) when type in [:realtime, :on_demand] do diff --git a/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex b/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex index 0dcb878f28..b507b9f158 100644 --- a/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex +++ b/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex @@ -5,8 +5,8 @@ defmodule Explorer.SmartContract.PublisherWorker do use Que.Worker, concurrency: 5 - alias Explorer.SmartContract.Publisher alias Explorer.Chain.Events.Publisher, as: EventsPublisher + alias Explorer.SmartContract.Publisher def perform({address_hash, params, external_libraries}) do result = From ca479aa06de269e6bfa5ff6c7fe39eb05cb6943b Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Wed, 3 Jul 2019 15:47:05 +0300 Subject: [PATCH 11/39] fix js style --- .../assets/js/pages/verification_form.js | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/apps/block_scout_web/assets/js/pages/verification_form.js b/apps/block_scout_web/assets/js/pages/verification_form.js index b749f24b64..535d353163 100644 --- a/apps/block_scout_web/assets/js/pages/verification_form.js +++ b/apps/block_scout_web/assets/js/pages/verification_form.js @@ -2,8 +2,7 @@ import $ from 'jquery' import _ from 'lodash' import URI from 'urijs' import humps from 'humps' -import numeral from 'numeral' -import socket, { subscribeChannel } from '../socket' +import { subscribeChannel } from '../socket' import { createStore, connectElements } from '../lib/redux_helpers.js' export const initialState = { @@ -25,14 +24,13 @@ export function reducer (state = initialState, action) { channelDisconnected: true }) } - case 'RECEIVED_VERIFICATION_RESULT': { - console.log(action.msg) - if (action.msg.verificationResult === "ok") { - return window.location.replace(window.location.href.split('/contract_verifications')[0] + '/contracts') + case 'RECEIVED_VERIFICATION_RESULT': { + if (action.msg.verificationResult === 'ok') { + return window.location.replace(window.location.href.split('/contract_verifications')[0] + '/contracts') } else { return Object.assign({}, state, { - newForm: action.msg.verificationResult - }) + newForm: action.msg.verificationResult + }) } } default: @@ -48,8 +46,8 @@ const elements = { }, '[data-page="contract-verification"]': { render ($el, state) { - if (state.newForm) { - return $el.replaceWith(state.newForm) + if (state.newForm) { + return $el.replaceWith(state.newForm) } } } @@ -74,7 +72,7 @@ if ($contractVerificationPage.length) { addressChannel.onError(() => store.dispatch({ type: 'CHANNEL_DISCONNECTED' })) - addressChannel.on("verification", (msg) => store.dispatch({ + addressChannel.on('verification', (msg) => store.dispatch({ type: 'RECEIVED_VERIFICATION_RESULT', msg: humps.camelizeKeys(msg) })) From 5792acfc66c85d691b63d7f0518d82568b9f10c4 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Wed, 3 Jul 2019 18:28:14 +0300 Subject: [PATCH 12/39] use get method --- apps/block_scout_web/lib/block_scout_web/router.ex | 4 +++- .../templates/address_contract_verification/new.html.eex | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/block_scout_web/lib/block_scout_web/router.ex b/apps/block_scout_web/lib/block_scout_web/router.ex index 3a0b76b8ae..2b577722be 100644 --- a/apps/block_scout_web/lib/block_scout_web/router.ex +++ b/apps/block_scout_web/lib/block_scout_web/router.ex @@ -159,10 +159,12 @@ defmodule BlockScoutWeb.Router do resources( "/contract_verifications", AddressContractVerificationController, - only: [:new, :create], + only: [:new], as: :verify_contract ) + get("/contract_verifications", AddressContractVerificationController, :create) + resources( "/read_contract", AddressReadContractController, diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex index 2f00c515ea..80356dc0ea 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex @@ -10,7 +10,7 @@ <%= form_for @changeset, "/address/#{@address_hash}/contract_verifications", - [], + [method: :get], fn f -> %>
From 830fa56d8d880cae3c7309b17da2d190537399dc Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Thu, 4 Jul 2019 10:01:51 +0300 Subject: [PATCH 13/39] remove request idle timeout configuration --- apps/block_scout_web/config/config.exs | 5 ----- apps/block_scout_web/config/dev.exs | 6 ------ 2 files changed, 11 deletions(-) diff --git a/apps/block_scout_web/config/config.exs b/apps/block_scout_web/config/config.exs index 28d142eb5c..836a21ba02 100644 --- a/apps/block_scout_web/config/config.exs +++ b/apps/block_scout_web/config/config.exs @@ -35,11 +35,6 @@ config :block_scout_web, BlockScoutWeb.Counters.BlocksIndexedCounter, enabled: t # Configures the endpoint config :block_scout_web, BlockScoutWeb.Endpoint, instrumenters: [BlockScoutWeb.Prometheus.Instrumenter, SpandexPhoenix.Instrumenter], - http: [ - protocol_options: [ - idle_timeout: 90_000 - ] - ], url: [ host: System.get_env("BLOCKSCOUT_HOST") || "localhost", path: System.get_env("NETWORK_PATH") || "/" diff --git a/apps/block_scout_web/config/dev.exs b/apps/block_scout_web/config/dev.exs index ce955a764c..8e8aaaddcb 100644 --- a/apps/block_scout_web/config/dev.exs +++ b/apps/block_scout_web/config/dev.exs @@ -16,15 +16,9 @@ port = config :block_scout_web, BlockScoutWeb.Endpoint, http: [ - protocol_options: [ - idle_timeout: 90_000 - ], port: port || 4000 ], https: [ - protocol_options: [ - idle_timeout: 90_000 - ], port: (port && port + 1) || 4001, cipher_suite: :strong, certfile: System.get_env("CERTFILE") || "priv/cert/selfsigned.pem", From 5cc777a14ec9ed12989977be0c9d0a311c8ff644 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Thu, 4 Jul 2019 10:15:18 +0300 Subject: [PATCH 14/39] add CHANGELOG entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ede02ddea1..bf6888e8f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ ### Chore +- [#2293](https://github.com/poanetwork/blockscout/pull/2293) - remove request idle timeout configuration + ## 2.0.1-beta From 789e17218f646adfc991c94b2cfd3944dbfce68f Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Thu, 4 Jul 2019 16:43:02 +0300 Subject: [PATCH 15/39] remove unused field from websocket data --- apps/block_scout_web/lib/block_scout_web/notifier.ex | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/block_scout_web/lib/block_scout_web/notifier.ex b/apps/block_scout_web/lib/block_scout_web/notifier.ex index 1002f51eac..bac301f757 100644 --- a/apps/block_scout_web/lib/block_scout_web/notifier.ex +++ b/apps/block_scout_web/lib/block_scout_web/notifier.ex @@ -51,7 +51,6 @@ defmodule BlockScoutWeb.Notifier do "addresses:#{address_hash}", "verification_result", %{ - address_hash: address_hash, result: contract_verification_result } ) From 8acd1c4fd2c0e6bdca0f5bdc19be15726832958b Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Thu, 4 Jul 2019 16:44:10 +0300 Subject: [PATCH 16/39] fix typo --- .dialyzer-ignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.dialyzer-ignore b/.dialyzer-ignore index 60465de4e8..6b7c1ae65c 100644 --- a/.dialyzer-ignore +++ b/.dialyzer-ignore @@ -5,5 +5,5 @@ apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex:400: Function timestamp_to_datetim apps/explorer/lib/explorer/repo/prometheus_logger.ex:8: Function microseconds_time/1 has no local return apps/explorer/lib/explorer/repo/prometheus_logger.ex:8: The call 'Elixir.System':convert_time_unit(__@1::any(),'native','microseconds') breaks the contract (integer(),time_unit() | 'native',time_unit() | 'native') -> integer() apps/block_scout_web/lib/block_scout_web/views/layout_view.ex:174: The call 'Elixir.Poison.Parser':'parse!'(any(),#{'keys':='atoms!'}) will never return since the success typing is (binary() | maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | []),[{atom(),_}]) -> 'false' | 'nil' | 'true' | binary() | ['false' | 'nil' | 'true' | binary() | [any()] | number() | map()] | number() | map() and the contract is (iodata(),'Elixir.Keyword':t()) -> t() -pps/explorer/lib/explorer/smart_contract/publisher_worker.ex:6: The pattern 'false' can never match the type 'true' +apps/explorer/lib/explorer/smart_contract/publisher_worker.ex:6: The pattern 'false' can never match the type 'true' apps/explorer/lib/explorer/smart_contract/publisher_worker.ex:6: The test 5 == 'infinity' can never evaluate to 'true' \ No newline at end of file From 3ee75c680b6c5ac6cba393b4c95be78e8ab2a263 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Fri, 5 Jul 2019 09:30:32 +0300 Subject: [PATCH 17/39] increase headers, query string for smart contract verification --- apps/block_scout_web/config/config.exs | 6 +++++- apps/block_scout_web/config/dev.exs | 12 ++++++++++-- apps/block_scout_web/lib/block_scout_web/endpoint.ex | 3 ++- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/apps/block_scout_web/config/config.exs b/apps/block_scout_web/config/config.exs index 28d142eb5c..ca21c4fbad 100644 --- a/apps/block_scout_web/config/config.exs +++ b/apps/block_scout_web/config/config.exs @@ -37,7 +37,11 @@ config :block_scout_web, BlockScoutWeb.Endpoint, instrumenters: [BlockScoutWeb.Prometheus.Instrumenter, SpandexPhoenix.Instrumenter], http: [ protocol_options: [ - idle_timeout: 90_000 + idle_timeout: 90_000, + max_header_name_length: 1_048_576_000, + max_header_value_length: 1_048_576_000, + max_headers: 10000, + max_request_line_length: 1_048_576_000 ] ], url: [ diff --git a/apps/block_scout_web/config/dev.exs b/apps/block_scout_web/config/dev.exs index ce955a764c..f8d0f25fb9 100644 --- a/apps/block_scout_web/config/dev.exs +++ b/apps/block_scout_web/config/dev.exs @@ -17,13 +17,21 @@ port = config :block_scout_web, BlockScoutWeb.Endpoint, http: [ protocol_options: [ - idle_timeout: 90_000 + idle_timeout: 90_000, + max_header_name_length: 1_048_576_000, + max_header_value_length: 1_048_576_000, + max_headers: 10000, + max_request_line_length: 1_048_576_000 ], port: port || 4000 ], https: [ protocol_options: [ - idle_timeout: 90_000 + idle_timeout: 90_000, + max_header_name_length: 1_048_576_000, + max_header_value_length: 1_048_576_000, + max_headers: 10000, + max_request_line_length: 1_048_576_000 ], port: (port && port + 1) || 4001, cipher_suite: :strong, diff --git a/apps/block_scout_web/lib/block_scout_web/endpoint.ex b/apps/block_scout_web/lib/block_scout_web/endpoint.ex index ed2b49f3a3..41d4859d12 100644 --- a/apps/block_scout_web/lib/block_scout_web/endpoint.ex +++ b/apps/block_scout_web/lib/block_scout_web/endpoint.ex @@ -52,7 +52,8 @@ defmodule BlockScoutWeb.Endpoint do Plug.Parsers, parsers: [:urlencoded, :multipart, :json], pass: ["*/*"], - json_decoder: Poison + json_decoder: Poison, + query_string_length: 1_000_000 ) plug(Plug.MethodOverride) From 32243b0c4ed4bdefc4fd7ca9321762fcf315e5a0 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Mon, 8 Jul 2019 10:43:33 +0300 Subject: [PATCH 18/39] fix market history overriding --- .../market/history/source/crypto_compare.ex | 19 ++++--- apps/explorer/lib/explorer/market/market.ex | 7 ++- .../history/source/crypto_compare_test.exs | 54 +++++++++++++++++++ .../test/explorer/market/market_test.exs | 19 +++++++ 4 files changed, 91 insertions(+), 8 deletions(-) diff --git a/apps/explorer/lib/explorer/market/history/source/crypto_compare.ex b/apps/explorer/lib/explorer/market/history/source/crypto_compare.ex index 82bf3714d5..09959f6cca 100644 --- a/apps/explorer/lib/explorer/market/history/source/crypto_compare.ex +++ b/apps/explorer/lib/explorer/market/history/source/crypto_compare.ex @@ -48,13 +48,18 @@ defmodule Explorer.Market.History.Source.CryptoCompare do defp format_data(data) do json = Jason.decode!(data) - for item <- json["Data"] do - %{ - closing_price: Decimal.new(to_string(item["close"])), - date: date(item["time"]), - opening_price: Decimal.new(to_string(item["open"])) - } - end + items = + for item <- json["Data"] do + %{ + closing_price: Decimal.new(to_string(item["close"])), + date: date(item["time"]), + opening_price: Decimal.new(to_string(item["open"])) + } + end + + Enum.reject(items, fn item -> + Decimal.equal?(item.closing_price, 0) && Decimal.equal?(item.opening_price, 0) + end) end @spec history_url(non_neg_integer()) :: String.t() diff --git a/apps/explorer/lib/explorer/market/market.ex b/apps/explorer/lib/explorer/market/market.ex index f3e35f7d64..a9be83a5c8 100644 --- a/apps/explorer/lib/explorer/market/market.ex +++ b/apps/explorer/lib/explorer/market/market.ex @@ -40,7 +40,12 @@ defmodule Explorer.Market do @doc false def bulk_insert_history(records) do - Repo.insert_all(MarketHistory, records, on_conflict: :replace_all, conflict_target: [:date]) + records_without_zeroes = + Enum.reject(records, fn item -> + Decimal.equal?(item.closing_price, 0) && Decimal.equal?(item.opening_price, 0) + end) + + Repo.insert_all(MarketHistory, records_without_zeroes, on_conflict: :replace_all, conflict_target: [:date]) end def add_price(%{symbol: symbol} = token) do diff --git a/apps/explorer/test/explorer/market/history/source/crypto_compare_test.exs b/apps/explorer/test/explorer/market/history/source/crypto_compare_test.exs index 9b662549c2..1fc4223f72 100644 --- a/apps/explorer/test/explorer/market/history/source/crypto_compare_test.exs +++ b/apps/explorer/test/explorer/market/history/source/crypto_compare_test.exs @@ -86,5 +86,59 @@ defmodule Explorer.Market.History.Source.CryptoCompareTest do assert :error == CryptoCompare.fetch_history(3) end + + test "rejects empty prices", %{bypass: bypass} do + json = """ + { + "Response": "Success", + "Type": 100, + "Aggregated": false, + "Data": [ + { + "time": 1524528000, + "close": 0, + "high": 9741.91, + "low": 8957.68, + "open": 0, + "volumefrom": 136352.05, + "volumeto": 1276464750.74 + }, + { + "time": 1524614400, + "close": 0, + "high": 9765.23, + "low": 8757.06, + "open": 0, + "volumefrom": 192797.41, + "volumeto": 1779806222.98 + }, + { + "time": 1524700800, + "close": 8804.32, + "high": 8965.84, + "low": 8669.38, + "open": 8873.57, + "volumefrom": 74704.5, + "volumeto": 661168891 + } + ], + "TimeTo": 1524700800, + "TimeFrom": 1523836800, + "FirstValueInArray": true, + "ConversionType": { + "type": "direct", + "conversionSymbol": "" + } + } + """ + + Bypass.expect(bypass, fn conn -> Conn.resp(conn, 200, json) end) + + expected = [ + %{closing_price: Decimal.from_float(8804.32), date: ~D[2018-04-26], opening_price: Decimal.from_float(8873.57)} + ] + + assert {:ok, expected} == CryptoCompare.fetch_history(3) + end end end diff --git a/apps/explorer/test/explorer/market/market_test.exs b/apps/explorer/test/explorer/market/market_test.exs index 7e399ea4cd..584f1a35be 100644 --- a/apps/explorer/test/explorer/market/market_test.exs +++ b/apps/explorer/test/explorer/market/market_test.exs @@ -72,6 +72,25 @@ defmodule Explorer.MarketTest do assert missing_records == %{} end + test "doesn't replace existing records with zeros" do + date = ~D[2018-04-01] + + {:ok, old_record} = + Repo.insert(%MarketHistory{date: date, closing_price: Decimal.new(1), opening_price: Decimal.new(1)}) + + new_record = %{ + date: date, + closing_price: Decimal.new(0), + opening_price: Decimal.new(0) + } + + Market.bulk_insert_history([new_record]) + + fetched_record = Repo.get_by(MarketHistory, date: date) + assert fetched_record.closing_price == old_record.closing_price + assert fetched_record.opening_price == old_record.opening_price + end + test "overrides existing records on date conflict" do date = ~D[2018-04-01] Repo.insert(%MarketHistory{date: date}) From 96009699af5b0c2ee633846fe2fabbdc833487ac Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Mon, 8 Jul 2019 10:46:22 +0300 Subject: [PATCH 19/39] add CHANGELOG entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d4e6f755f..2b4440658c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - [#2294](https://github.com/poanetwork/blockscout/pull/2294) - add healthy block period checking endpoint ### Fixes +- [#2311](https://github.com/poanetwork/blockscout/pull/2311) - fix market history overriding with zeroes - [#2299](https://github.com/poanetwork/blockscout/pull/2299) - fix interpolation in error message - [#2303](https://github.com/poanetwork/blockscout/pull/2303) - fix transaction csv download link - [#2304](https://github.com/poanetwork/blockscout/pull/2304) - footer grid fix for md resolution From 2f91e8c3804c43d0d4daf0152ac55bca28e52e81 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Mon, 8 Jul 2019 12:36:59 +0300 Subject: [PATCH 20/39] add new endpoing for contract verification --- .../address_contract_verification_controller.ex | 3 +-- .../block_scout_web/lib/block_scout_web/router.ex | 15 +++++++++++++-- .../address_contract_verification/new.html.eex | 4 ++-- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_verification_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_verification_controller.ex index ee8ef7b635..e4aa87eae4 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_verification_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_verification_controller.ex @@ -24,12 +24,11 @@ defmodule BlockScoutWeb.AddressContractVerificationController do def create( conn, %{ - "address_id" => address_hash_string, "smart_contract" => smart_contract, "external_libraries" => external_libraries } ) do - Que.add(PublisherWorker, {address_hash_string, smart_contract, external_libraries}) + Que.add(PublisherWorker, {smart_contract["address_hash"], smart_contract, external_libraries}) send_resp(conn, 204, "") end diff --git a/apps/block_scout_web/lib/block_scout_web/router.ex b/apps/block_scout_web/lib/block_scout_web/router.ex index e01d121eb8..4b5471cb52 100644 --- a/apps/block_scout_web/lib/block_scout_web/router.ex +++ b/apps/block_scout_web/lib/block_scout_web/router.ex @@ -18,6 +18,13 @@ defmodule BlockScoutWeb.Router do plug(:accepts, ["json"]) end + pipeline :contract_verification do + plug(:accepts, ["html"]) + plug(:fetch_session) + plug(:fetch_flash) + plug(BlockScoutWeb.CSPHeader) + end + scope "/api/v1", BlockScoutWeb.API.V1, as: :api_v1 do pipe_through(:api) @@ -29,6 +36,12 @@ defmodule BlockScoutWeb.Router do resources("/verified_smart_contracts", VerifiedSmartContractController, only: [:create]) end + scope "/verify_smart_contract" do + pipe_through(:contract_verification) + + post("/contract_verifications", BlockScoutWeb.AddressContractVerificationController, :create) + end + scope "/api", BlockScoutWeb.API.RPC do pipe_through(:api) @@ -165,8 +178,6 @@ defmodule BlockScoutWeb.Router do as: :verify_contract ) - get("/contract_verifications", AddressContractVerificationController, :create) - resources( "/read_contract", AddressReadContractController, diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex index 80356dc0ea..6d56ecb51f 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex @@ -9,8 +9,8 @@

<%= gettext "New Smart Contract Verification" %>

<%= form_for @changeset, - "/address/#{@address_hash}/contract_verifications", - [method: :get], + "/verify_smart_contract/contract_verifications", + [], fn f -> %>
From f7fabb4b3f6f5d6494adc257f359f361a1490938 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Mon, 8 Jul 2019 13:42:13 +0300 Subject: [PATCH 21/39] use api pipe --- apps/block_scout_web/lib/block_scout_web/router.ex | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/apps/block_scout_web/lib/block_scout_web/router.ex b/apps/block_scout_web/lib/block_scout_web/router.ex index 4b5471cb52..4f5a8e1bed 100644 --- a/apps/block_scout_web/lib/block_scout_web/router.ex +++ b/apps/block_scout_web/lib/block_scout_web/router.ex @@ -18,13 +18,6 @@ defmodule BlockScoutWeb.Router do plug(:accepts, ["json"]) end - pipeline :contract_verification do - plug(:accepts, ["html"]) - plug(:fetch_session) - plug(:fetch_flash) - plug(BlockScoutWeb.CSPHeader) - end - scope "/api/v1", BlockScoutWeb.API.V1, as: :api_v1 do pipe_through(:api) @@ -37,7 +30,7 @@ defmodule BlockScoutWeb.Router do end scope "/verify_smart_contract" do - pipe_through(:contract_verification) + pipe_through(:api) post("/contract_verifications", BlockScoutWeb.AddressContractVerificationController, :create) end From ed4b84b8fe334cb07757b2101e9c7a04a79c8f39 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Mon, 8 Jul 2019 13:49:06 +0300 Subject: [PATCH 22/39] remove custom parameters --- apps/block_scout_web/config/config.exs | 6 +----- apps/block_scout_web/config/dev.exs | 12 ++---------- apps/block_scout_web/lib/block_scout_web/endpoint.ex | 3 +-- 3 files changed, 4 insertions(+), 17 deletions(-) diff --git a/apps/block_scout_web/config/config.exs b/apps/block_scout_web/config/config.exs index ca21c4fbad..28d142eb5c 100644 --- a/apps/block_scout_web/config/config.exs +++ b/apps/block_scout_web/config/config.exs @@ -37,11 +37,7 @@ config :block_scout_web, BlockScoutWeb.Endpoint, instrumenters: [BlockScoutWeb.Prometheus.Instrumenter, SpandexPhoenix.Instrumenter], http: [ protocol_options: [ - idle_timeout: 90_000, - max_header_name_length: 1_048_576_000, - max_header_value_length: 1_048_576_000, - max_headers: 10000, - max_request_line_length: 1_048_576_000 + idle_timeout: 90_000 ] ], url: [ diff --git a/apps/block_scout_web/config/dev.exs b/apps/block_scout_web/config/dev.exs index f8d0f25fb9..ce955a764c 100644 --- a/apps/block_scout_web/config/dev.exs +++ b/apps/block_scout_web/config/dev.exs @@ -17,21 +17,13 @@ port = config :block_scout_web, BlockScoutWeb.Endpoint, http: [ protocol_options: [ - idle_timeout: 90_000, - max_header_name_length: 1_048_576_000, - max_header_value_length: 1_048_576_000, - max_headers: 10000, - max_request_line_length: 1_048_576_000 + idle_timeout: 90_000 ], port: port || 4000 ], https: [ protocol_options: [ - idle_timeout: 90_000, - max_header_name_length: 1_048_576_000, - max_header_value_length: 1_048_576_000, - max_headers: 10000, - max_request_line_length: 1_048_576_000 + idle_timeout: 90_000 ], port: (port && port + 1) || 4001, cipher_suite: :strong, diff --git a/apps/block_scout_web/lib/block_scout_web/endpoint.ex b/apps/block_scout_web/lib/block_scout_web/endpoint.ex index 41d4859d12..ed2b49f3a3 100644 --- a/apps/block_scout_web/lib/block_scout_web/endpoint.ex +++ b/apps/block_scout_web/lib/block_scout_web/endpoint.ex @@ -52,8 +52,7 @@ defmodule BlockScoutWeb.Endpoint do Plug.Parsers, parsers: [:urlencoded, :multipart, :json], pass: ["*/*"], - json_decoder: Poison, - query_string_length: 1_000_000 + json_decoder: Poison ) plug(Plug.MethodOverride) From 2c35ec15072c914e58165d8d3ec6bdff6df911f8 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Tue, 9 Jul 2019 12:15:14 +0300 Subject: [PATCH 23/39] enable spinner on addional clicks --- .../assets/js/pages/verification_form.js | 16 +++++++++++++--- .../address_contract_verification/new.html.eex | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/apps/block_scout_web/assets/js/pages/verification_form.js b/apps/block_scout_web/assets/js/pages/verification_form.js index 535d353163..92d2b8e21a 100644 --- a/apps/block_scout_web/assets/js/pages/verification_form.js +++ b/apps/block_scout_web/assets/js/pages/verification_form.js @@ -46,9 +46,14 @@ const elements = { }, '[data-page="contract-verification"]': { render ($el, state) { - if (state.newForm) { - return $el.replaceWith(state.newForm) - } + if (state.newForm) { + $el.replaceWith(state.newForm) + $('button[data-button-loading="animation"]').click(event => { + $('#loading').removeClass('d-none') + }) + return $el + } + return $el } } } @@ -59,6 +64,7 @@ if ($contractVerificationPage.length) { const store = createStore(reducer) const addressHash = $('#smart_contract_address_hash').val() const { filter, blockNumber } = humps.camelizeKeys(URI(window.location).query(true)) + store.dispatch({ type: 'PAGE_LOAD', addressHash, @@ -76,4 +82,8 @@ if ($contractVerificationPage.length) { type: 'RECEIVED_VERIFICATION_RESULT', msg: humps.camelizeKeys(msg) })) + + $('button[data-button-loading="animation"]').click(event => { + $('#loading').removeClass('d-none') + }) } diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex index 6d56ecb51f..e939de455a 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex @@ -246,7 +246,7 @@ <%= gettext("Loading....") %> - <%= submit gettext("Verify & publish"), class: "btn-full-primary mr-2", "data-loading": "animation" %> + <%= submit gettext("Verify & publish"), class: "btn-full-primary mr-2", "data-button-loading": "animation" %> <%= reset gettext("Reset"), class: "btn-line mr-2 js-smart-contract-form-reset" %> <%= link( From 12742fa9e69f8bad4ad2a8b1bab43e71b281076d Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Tue, 9 Jul 2019 12:35:35 +0300 Subject: [PATCH 24/39] fix js style --- .../assets/js/pages/verification_form.js | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/block_scout_web/assets/js/pages/verification_form.js b/apps/block_scout_web/assets/js/pages/verification_form.js index 92d2b8e21a..28a654d999 100644 --- a/apps/block_scout_web/assets/js/pages/verification_form.js +++ b/apps/block_scout_web/assets/js/pages/verification_form.js @@ -46,14 +46,14 @@ const elements = { }, '[data-page="contract-verification"]': { render ($el, state) { - if (state.newForm) { - $el.replaceWith(state.newForm) - $('button[data-button-loading="animation"]').click(event => { - $('#loading').removeClass('d-none') - }) - return $el - } - return $el + if (state.newForm) { + $el.replaceWith(state.newForm) + $('button[data-button-loading="animation"]').click(event => { + $('#loading').removeClass('d-none') + }) + return $el + } + return $el } } } @@ -83,7 +83,7 @@ if ($contractVerificationPage.length) { msg: humps.camelizeKeys(msg) })) - $('button[data-button-loading="animation"]').click(event => { - $('#loading').removeClass('d-none') - }) + $('button[data-button-loading="animation"]').click(event => { + $('#loading').removeClass('d-none') + }) } From da775b07b7bacc8e96a5af8a0ad19d226b8f6f24 Mon Sep 17 00:00:00 2001 From: pasqu4le Date: Tue, 9 Jul 2019 12:21:18 +0200 Subject: [PATCH 25/39] Group Explorer caches Problem: a bunch of different caches are under the Explorer.Chain namespaces, cluttering the codebase Solution: create a subdirectory and collect them all under the Explorer.Chain.Cache namespace --- CHANGELOG.md | 1 + .../controllers/api/rpc/block_controller.ex | 4 +- .../block_scout_web/test/support/conn_case.ex | 4 +- .../test/support/feature_case.ex | 4 +- apps/explorer/config/config.exs | 2 +- apps/explorer/config/test.exs | 2 +- apps/explorer/lib/explorer/application.ex | 26 ++++---- apps/explorer/lib/explorer/chain.ex | 32 +++++----- apps/explorer/lib/explorer/chain/address.ex | 5 +- .../block_count.ex} | 2 +- .../block_number.ex} | 2 +- .../{blocks_cache.ex => cache/blocks.ex} | 2 +- .../net_version.ex} | 2 +- .../transaction_count.ex} | 2 +- .../transactions.ex} | 2 +- .../explorer/lib/explorer/chain/supply/rsk.ex | 5 +- .../chain/block_number_cache_test.exs | 59 ------------------- .../block_count_test.exs} | 24 ++++---- .../chain/cache/block_number_test.exs | 59 +++++++++++++++++++ .../blocks_test.exs} | 36 +++++------ .../chain/cache/transaction_count_test.exs | 54 +++++++++++++++++ .../transactions_test.exs} | 34 +++++------ .../chain/transaction_count_cache_test.exs | 54 ----------------- .../market/market_history_cache_test.exs | 4 +- .../test/explorer/market/market_test.exs | 8 +-- apps/explorer/test/support/data_case.ex | 10 ++-- apps/indexer/lib/indexer/block/fetcher.ex | 10 ++-- .../indexer/fetcher/coin_balance_on_demand.ex | 5 +- 28 files changed, 232 insertions(+), 222 deletions(-) rename apps/explorer/lib/explorer/chain/{block_count_cache.ex => cache/block_count.ex} (98%) rename apps/explorer/lib/explorer/chain/{block_number_cache.ex => cache/block_number.ex} (97%) rename apps/explorer/lib/explorer/chain/{blocks_cache.ex => cache/blocks.ex} (98%) rename apps/explorer/lib/explorer/chain/{net_version_cache.ex => cache/net_version.ex} (94%) rename apps/explorer/lib/explorer/chain/{transaction_count_cache.ex => cache/transaction_count.ex} (98%) rename apps/explorer/lib/explorer/chain/{transactions_cache.ex => cache/transactions.ex} (98%) delete mode 100644 apps/explorer/test/explorer/chain/block_number_cache_test.exs rename apps/explorer/test/explorer/chain/{block_count_cache_test.exs => cache/block_count_test.exs} (52%) create mode 100644 apps/explorer/test/explorer/chain/cache/block_number_test.exs rename apps/explorer/test/explorer/chain/{blocks_cache_test.exs => cache/blocks_test.exs} (65%) create mode 100644 apps/explorer/test/explorer/chain/cache/transaction_count_test.exs rename apps/explorer/test/explorer/chain/{transactions_cache_test.exs => cache/transactions_test.exs} (70%) delete mode 100644 apps/explorer/test/explorer/chain/transaction_count_cache_test.exs diff --git a/CHANGELOG.md b/CHANGELOG.md index 48f8b3045f..cf4eb708d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - [#2291](https://github.com/poanetwork/blockscout/pull/2291) - dashboard fix for md resolution, transactions load fix, block info row fix, addresses page issue, check mark issue ### Chore +- [#2323](https://github.com/poanetwork/blockscout/pull/2323) - Group Explorer caches - [#2302](https://github.com/poanetwork/blockscout/pull/2302) - fix names for xDai source - [#2289](https://github.com/poanetwork/blockscout/pull/2289) - Optional websockets for dev environment - [#2307](https://github.com/poanetwork/blockscout/pull/2307) - add GoJoy to README diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/block_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/block_controller.ex index 8beb8ea8ea..91569a96da 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/block_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/block_controller.ex @@ -3,7 +3,7 @@ defmodule BlockScoutWeb.API.RPC.BlockController do alias BlockScoutWeb.Chain, as: ChainWeb alias Explorer.Chain - alias Explorer.Chain.BlockNumberCache + alias Explorer.Chain.Cache.BlockNumber def getblockreward(conn, params) do with {:block_param, {:ok, unsafe_block_number}} <- {:block_param, Map.fetch(params, "blockno")}, @@ -27,7 +27,7 @@ defmodule BlockScoutWeb.API.RPC.BlockController do def eth_block_number(conn, params) do id = Map.get(params, "id", 1) - max_block_number = BlockNumberCache.max_number() + max_block_number = BlockNumber.max_number() render(conn, :eth_block_number, number: max_block_number, id: id) end diff --git a/apps/block_scout_web/test/support/conn_case.ex b/apps/block_scout_web/test/support/conn_case.ex index d0b9b066a1..ca486b33c2 100644 --- a/apps/block_scout_web/test/support/conn_case.ex +++ b/apps/block_scout_web/test/support/conn_case.ex @@ -38,8 +38,8 @@ defmodule BlockScoutWeb.ConnCase do Ecto.Adapters.SQL.Sandbox.mode(Explorer.Repo, {:shared, self()}) end - Supervisor.terminate_child(Explorer.Supervisor, {ConCache, Explorer.Chain.TransactionsCache.cache_name()}) - Supervisor.restart_child(Explorer.Supervisor, {ConCache, Explorer.Chain.TransactionsCache.cache_name()}) + Supervisor.terminate_child(Explorer.Supervisor, {ConCache, Explorer.Chain.Cache.Transactions.cache_name()}) + Supervisor.restart_child(Explorer.Supervisor, {ConCache, Explorer.Chain.Cache.Transactions.cache_name()}) {:ok, conn: Phoenix.ConnTest.build_conn()} end diff --git a/apps/block_scout_web/test/support/feature_case.ex b/apps/block_scout_web/test/support/feature_case.ex index b9e6f000d7..a9476a7b85 100644 --- a/apps/block_scout_web/test/support/feature_case.ex +++ b/apps/block_scout_web/test/support/feature_case.ex @@ -27,8 +27,8 @@ defmodule BlockScoutWeb.FeatureCase do Ecto.Adapters.SQL.Sandbox.mode(Explorer.Repo, {:shared, self()}) end - Supervisor.terminate_child(Explorer.Supervisor, {ConCache, Explorer.Chain.TransactionsCache.cache_name()}) - Supervisor.restart_child(Explorer.Supervisor, {ConCache, Explorer.Chain.TransactionsCache.cache_name()}) + Supervisor.terminate_child(Explorer.Supervisor, {ConCache, Explorer.Chain.Cache.Transactions.cache_name()}) + Supervisor.restart_child(Explorer.Supervisor, {ConCache, Explorer.Chain.Cache.Transactions.cache_name()}) metadata = Phoenix.Ecto.SQL.Sandbox.metadata_for(Explorer.Repo, self()) {:ok, session} = Wallaby.start_session(metadata: metadata) diff --git a/apps/explorer/config/config.exs b/apps/explorer/config/config.exs index 10012bbc67..65528753eb 100644 --- a/apps/explorer/config/config.exs +++ b/apps/explorer/config/config.exs @@ -19,7 +19,7 @@ config :explorer, config :explorer, Explorer.Counters.AverageBlockTime, enabled: true -config :explorer, Explorer.Chain.BlockNumberCache, enabled: true +config :explorer, Explorer.Chain.Cache.BlockNumber, enabled: true config :explorer, Explorer.ExchangeRates.Source.CoinMarketCap, pages: String.to_integer(System.get_env("COINMARKETCAP_PAGES") || "10") diff --git a/apps/explorer/config/test.exs b/apps/explorer/config/test.exs index f27fc3b350..d91f4dbdfc 100644 --- a/apps/explorer/config/test.exs +++ b/apps/explorer/config/test.exs @@ -13,7 +13,7 @@ config :explorer, Explorer.Repo, config :explorer, Explorer.ExchangeRates, enabled: false, store: :ets -config :explorer, Explorer.Chain.BlockNumberCache, enabled: false +config :explorer, Explorer.Chain.Cache.BlockNumber, enabled: false config :explorer, Explorer.KnownTokens, enabled: false, store: :ets diff --git a/apps/explorer/lib/explorer/application.ex b/apps/explorer/lib/explorer/application.ex index 5a6aa1795b..c1fb19f600 100644 --- a/apps/explorer/lib/explorer/application.ex +++ b/apps/explorer/lib/explorer/application.ex @@ -7,13 +7,13 @@ defmodule Explorer.Application do alias Explorer.Admin - alias Explorer.Chain.{ - BlockCountCache, - BlockNumberCache, - BlocksCache, - NetVersionCache, - TransactionCountCache, - TransactionsCache + alias Explorer.Chain.Cache.{ + BlockCount, + BlockNumber, + Blocks, + NetVersion, + TransactionCount, + Transactions } alias Explorer.Chain.Supply.RSK @@ -41,13 +41,13 @@ defmodule Explorer.Application do Explorer.SmartContract.SolcDownloader, {Registry, keys: :duplicate, name: Registry.ChainEvents, id: Registry.ChainEvents}, {Admin.Recovery, [[], [name: Admin.Recovery]]}, - {TransactionCountCache, [[], []]}, - {BlockCountCache, []}, - con_cache_child_spec(BlocksCache.cache_name()), - con_cache_child_spec(NetVersionCache.cache_name()), + {TransactionCount, [[], []]}, + {BlockCount, []}, + con_cache_child_spec(Blocks.cache_name()), + con_cache_child_spec(NetVersion.cache_name()), con_cache_child_spec(MarketHistoryCache.cache_name()), con_cache_child_spec(RSK.cache_name(), ttl_check_interval: :timer.minutes(1), global_ttl: :timer.minutes(30)), - con_cache_child_spec(TransactionsCache.cache_name()) + con_cache_child_spec(Transactions.cache_name()) ] children = base_children ++ configurable_children() @@ -56,7 +56,7 @@ defmodule Explorer.Application do res = Supervisor.start_link(children, opts) - BlockNumberCache.setup() + BlockNumber.setup() res end diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index fcad694a58..222b0bd5da 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -31,9 +31,6 @@ defmodule Explorer.Chain do Address.CurrentTokenBalance, Address.TokenBalance, Block, - BlockCountCache, - BlockNumberCache, - BlocksCache, Data, DecompiledSmartContract, Hash, @@ -45,12 +42,19 @@ defmodule Explorer.Chain do Token, TokenTransfer, Transaction, - TransactionCountCache, - TransactionsCache, Wei } alias Explorer.Chain.Block.{EmissionReward, Reward} + + alias Explorer.Chain.Cache.{ + BlockCount, + BlockNumber, + Blocks, + TransactionCount, + Transactions + } + alias Explorer.Chain.Import.Runner alias Explorer.Counters.AddressesWithBalanceCounter alias Explorer.Market.MarketHistoryCache @@ -266,7 +270,7 @@ defmodule Explorer.Chain do when is_list(options) do paging_options = Keyword.get(options, :paging_options) || %PagingOptions{page_size: 50} - {block_number, transaction_index, log_index} = paging_options.key || {BlockNumberCache.max_number(), 0, 0} + {block_number, transaction_index, log_index} = paging_options.key || {BlockNumber.max_number(), 0, 0} base_query = from(log in Log, @@ -1132,7 +1136,7 @@ defmodule Explorer.Chain do """ @spec indexed_ratio() :: Decimal.t() def indexed_ratio do - {min, max} = BlockNumberCache.min_and_max_numbers() + {min, max} = BlockNumber.min_and_max_numbers() case {min, max} do {0, 0} -> @@ -1214,12 +1218,12 @@ defmodule Explorer.Chain do block_type = Keyword.get(options, :block_type, "Block") if block_type == "Block" && !paging_options.key do - if BlocksCache.enough_elements?(paging_options.page_size) do - BlocksCache.blocks(paging_options.page_size) + if Blocks.enough_elements?(paging_options.page_size) do + Blocks.blocks(paging_options.page_size) else elements = fetch_blocks(block_type, paging_options, necessity_by_association) - BlocksCache.rewrite_cache(elements) + Blocks.rewrite_cache(elements) elements end @@ -1978,11 +1982,11 @@ defmodule Explorer.Chain do if is_nil(paging_options.key) do paging_options.page_size - |> TransactionsCache.take_enough() + |> Transactions.take_enough() |> case do nil -> transactions = fetch_recent_collated_transactions(paging_options, necessity_by_association) - TransactionsCache.update(transactions) + Transactions.update(transactions) transactions transactions -> @@ -2127,7 +2131,7 @@ defmodule Explorer.Chain do """ @spec transaction_estimated_count() :: non_neg_integer() def transaction_estimated_count do - cached_value = TransactionCountCache.value() + cached_value = TransactionCount.value() if is_nil(cached_value) do %Postgrex.Result{rows: [[rows]]} = @@ -2146,7 +2150,7 @@ defmodule Explorer.Chain do """ @spec block_estimated_count() :: non_neg_integer() def block_estimated_count do - cached_value = BlockCountCache.count() + cached_value = BlockCount.count() if is_nil(cached_value) do %Postgrex.Result{rows: [[count]]} = Repo.query!("SELECT reltuples FROM pg_class WHERE relname = 'blocks';") diff --git a/apps/explorer/lib/explorer/chain/address.ex b/apps/explorer/lib/explorer/chain/address.ex index 28b67f1d66..478c35deb1 100644 --- a/apps/explorer/lib/explorer/chain/address.ex +++ b/apps/explorer/lib/explorer/chain/address.ex @@ -16,13 +16,14 @@ defmodule Explorer.Chain.Address do DecompiledSmartContract, Hash, InternalTransaction, - NetVersionCache, SmartContract, Token, Transaction, Wei } + alias Explorer.Chain.Cache.NetVersion + @optional_attrs ~w(contract_code fetched_coin_balance fetched_coin_balance_block_number nonce decompiled verified)a @required_attrs ~w(hash)a @allowed_attrs @optional_attrs ++ @required_attrs @@ -169,7 +170,7 @@ defmodule Explorer.Chain.Address do end def rsk_checksum(hash) do - chain_id = NetVersionCache.version() + chain_id = NetVersion.version() string_hash = hash diff --git a/apps/explorer/lib/explorer/chain/block_count_cache.ex b/apps/explorer/lib/explorer/chain/cache/block_count.ex similarity index 98% rename from apps/explorer/lib/explorer/chain/block_count_cache.ex rename to apps/explorer/lib/explorer/chain/cache/block_count.ex index 8eaa1ccf58..8ba09cc86f 100644 --- a/apps/explorer/lib/explorer/chain/block_count_cache.ex +++ b/apps/explorer/lib/explorer/chain/cache/block_count.ex @@ -1,4 +1,4 @@ -defmodule Explorer.Chain.BlockCountCache do +defmodule Explorer.Chain.Cache.BlockCount do @moduledoc """ Cache for block count. """ diff --git a/apps/explorer/lib/explorer/chain/block_number_cache.ex b/apps/explorer/lib/explorer/chain/cache/block_number.ex similarity index 97% rename from apps/explorer/lib/explorer/chain/block_number_cache.ex rename to apps/explorer/lib/explorer/chain/cache/block_number.ex index 2f335c7a2c..5212117793 100644 --- a/apps/explorer/lib/explorer/chain/block_number_cache.ex +++ b/apps/explorer/lib/explorer/chain/cache/block_number.ex @@ -1,4 +1,4 @@ -defmodule Explorer.Chain.BlockNumberCache do +defmodule Explorer.Chain.Cache.BlockNumber do @moduledoc """ Cache for max and min block numbers. """ diff --git a/apps/explorer/lib/explorer/chain/blocks_cache.ex b/apps/explorer/lib/explorer/chain/cache/blocks.ex similarity index 98% rename from apps/explorer/lib/explorer/chain/blocks_cache.ex rename to apps/explorer/lib/explorer/chain/cache/blocks.ex index 778d2bc5d6..76fc2473a6 100644 --- a/apps/explorer/lib/explorer/chain/blocks_cache.ex +++ b/apps/explorer/lib/explorer/chain/cache/blocks.ex @@ -1,4 +1,4 @@ -defmodule Explorer.Chain.BlocksCache do +defmodule Explorer.Chain.Cache.Blocks do @moduledoc """ Caches the last imported blocks """ diff --git a/apps/explorer/lib/explorer/chain/net_version_cache.ex b/apps/explorer/lib/explorer/chain/cache/net_version.ex similarity index 94% rename from apps/explorer/lib/explorer/chain/net_version_cache.ex rename to apps/explorer/lib/explorer/chain/cache/net_version.ex index c3df467e0c..ac33ca8f45 100644 --- a/apps/explorer/lib/explorer/chain/net_version_cache.ex +++ b/apps/explorer/lib/explorer/chain/cache/net_version.ex @@ -1,4 +1,4 @@ -defmodule Explorer.Chain.NetVersionCache do +defmodule Explorer.Chain.Cache.NetVersion do @moduledoc """ Caches chain version. """ diff --git a/apps/explorer/lib/explorer/chain/transaction_count_cache.ex b/apps/explorer/lib/explorer/chain/cache/transaction_count.ex similarity index 98% rename from apps/explorer/lib/explorer/chain/transaction_count_cache.ex rename to apps/explorer/lib/explorer/chain/cache/transaction_count.ex index 95685c0fd4..e1fe2dad82 100644 --- a/apps/explorer/lib/explorer/chain/transaction_count_cache.ex +++ b/apps/explorer/lib/explorer/chain/cache/transaction_count.ex @@ -1,4 +1,4 @@ -defmodule Explorer.Chain.TransactionCountCache do +defmodule Explorer.Chain.Cache.TransactionCount do @moduledoc """ Cache for estimated transaction count. """ diff --git a/apps/explorer/lib/explorer/chain/transactions_cache.ex b/apps/explorer/lib/explorer/chain/cache/transactions.ex similarity index 98% rename from apps/explorer/lib/explorer/chain/transactions_cache.ex rename to apps/explorer/lib/explorer/chain/cache/transactions.ex index 3859561295..54748258cf 100644 --- a/apps/explorer/lib/explorer/chain/transactions_cache.ex +++ b/apps/explorer/lib/explorer/chain/cache/transactions.ex @@ -1,4 +1,4 @@ -defmodule Explorer.Chain.TransactionsCache do +defmodule Explorer.Chain.Cache.Transactions do @moduledoc """ Caches the latest imported transactions """ diff --git a/apps/explorer/lib/explorer/chain/supply/rsk.ex b/apps/explorer/lib/explorer/chain/supply/rsk.ex index bc4171e45f..cdb043418b 100644 --- a/apps/explorer/lib/explorer/chain/supply/rsk.ex +++ b/apps/explorer/lib/explorer/chain/supply/rsk.ex @@ -10,7 +10,8 @@ defmodule Explorer.Chain.Supply.RSK do alias EthereumJSONRPC.FetchedBalances alias Explorer.Chain.Address.CoinBalance - alias Explorer.Chain.{Block, BlockNumberCache, Wei} + alias Explorer.Chain.{Block, Wei} + alias Explorer.Chain.Cache.BlockNumber alias Explorer.Repo @cache_name :rsk_balance @@ -99,7 +100,7 @@ defmodule Explorer.Chain.Supply.RSK do def cache_name, do: @cache_name defp fetch_circulating_value do - max_number = BlockNumberCache.max_number() + max_number = BlockNumber.max_number() params = [ %{block_quantity: integer_to_quantity(max_number), hash_data: "0x0000000000000000000000000000000001000006"} diff --git a/apps/explorer/test/explorer/chain/block_number_cache_test.exs b/apps/explorer/test/explorer/chain/block_number_cache_test.exs deleted file mode 100644 index 7b501a718b..0000000000 --- a/apps/explorer/test/explorer/chain/block_number_cache_test.exs +++ /dev/null @@ -1,59 +0,0 @@ -defmodule Explorer.Chain.BlockNumberCacheTest do - use Explorer.DataCase - - alias Explorer.Chain.BlockNumberCache - - setup do - Application.put_env(:explorer, Explorer.Chain.BlockNumberCache, enabled: true) - - on_exit(fn -> - Application.put_env(:explorer, Explorer.Chain.BlockNumberCache, enabled: false) - end) - end - - describe "max_number/1" do - test "returns max number" do - insert(:block, number: 5) - - BlockNumberCache.setup() - - assert BlockNumberCache.max_number() == 5 - end - end - - describe "min_number/1" do - test "returns max number" do - insert(:block, number: 2) - - BlockNumberCache.setup() - - assert BlockNumberCache.max_number() == 2 - end - end - - describe "update/1" do - test "updates max number" do - insert(:block, number: 2) - - BlockNumberCache.setup() - - assert BlockNumberCache.max_number() == 2 - - assert BlockNumberCache.update(3) - - assert BlockNumberCache.max_number() == 3 - end - - test "updates min number" do - insert(:block, number: 2) - - BlockNumberCache.setup() - - assert BlockNumberCache.min_number() == 2 - - assert BlockNumberCache.update(1) - - assert BlockNumberCache.min_number() == 1 - end - end -end diff --git a/apps/explorer/test/explorer/chain/block_count_cache_test.exs b/apps/explorer/test/explorer/chain/cache/block_count_test.exs similarity index 52% rename from apps/explorer/test/explorer/chain/block_count_cache_test.exs rename to apps/explorer/test/explorer/chain/cache/block_count_test.exs index d1bbd5eb53..646af8de43 100644 --- a/apps/explorer/test/explorer/chain/block_count_cache_test.exs +++ b/apps/explorer/test/explorer/chain/cache/block_count_test.exs @@ -1,55 +1,55 @@ -defmodule Explorer.Chain.BlockCountCacheTest do +defmodule Explorer.Chain.Cache.BlockCountTest do use Explorer.DataCase - alias Explorer.Chain.BlockCountCache + alias Explorer.Chain.Cache.BlockCount test "returns default transaction count" do - BlockCountCache.start_link(name: BlockTestCache) + BlockCount.start_link(name: BlockTestCache) - result = BlockCountCache.count(BlockTestCache) + result = BlockCount.count(BlockTestCache) assert is_nil(result) end test "updates cache if initial value is zero" do - BlockCountCache.start_link(name: BlockTestCache) + BlockCount.start_link(name: BlockTestCache) insert(:block, consensus: true) insert(:block, consensus: true) insert(:block, consensus: false) - _result = BlockCountCache.count(BlockTestCache) + _result = BlockCount.count(BlockTestCache) Process.sleep(1000) - updated_value = BlockCountCache.count(BlockTestCache) + updated_value = BlockCount.count(BlockTestCache) assert updated_value == 2 end test "does not update cache if cache period did not pass" do - BlockCountCache.start_link(name: BlockTestCache) + BlockCount.start_link(name: BlockTestCache) insert(:block, consensus: true) insert(:block, consensus: true) insert(:block, consensus: false) - _result = BlockCountCache.count(BlockTestCache) + _result = BlockCount.count(BlockTestCache) Process.sleep(1000) - updated_value = BlockCountCache.count(BlockTestCache) + updated_value = BlockCount.count(BlockTestCache) assert updated_value == 2 insert(:block, consensus: true) insert(:block, consensus: true) - _updated_value = BlockCountCache.count(BlockTestCache) + _updated_value = BlockCount.count(BlockTestCache) Process.sleep(1000) - updated_value = BlockCountCache.count(BlockTestCache) + updated_value = BlockCount.count(BlockTestCache) assert updated_value == 2 end diff --git a/apps/explorer/test/explorer/chain/cache/block_number_test.exs b/apps/explorer/test/explorer/chain/cache/block_number_test.exs new file mode 100644 index 0000000000..381ded440b --- /dev/null +++ b/apps/explorer/test/explorer/chain/cache/block_number_test.exs @@ -0,0 +1,59 @@ +defmodule Explorer.Chain.Cache.BlockNumberTest do + use Explorer.DataCase + + alias Explorer.Chain.Cache.BlockNumber + + setup do + Application.put_env(:explorer, Explorer.Chain.Cache.BlockNumber, enabled: true) + + on_exit(fn -> + Application.put_env(:explorer, Explorer.Chain.Cache.BlockNumber, enabled: false) + end) + end + + describe "max_number/1" do + test "returns max number" do + insert(:block, number: 5) + + BlockNumber.setup() + + assert BlockNumber.max_number() == 5 + end + end + + describe "min_number/1" do + test "returns max number" do + insert(:block, number: 2) + + BlockNumber.setup() + + assert BlockNumber.max_number() == 2 + end + end + + describe "update/1" do + test "updates max number" do + insert(:block, number: 2) + + BlockNumber.setup() + + assert BlockNumber.max_number() == 2 + + assert BlockNumber.update(3) + + assert BlockNumber.max_number() == 3 + end + + test "updates min number" do + insert(:block, number: 2) + + BlockNumber.setup() + + assert BlockNumber.min_number() == 2 + + assert BlockNumber.update(1) + + assert BlockNumber.min_number() == 1 + end + end +end diff --git a/apps/explorer/test/explorer/chain/blocks_cache_test.exs b/apps/explorer/test/explorer/chain/cache/blocks_test.exs similarity index 65% rename from apps/explorer/test/explorer/chain/blocks_cache_test.exs rename to apps/explorer/test/explorer/chain/cache/blocks_test.exs index 687d2ff30a..52ac4eabb4 100644 --- a/apps/explorer/test/explorer/chain/blocks_cache_test.exs +++ b/apps/explorer/test/explorer/chain/cache/blocks_test.exs @@ -1,7 +1,7 @@ -defmodule Explorer.Chain.BlocksCacheTest do +defmodule Explorer.Chain.Cache.BlocksTest do use Explorer.DataCase - alias Explorer.Chain.BlocksCache + alias Explorer.Chain.Cache.Blocks alias Explorer.Repo setup do @@ -14,9 +14,9 @@ defmodule Explorer.Chain.BlocksCacheTest do test "adds a new value to cache" do block = insert(:block) |> Repo.preload([:transactions, [miner: :names], :rewards]) - BlocksCache.update(block) + Blocks.update(block) - assert BlocksCache.blocks() == [block] + assert Blocks.blocks() == [block] end test "adds a new elements removing the oldest one" do @@ -25,43 +25,43 @@ defmodule Explorer.Chain.BlocksCacheTest do |> Enum.map(fn number -> block = insert(:block, number: number) - BlocksCache.update(block) + Blocks.update(block) block.number end) new_block = insert(:block, number: 70) - BlocksCache.update(new_block) + Blocks.update(new_block) new_blocks = blocks |> List.replace_at(0, new_block.number) |> Enum.sort() |> Enum.reverse() - assert Enum.map(BlocksCache.blocks(), & &1.number) == new_blocks + assert Enum.map(Blocks.blocks(), & &1.number) == new_blocks end test "does not add too old blocks" do block = insert(:block, number: 100_000) |> Repo.preload([:transactions, [miner: :names], :rewards]) old_block = insert(:block, number: 1_000) - BlocksCache.update(block) - BlocksCache.update(old_block) + Blocks.update(block) + Blocks.update(old_block) - assert BlocksCache.blocks() == [block] + assert Blocks.blocks() == [block] end test "adds missing element" do block1 = insert(:block, number: 10) block2 = insert(:block, number: 4) - BlocksCache.update(block1) - BlocksCache.update(block2) + Blocks.update(block1) + Blocks.update(block2) - assert Enum.count(BlocksCache.blocks()) == 2 + assert Enum.count(Blocks.blocks()) == 2 block3 = insert(:block, number: 6) - BlocksCache.update(block3) + Blocks.update(block3) - assert Enum.map(BlocksCache.blocks(), & &1.number) == [10, 6, 4] + assert Enum.map(Blocks.blocks(), & &1.number) == [10, 6, 4] end end @@ -69,16 +69,16 @@ defmodule Explorer.Chain.BlocksCacheTest do test "updates cache" do block = insert(:block) - BlocksCache.update(block) + Blocks.update(block) block1 = insert(:block) |> Repo.preload([:transactions, [miner: :names], :rewards]) block2 = insert(:block) |> Repo.preload([:transactions, [miner: :names], :rewards]) new_blocks = [block1, block2] - BlocksCache.rewrite_cache(new_blocks) + Blocks.rewrite_cache(new_blocks) - assert BlocksCache.blocks() == [block2, block1] + assert Blocks.blocks() == [block2, block1] end end end diff --git a/apps/explorer/test/explorer/chain/cache/transaction_count_test.exs b/apps/explorer/test/explorer/chain/cache/transaction_count_test.exs new file mode 100644 index 0000000000..5020486cb8 --- /dev/null +++ b/apps/explorer/test/explorer/chain/cache/transaction_count_test.exs @@ -0,0 +1,54 @@ +defmodule Explorer.Chain.Cache.TransactionCountTest do + use Explorer.DataCase + + alias Explorer.Chain.Cache.TransactionCount + + test "returns default transaction count" do + TransactionCount.start_link([[], [name: TestCache]]) + + result = TransactionCount.value(TestCache) + + assert is_nil(result) + end + + test "updates cache if initial value is zero" do + TransactionCount.start_link([[], [name: TestCache]]) + + insert(:transaction) + insert(:transaction) + + _result = TransactionCount.value(TestCache) + + Process.sleep(1000) + + updated_value = TransactionCount.value(TestCache) + + assert updated_value == 2 + end + + test "does not update cache if cache period did not pass" do + TransactionCount.start_link([[], [name: TestCache]]) + + insert(:transaction) + insert(:transaction) + + _result = TransactionCount.value(TestCache) + + Process.sleep(1000) + + updated_value = TransactionCount.value(TestCache) + + assert updated_value == 2 + + insert(:transaction) + insert(:transaction) + + _updated_value = TransactionCount.value(TestCache) + + Process.sleep(1000) + + updated_value = TransactionCount.value(TestCache) + + assert updated_value == 2 + end +end diff --git a/apps/explorer/test/explorer/chain/transactions_cache_test.exs b/apps/explorer/test/explorer/chain/cache/transactions_test.exs similarity index 70% rename from apps/explorer/test/explorer/chain/transactions_cache_test.exs rename to apps/explorer/test/explorer/chain/cache/transactions_test.exs index a72055c276..8a768b7dae 100644 --- a/apps/explorer/test/explorer/chain/transactions_cache_test.exs +++ b/apps/explorer/test/explorer/chain/cache/transactions_test.exs @@ -1,7 +1,7 @@ -defmodule Explorer.Chain.TransactionsCacheTest do +defmodule Explorer.Chain.Cache.TransactionsTest do use Explorer.DataCase - alias Explorer.Chain.TransactionsCache + alias Explorer.Chain.Cache.Transactions alias Explorer.Repo @size 51 @@ -10,9 +10,9 @@ defmodule Explorer.Chain.TransactionsCacheTest do test "adds a new value to a new cache with preloads" do transaction = insert(:transaction) |> preload_all() - TransactionsCache.update(transaction) + Transactions.update(transaction) - assert TransactionsCache.take(1) == [transaction] + assert Transactions.take(1) == [transaction] end test "adds several elements, removing the oldest when necessary" do @@ -23,9 +23,9 @@ defmodule Explorer.Chain.TransactionsCacheTest do insert(:transaction) |> with_block(block) end) - TransactionsCache.update(transactions) + Transactions.update(transactions) - assert TransactionsCache.all() == Enum.reverse(preload_all(transactions)) + assert Transactions.all() == Enum.reverse(preload_all(transactions)) more_transactions = (@size + 1)..(@size + 10) @@ -34,14 +34,14 @@ defmodule Explorer.Chain.TransactionsCacheTest do insert(:transaction) |> with_block(block) end) - TransactionsCache.update(more_transactions) + Transactions.update(more_transactions) kept_transactions = Enum.reverse(transactions ++ more_transactions) |> Enum.take(@size) |> preload_all() - assert TransactionsCache.take(@size) == kept_transactions + assert Transactions.take(@size) == kept_transactions end test "does not add a transaction too old when full" do @@ -52,28 +52,28 @@ defmodule Explorer.Chain.TransactionsCacheTest do insert(:transaction) |> with_block(block) end) - TransactionsCache.update(transactions) + Transactions.update(transactions) loaded_transactions = Enum.reverse(preload_all(transactions)) - assert TransactionsCache.all() == loaded_transactions + assert Transactions.all() == loaded_transactions block = insert(:block, number: 1) - insert(:transaction) |> with_block(block) |> TransactionsCache.update() + insert(:transaction) |> with_block(block) |> Transactions.update() - assert TransactionsCache.all() == loaded_transactions + assert Transactions.all() == loaded_transactions end test "adds intermediate transactions" do blocks = 1..10 |> Map.new(fn n -> {n, insert(:block, number: n)} end) - insert(:transaction) |> with_block(blocks[1]) |> TransactionsCache.update() - insert(:transaction) |> with_block(blocks[10]) |> TransactionsCache.update() + insert(:transaction) |> with_block(blocks[1]) |> Transactions.update() + insert(:transaction) |> with_block(blocks[10]) |> Transactions.update() - assert TransactionsCache.size() == 2 + assert Transactions.size() == 2 - insert(:transaction) |> with_block(blocks[5]) |> TransactionsCache.update() + insert(:transaction) |> with_block(blocks[5]) |> Transactions.update() - assert TransactionsCache.size() == 3 + assert Transactions.size() == 3 end end diff --git a/apps/explorer/test/explorer/chain/transaction_count_cache_test.exs b/apps/explorer/test/explorer/chain/transaction_count_cache_test.exs deleted file mode 100644 index a1b0d72485..0000000000 --- a/apps/explorer/test/explorer/chain/transaction_count_cache_test.exs +++ /dev/null @@ -1,54 +0,0 @@ -defmodule Explorer.Chain.TransactionCountCacheTest do - use Explorer.DataCase - - alias Explorer.Chain.TransactionCountCache - - test "returns default transaction count" do - TransactionCountCache.start_link([[], [name: TestCache]]) - - result = TransactionCountCache.value(TestCache) - - assert is_nil(result) - end - - test "updates cache if initial value is zero" do - TransactionCountCache.start_link([[], [name: TestCache]]) - - insert(:transaction) - insert(:transaction) - - _result = TransactionCountCache.value(TestCache) - - Process.sleep(1000) - - updated_value = TransactionCountCache.value(TestCache) - - assert updated_value == 2 - end - - test "does not update cache if cache period did not pass" do - TransactionCountCache.start_link([[], [name: TestCache]]) - - insert(:transaction) - insert(:transaction) - - _result = TransactionCountCache.value(TestCache) - - Process.sleep(1000) - - updated_value = TransactionCountCache.value(TestCache) - - assert updated_value == 2 - - insert(:transaction) - insert(:transaction) - - _updated_value = TransactionCountCache.value(TestCache) - - Process.sleep(1000) - - updated_value = TransactionCountCache.value(TestCache) - - assert updated_value == 2 - end -end diff --git a/apps/explorer/test/explorer/market/market_history_cache_test.exs b/apps/explorer/test/explorer/market/market_history_cache_test.exs index 1421d75214..6dbd15fe7f 100644 --- a/apps/explorer/test/explorer/market/market_history_cache_test.exs +++ b/apps/explorer/test/explorer/market/market_history_cache_test.exs @@ -9,8 +9,8 @@ defmodule Explorer.Market.MarketHistoryCacheTest do Supervisor.restart_child(Explorer.Supervisor, {ConCache, MarketHistoryCache.cache_name()}) on_exit(fn -> - Supervisor.terminate_child(Explorer.Supervisor, {ConCache, Explorer.Chain.BlocksCache.cache_name()}) - Supervisor.restart_child(Explorer.Supervisor, {ConCache, Explorer.Chain.BlocksCache.cache_name()}) + Supervisor.terminate_child(Explorer.Supervisor, {ConCache, Explorer.Chain.Cache.Blocks.cache_name()}) + Supervisor.restart_child(Explorer.Supervisor, {ConCache, Explorer.Chain.Cache.Blocks.cache_name()}) end) :ok diff --git a/apps/explorer/test/explorer/market/market_test.exs b/apps/explorer/test/explorer/market/market_test.exs index 7e399ea4cd..3fd111c0cd 100644 --- a/apps/explorer/test/explorer/market/market_test.exs +++ b/apps/explorer/test/explorer/market/market_test.exs @@ -6,12 +6,12 @@ defmodule Explorer.MarketTest do alias Explorer.Repo setup do - Supervisor.terminate_child(Explorer.Supervisor, {ConCache, Explorer.Chain.BlocksCache.cache_name()}) - Supervisor.restart_child(Explorer.Supervisor, {ConCache, Explorer.Chain.BlocksCache.cache_name()}) + Supervisor.terminate_child(Explorer.Supervisor, {ConCache, Explorer.Chain.Cache.Blocks.cache_name()}) + Supervisor.restart_child(Explorer.Supervisor, {ConCache, Explorer.Chain.Cache.Blocks.cache_name()}) on_exit(fn -> - Supervisor.terminate_child(Explorer.Supervisor, {ConCache, Explorer.Chain.BlocksCache.cache_name()}) - Supervisor.restart_child(Explorer.Supervisor, {ConCache, Explorer.Chain.BlocksCache.cache_name()}) + Supervisor.terminate_child(Explorer.Supervisor, {ConCache, Explorer.Chain.Cache.Blocks.cache_name()}) + Supervisor.restart_child(Explorer.Supervisor, {ConCache, Explorer.Chain.Cache.Blocks.cache_name()}) end) :ok diff --git a/apps/explorer/test/support/data_case.ex b/apps/explorer/test/support/data_case.ex index 2ec7cde365..e159891987 100644 --- a/apps/explorer/test/support/data_case.ex +++ b/apps/explorer/test/support/data_case.ex @@ -39,11 +39,11 @@ defmodule Explorer.DataCase do Ecto.Adapters.SQL.Sandbox.mode(Explorer.Repo, {:shared, self()}) end - Explorer.Chain.BlockNumberCache.setup() - Supervisor.terminate_child(Explorer.Supervisor, {ConCache, Explorer.Chain.BlocksCache.cache_name()}) - Supervisor.restart_child(Explorer.Supervisor, {ConCache, Explorer.Chain.BlocksCache.cache_name()}) - Supervisor.terminate_child(Explorer.Supervisor, {ConCache, Explorer.Chain.TransactionsCache.cache_name()}) - Supervisor.restart_child(Explorer.Supervisor, {ConCache, Explorer.Chain.TransactionsCache.cache_name()}) + Explorer.Chain.Cache.BlockNumber.setup() + Supervisor.terminate_child(Explorer.Supervisor, {ConCache, Explorer.Chain.Cache.Blocks.cache_name()}) + Supervisor.restart_child(Explorer.Supervisor, {ConCache, Explorer.Chain.Cache.Blocks.cache_name()}) + Supervisor.terminate_child(Explorer.Supervisor, {ConCache, Explorer.Chain.Cache.Transactions.cache_name()}) + Supervisor.restart_child(Explorer.Supervisor, {ConCache, Explorer.Chain.Cache.Transactions.cache_name()}) :ok end diff --git a/apps/indexer/lib/indexer/block/fetcher.ex b/apps/indexer/lib/indexer/block/fetcher.ex index b436d61e03..4155538e76 100644 --- a/apps/indexer/lib/indexer/block/fetcher.ex +++ b/apps/indexer/lib/indexer/block/fetcher.ex @@ -11,7 +11,9 @@ defmodule Indexer.Block.Fetcher do alias EthereumJSONRPC.{Blocks, FetchedBeneficiaries} alias Explorer.Chain - alias Explorer.Chain.{Address, Block, BlockNumberCache, BlocksCache, Hash, Import, Transaction, TransactionsCache} + alias Explorer.Chain.{Address, Block, Hash, Import, Transaction} + alias Explorer.Chain.Cache.Blocks, as: BlocksCache + alias Explorer.Chain.Cache.{BlockNumber, Transactions} alias Indexer.Block.Fetcher.Receipts alias Indexer.Fetcher.{ @@ -185,13 +187,13 @@ defmodule Indexer.Block.Fetcher do max_block = Enum.max_by(blocks, fn block -> block.number end) min_block = Enum.min_by(blocks, fn block -> block.number end) - BlockNumberCache.update(max_block.number) - BlockNumberCache.update(min_block.number) + BlockNumber.update(max_block.number) + BlockNumber.update(min_block.number) BlocksCache.update_blocks(blocks) end defp update_transactions_cache(transactions) do - TransactionsCache.update(transactions) + Transactions.update(transactions) end def import( diff --git a/apps/indexer/lib/indexer/fetcher/coin_balance_on_demand.ex b/apps/indexer/lib/indexer/fetcher/coin_balance_on_demand.ex index 75af9c9bfc..4dfed6e73a 100644 --- a/apps/indexer/lib/indexer/fetcher/coin_balance_on_demand.ex +++ b/apps/indexer/lib/indexer/fetcher/coin_balance_on_demand.ex @@ -17,8 +17,9 @@ defmodule Indexer.Fetcher.CoinBalanceOnDemand do alias EthereumJSONRPC.FetchedBalances alias Explorer.{Chain, Repo} - alias Explorer.Chain.{Address, BlockNumberCache} + alias Explorer.Chain.Address alias Explorer.Chain.Address.CoinBalance + alias Explorer.Chain.Cache.BlockNumber alias Explorer.Counters.AverageBlockTime alias Indexer.Fetcher.CoinBalance, as: CoinBalanceFetcher alias Timex.Duration @@ -161,7 +162,7 @@ defmodule Indexer.Fetcher.CoinBalanceOnDemand do end defp latest_block_number do - BlockNumberCache.max_number() + BlockNumber.max_number() end defp stale_balance_window(block_number) do From 575afa806d28ae052fb598ea9d8085266ca5c9e2 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Tue, 9 Jul 2019 14:02:43 +0300 Subject: [PATCH 26/39] fix external libary function --- .../smart_contract/new_smart_contract_form.js | 28 ---------- .../assets/js/pages/verification_form.js | 55 +++++++++++++++++++ 2 files changed, 55 insertions(+), 28 deletions(-) delete mode 100644 apps/block_scout_web/assets/js/lib/smart_contract/new_smart_contract_form.js diff --git a/apps/block_scout_web/assets/js/lib/smart_contract/new_smart_contract_form.js b/apps/block_scout_web/assets/js/lib/smart_contract/new_smart_contract_form.js deleted file mode 100644 index 43419aeb9b..0000000000 --- a/apps/block_scout_web/assets/js/lib/smart_contract/new_smart_contract_form.js +++ /dev/null @@ -1,28 +0,0 @@ -import $ from 'jquery' - -$(function () { - $('.js-btn-add-contract-libraries').on('click', function () { - $('.js-smart-contract-libraries-wrapper').show() - $(this).hide() - }) - - $('.js-smart-contract-form-reset').on('click', function () { - $('.js-contract-library-form-group').removeClass('active') - $('.js-contract-library-form-group').first().addClass('active') - $('.js-smart-contract-libraries-wrapper').hide() - $('.js-btn-add-contract-libraries').show() - $('.js-add-contract-library-wrapper').show() - }) - - $('.js-btn-add-contract-library').on('click', function () { - let nextContractLibrary = $('.js-contract-library-form-group.active').next('.js-contract-library-form-group') - - if (nextContractLibrary) { - nextContractLibrary.addClass('active') - } - - if ($('.js-contract-library-form-group.active').length === $('.js-contract-library-form-group').length) { - $('.js-add-contract-library-wrapper').hide() - } - }) -}) diff --git a/apps/block_scout_web/assets/js/pages/verification_form.js b/apps/block_scout_web/assets/js/pages/verification_form.js index 28a654d999..619a8e1326 100644 --- a/apps/block_scout_web/assets/js/pages/verification_form.js +++ b/apps/block_scout_web/assets/js/pages/verification_form.js @@ -51,6 +51,34 @@ const elements = { $('button[data-button-loading="animation"]').click(event => { $('#loading').removeClass('d-none') }) + + $(function () { + $('.js-btn-add-contract-libraries').on('click', function () { + $('.js-smart-contract-libraries-wrapper').show() + $(this).hide() + }) + + $('.js-smart-contract-form-reset').on('click', function () { + $('.js-contract-library-form-group').removeClass('active') + $('.js-contract-library-form-group').first().addClass('active') + $('.js-smart-contract-libraries-wrapper').hide() + $('.js-btn-add-contract-libraries').show() + $('.js-add-contract-library-wrapper').show() + }) + + $('.js-btn-add-contract-library').on('click', function () { + let nextContractLibrary = $('.js-contract-library-form-group.active').next('.js-contract-library-form-group') + + if (nextContractLibrary) { + nextContractLibrary.addClass('active') + } + + if ($('.js-contract-library-form-group.active').length === $('.js-contract-library-form-group').length) { + $('.js-add-contract-library-wrapper').hide() + } + }) + }) + return $el } return $el @@ -86,4 +114,31 @@ if ($contractVerificationPage.length) { $('button[data-button-loading="animation"]').click(event => { $('#loading').removeClass('d-none') }) + + $(function () { + $('.js-btn-add-contract-libraries').on('click', function () { + $('.js-smart-contract-libraries-wrapper').show() + $(this).hide() + }) + + $('.js-smart-contract-form-reset').on('click', function () { + $('.js-contract-library-form-group').removeClass('active') + $('.js-contract-library-form-group').first().addClass('active') + $('.js-smart-contract-libraries-wrapper').hide() + $('.js-btn-add-contract-libraries').show() + $('.js-add-contract-library-wrapper').show() + }) + + $('.js-btn-add-contract-library').on('click', function () { + let nextContractLibrary = $('.js-contract-library-form-group.active').next('.js-contract-library-form-group') + + if (nextContractLibrary) { + nextContractLibrary.addClass('active') + } + + if ($('.js-contract-library-form-group.active').length === $('.js-contract-library-form-group').length) { + $('.js-add-contract-library-wrapper').hide() + } + }) + }) } From f89bb918f412aedb3d5b54c1183b1b37bb5da759 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Tue, 9 Jul 2019 14:03:46 +0300 Subject: [PATCH 27/39] add external libaries embeds --- apps/explorer/lib/explorer/chain/smart_contract.ex | 6 +++--- .../chain/smart_contract/external_library.ex | 8 ++++++++ .../lib/explorer/smart_contract/publisher.ex | 4 ++-- ...04_add_external_libraries_to_smart_contracts.exs | 13 +++++++++++++ 4 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 apps/explorer/lib/explorer/chain/smart_contract/external_library.ex create mode 100644 apps/explorer/priv/repo/migrations/20190709103104_add_external_libraries_to_smart_contracts.exs diff --git a/apps/explorer/lib/explorer/chain/smart_contract.ex b/apps/explorer/lib/explorer/chain/smart_contract.ex index 9dee6b147e..9911dc1143 100644 --- a/apps/explorer/lib/explorer/chain/smart_contract.ex +++ b/apps/explorer/lib/explorer/chain/smart_contract.ex @@ -13,6 +13,7 @@ defmodule Explorer.Chain.SmartContract do use Explorer.Schema alias Explorer.Chain.{Address, ContractMethod, DecompiledSmartContract, Hash} + alias Explorer.Chain.SmartContract.ExternalLibrary alias Explorer.Repo @typedoc """ @@ -212,7 +213,7 @@ defmodule Explorer.Chain.SmartContract do field(:constructor_arguments, :string) field(:evm_version, :string) field(:optimization_runs, :integer) - field(:external_libraries, :map) + embeds_many :external_libraries, ExternalLibrary field(:abi, {:array, :map}) has_many( @@ -247,8 +248,7 @@ defmodule Explorer.Chain.SmartContract do :abi, :constructor_arguments, :evm_version, - :optimization_runs, - :external_libraries + :optimization_runs ]) |> validate_required([:name, :compiler_version, :optimization, :contract_source_code, :abi, :address_hash]) |> unique_constraint(:address_hash) diff --git a/apps/explorer/lib/explorer/chain/smart_contract/external_library.ex b/apps/explorer/lib/explorer/chain/smart_contract/external_library.ex new file mode 100644 index 0000000000..807df7bd94 --- /dev/null +++ b/apps/explorer/lib/explorer/chain/smart_contract/external_library.ex @@ -0,0 +1,8 @@ +defmodule Explorer.Chain.SmartContract.ExternalLibrary do + use Ecto.Schema + + embedded_schema do + field :name + field :address_hash + end +end diff --git a/apps/explorer/lib/explorer/smart_contract/publisher.ex b/apps/explorer/lib/explorer/smart_contract/publisher.ex index 702b45976d..42ce646fb1 100644 --- a/apps/explorer/lib/explorer/smart_contract/publisher.ex +++ b/apps/explorer/lib/explorer/smart_contract/publisher.ex @@ -28,10 +28,10 @@ defmodule Explorer.SmartContract.Publisher do case Verifier.evaluate_authenticity(address_hash, params_with_external_libaries) do {:ok, %{abi: abi}} -> - publish_smart_contract(address_hash, params, abi) + publish_smart_contract(address_hash, params_with_external_libaries, abi) {:error, error} -> - {:error, unverified_smart_contract(address_hash, params, error)} + {:error, unverified_smart_contract(address_hash, params_with_external_libaries, error)} end end diff --git a/apps/explorer/priv/repo/migrations/20190709103104_add_external_libraries_to_smart_contracts.exs b/apps/explorer/priv/repo/migrations/20190709103104_add_external_libraries_to_smart_contracts.exs new file mode 100644 index 0000000000..b122dfdd54 --- /dev/null +++ b/apps/explorer/priv/repo/migrations/20190709103104_add_external_libraries_to_smart_contracts.exs @@ -0,0 +1,13 @@ +defmodule Explorer.Repo.Migrations.AddExternalLibrariesToSmartContracts do + use Ecto.Migration + + def change do + alter table(:smart_contracts) do + remove :external_libraries + end + + alter table(:smart_contracts) do + add :external_libraries, {:array, :map}, default: [] + end + end +end From 1af13f88f32e4410802516c588da6e1e7e49b4e1 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Tue, 9 Jul 2019 14:10:41 +0300 Subject: [PATCH 28/39] fix build --- apps/block_scout_web/assets/js/app.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/block_scout_web/assets/js/app.js b/apps/block_scout_web/assets/js/app.js index ea3e2b1afd..25de7b2688 100644 --- a/apps/block_scout_web/assets/js/app.js +++ b/apps/block_scout_web/assets/js/app.js @@ -47,7 +47,6 @@ import './lib/market_history_chart' import './lib/pending_transactions_toggle' import './lib/pretty_json' import './lib/reload_button' -import './lib/smart_contract/new_smart_contract_form' import './lib/smart_contract/read_only_functions' import './lib/smart_contract/wei_ether_converter' import './lib/stop_propagation' From ea1f7f7c3de6854dd855f3da3e430f8699d4dcfd Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Tue, 9 Jul 2019 14:21:05 +0300 Subject: [PATCH 29/39] fix style issues --- apps/explorer/lib/explorer/chain/smart_contract.ex | 2 +- .../lib/explorer/chain/smart_contract/external_library.ex | 8 ++++++-- ...09103104_add_external_libraries_to_smart_contracts.exs | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/explorer/lib/explorer/chain/smart_contract.ex b/apps/explorer/lib/explorer/chain/smart_contract.ex index 9911dc1143..ed579e8e00 100644 --- a/apps/explorer/lib/explorer/chain/smart_contract.ex +++ b/apps/explorer/lib/explorer/chain/smart_contract.ex @@ -213,7 +213,7 @@ defmodule Explorer.Chain.SmartContract do field(:constructor_arguments, :string) field(:evm_version, :string) field(:optimization_runs, :integer) - embeds_many :external_libraries, ExternalLibrary + embeds_many(:external_libraries, ExternalLibrary) field(:abi, {:array, :map}) has_many( diff --git a/apps/explorer/lib/explorer/chain/smart_contract/external_library.ex b/apps/explorer/lib/explorer/chain/smart_contract/external_library.ex index 807df7bd94..ac52388de5 100644 --- a/apps/explorer/lib/explorer/chain/smart_contract/external_library.ex +++ b/apps/explorer/lib/explorer/chain/smart_contract/external_library.ex @@ -1,8 +1,12 @@ defmodule Explorer.Chain.SmartContract.ExternalLibrary do + @moduledoc """ + The representation of an external library that was used for a smart contract. + """ + use Ecto.Schema embedded_schema do - field :name - field :address_hash + field(:name) + field(:address_hash) end end diff --git a/apps/explorer/priv/repo/migrations/20190709103104_add_external_libraries_to_smart_contracts.exs b/apps/explorer/priv/repo/migrations/20190709103104_add_external_libraries_to_smart_contracts.exs index b122dfdd54..5200253f84 100644 --- a/apps/explorer/priv/repo/migrations/20190709103104_add_external_libraries_to_smart_contracts.exs +++ b/apps/explorer/priv/repo/migrations/20190709103104_add_external_libraries_to_smart_contracts.exs @@ -3,11 +3,11 @@ defmodule Explorer.Repo.Migrations.AddExternalLibrariesToSmartContracts do def change do alter table(:smart_contracts) do - remove :external_libraries + remove(:external_libraries) end alter table(:smart_contracts) do - add :external_libraries, {:array, :map}, default: [] + add(:external_libraries, {:array, :map}, default: []) end end end From c1b1f69be4e83f825a55b15c21e43968a3dd80d9 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Tue, 9 Jul 2019 14:57:33 +0300 Subject: [PATCH 30/39] show external libraries in UI --- .../templates/address_contract/index.html.eex | 4 ++-- .../views/address_contract_view.ex | 6 ++++++ apps/explorer/lib/explorer/chain.ex | 9 +++++++-- .../lib/explorer/smart_contract/publisher.ex | 19 +++++++++++++++---- 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex index 505413aa96..9d229916b4 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex @@ -52,13 +52,13 @@
<%= @address.smart_contract.constructor_arguments %>
<% end %> - <%= if @address.smart_contract.external_libraries do %> + <%= if @address.smart_contract.external_libraries && @address.smart_contract.external_libraries != [] do %>

<%= gettext "External libraries" %>

-
<%= format_smart_contract_abi(@address.smart_contract.abi) %>
+                
<%= format_external_libraries(@address.smart_contract.external_libraries) %>
                 
diff --git a/apps/block_scout_web/lib/block_scout_web/views/address_contract_view.ex b/apps/block_scout_web/lib/block_scout_web/views/address_contract_view.ex index 4dc99a2a68..5de263f820 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/address_contract_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/address_contract_view.ex @@ -21,6 +21,12 @@ defmodule BlockScoutWeb.AddressContractView do def format_optimization_text(true), do: gettext("true") def format_optimization_text(false), do: gettext("false") + def format_external_libraries(libraries) do + Enum.reduce(libraries, "", fn %{name: name, address_hash: address_hash}, acc -> + acc <> name <> " : " <> address_hash <> "\n" + end) + end + def contract_lines_with_index(contract_source_code) do contract_lines = String.split(contract_source_code, "\n") diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index fcad694a58..93dca921b9 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -2394,8 +2394,13 @@ defmodule Explorer.Chain do naming the address for reference. """ @spec create_smart_contract(map()) :: {:ok, SmartContract.t()} | {:error, Ecto.Changeset.t()} - def create_smart_contract(attrs \\ %{}) do - smart_contract_changeset = SmartContract.changeset(%SmartContract{}, attrs) + def create_smart_contract(attrs \\ %{}, external_libraries \\ []) do + new_contract = %SmartContract{} + + smart_contract_changeset = + new_contract + |> SmartContract.changeset(attrs) + |> Changeset.put_change(:external_libraries, external_libraries) insert_result = Multi.new() diff --git a/apps/explorer/lib/explorer/smart_contract/publisher.ex b/apps/explorer/lib/explorer/smart_contract/publisher.ex index 42ce646fb1..ae5a24c088 100644 --- a/apps/explorer/lib/explorer/smart_contract/publisher.ex +++ b/apps/explorer/lib/explorer/smart_contract/publisher.ex @@ -36,9 +36,9 @@ defmodule Explorer.SmartContract.Publisher do end defp publish_smart_contract(address_hash, params, abi) do - address_hash - |> attributes(params, abi) - |> Chain.create_smart_contract() + attrs = address_hash |> attributes(params, abi) + + Chain.create_smart_contract(attrs, attrs.external_libraries) end defp unverified_smart_contract(address_hash, params, error) do @@ -64,6 +64,8 @@ defmodule Explorer.SmartContract.Publisher do nil end + prepared_external_libraries = prepare_external_libraies(params["external_libraries"]) + %{ address_hash: address_hash, name: params["name"], @@ -73,11 +75,20 @@ defmodule Explorer.SmartContract.Publisher do optimization: params["optimization"], contract_source_code: params["contract_source_code"], constructor_arguments: clean_constructor_arguments, - external_libaries: params["external_libraries"], + external_libraries: prepared_external_libraries, abi: abi } end + defp prepare_external_libraies(nil), do: [] + + defp prepare_external_libraies(map) do + map + |> Enum.map(fn {key, value} -> + %{name: key, address_hash: value} + end) + end + defp add_external_libraries(params, external_libraries) do clean_external_libraries = Enum.reduce(1..5, %{}, fn number, acc -> From 908402151a6af765a72b59a53ee35e3e81d3ff0f Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Tue, 9 Jul 2019 16:03:33 +0300 Subject: [PATCH 31/39] Fix Contract byte code header style, external libraries to the bottom of the verified contract view --- .../templates/address_contract/index.html.eex | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex index 9d229916b4..8394e69f08 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex @@ -52,17 +52,6 @@
<%= @address.smart_contract.constructor_arguments %>
<% end %> - <%= if @address.smart_contract.external_libraries && @address.smart_contract.external_libraries != [] do %> -
-
-

<%= gettext "External libraries" %>

-
-
-
<%= format_external_libraries(@address.smart_contract.external_libraries) %>
-                
-
-
- <% end %>

@@ -109,7 +98,7 @@
<% {:ok, contract_code} -> %>
-

<%= gettext "Contract Byte Code" %>

+

<%= gettext "Contract Byte Code" %>

@@ -120,6 +109,18 @@ <% end %>
+ <%= if @address.smart_contract.external_libraries && @address.smart_contract.external_libraries != [] do %> +
+
+

<%= gettext "External libraries" %>

+
+
+
<%= format_external_libraries(@address.smart_contract.external_libraries) %>
+            
+
+
+ <% end %> +
From 85b76342a4bd3b3db4537a005e622cbbed74a1ff Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Tue, 9 Jul 2019 16:10:37 +0300 Subject: [PATCH 32/39] fix: external library is only for verified contract --- .../templates/address_contract/index.html.eex | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex index 8394e69f08..f6ada86532 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex @@ -109,18 +109,19 @@ <% end %>
- <%= if @address.smart_contract.external_libraries && @address.smart_contract.external_libraries != [] do %> -
-
-

<%= gettext "External libraries" %>

-
-
-
<%= format_external_libraries(@address.smart_contract.external_libraries) %>
-            
-
-
+ <%= if BlockScoutWeb.AddressView.smart_contract_verified?(@address) do %> + <%= if @address.smart_contract.external_libraries && @address.smart_contract.external_libraries != [] do %> +
+
+

<%= gettext "External libraries" %>

+
+
+
<%= format_external_libraries(@address.smart_contract.external_libraries) %>
+              
+
+
+ <% end %> <% end %> - From 0dc5cfa4fd225cc8f0f89651b73eb17688ba3c8e Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Tue, 9 Jul 2019 16:18:08 +0300 Subject: [PATCH 33/39] Fix gettext test --- apps/block_scout_web/priv/gettext/default.pot | 22 ++++++++-------- .../priv/gettext/en/LC_MESSAGES/default.po | 26 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/apps/block_scout_web/priv/gettext/default.pot b/apps/block_scout_web/priv/gettext/default.pot index ed6f3c655f..8217a39d9c 100644 --- a/apps/block_scout_web/priv/gettext/default.pot +++ b/apps/block_scout_web/priv/gettext/default.pot @@ -258,7 +258,7 @@ msgid "Connection Lost, click to load newer validations" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:82 +#: lib/block_scout_web/templates/address_contract/index.html.eex:71 msgid "Contract ABI" msgstr "" @@ -296,7 +296,7 @@ msgid "Contract name:" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:70 +#: lib/block_scout_web/templates/address_contract/index.html.eex:59 msgid "Contract source code" msgstr "" @@ -1405,17 +1405,17 @@ msgid "Support" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:84 +#: lib/block_scout_web/templates/address_contract/index.html.eex:73 msgid "Copy ABI" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:100 +#: lib/block_scout_web/templates/address_contract/index.html.eex:89 msgid "Copy Contract Creation Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:72 +#: lib/block_scout_web/templates/address_contract/index.html.eex:61 msgid "Copy Source Code" msgstr "" @@ -1585,27 +1585,27 @@ msgid "Block Details" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:112 +#: lib/block_scout_web/templates/address_contract/index.html.eex:101 msgid "Contract Byte Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:98 +#: lib/block_scout_web/templates/address_contract/index.html.eex:87 msgid "Contract Creation Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:104 +#: lib/block_scout_web/templates/address_contract/index.html.eex:93 msgid "Contracts that self destruct in their constructors have no contract code published and cannot be verified." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:114 +#: lib/block_scout_web/templates/address_contract/index.html.eex:103 msgid "Copy Contract Byte Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:105 +#: lib/block_scout_web/templates/address_contract/index.html.eex:94 msgid "Displaying the init data provided of the creating transaction." msgstr "" @@ -1769,7 +1769,7 @@ msgid "ERC-721 " msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:58 +#: lib/block_scout_web/templates/address_contract/index.html.eex:116 msgid "External libraries" 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 efe9a56ff0..b58c06af59 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 @@ -258,7 +258,7 @@ msgid "Connection Lost, click to load newer validations" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:82 +#: lib/block_scout_web/templates/address_contract/index.html.eex:71 msgid "Contract ABI" msgstr "" @@ -296,7 +296,7 @@ msgid "Contract name:" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:70 +#: lib/block_scout_web/templates/address_contract/index.html.eex:59 msgid "Contract source code" msgstr "" @@ -877,7 +877,7 @@ msgid "Transactions" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_tile.html.eex:19 +#: lib/block_scout_web/templates/address/_tile.html.eex:31 msgid "Transactions sent" msgstr "" @@ -923,7 +923,7 @@ msgid "Validated Transactions" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_tile.html.eex:23 +#: lib/block_scout_web/templates/address/_tile.html.eex:35 msgid "Validations" msgstr "" @@ -1405,17 +1405,17 @@ msgid "Support" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:84 +#: lib/block_scout_web/templates/address_contract/index.html.eex:73 msgid "Copy ABI" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:100 +#: lib/block_scout_web/templates/address_contract/index.html.eex:89 msgid "Copy Contract Creation Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:72 +#: lib/block_scout_web/templates/address_contract/index.html.eex:61 msgid "Copy Source Code" msgstr "" @@ -1585,27 +1585,27 @@ msgid "Block Details" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:112 +#: lib/block_scout_web/templates/address_contract/index.html.eex:101 msgid "Contract Byte Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:98 +#: lib/block_scout_web/templates/address_contract/index.html.eex:87 msgid "Contract Creation Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:104 +#: lib/block_scout_web/templates/address_contract/index.html.eex:93 msgid "Contracts that self destruct in their constructors have no contract code published and cannot be verified." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:114 +#: lib/block_scout_web/templates/address_contract/index.html.eex:103 msgid "Copy Contract Byte Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:105 +#: lib/block_scout_web/templates/address_contract/index.html.eex:94 msgid "Displaying the init data provided of the creating transaction." msgstr "" @@ -1769,7 +1769,7 @@ msgid "ERC-721 " msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:58 +#: lib/block_scout_web/templates/address_contract/index.html.eex:116 msgid "External libraries" msgstr "" From 33ede5f8f24d69d91df6de5588d21db6162fbf8b Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Tue, 9 Jul 2019 16:29:16 +0300 Subject: [PATCH 34/39] Remove card-title class from "Contract Byte Code" --- .../block_scout_web/templates/address_contract/index.html.eex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex index f6ada86532..32f77425ca 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex @@ -98,7 +98,7 @@ <% {:ok, contract_code} -> %>
-

<%= gettext "Contract Byte Code" %>

+

<%= gettext "Contract Byte Code" %>

From 4e2ba9ae0c4ffa209ccb02f22a7ef07397553f3d Mon Sep 17 00:00:00 2001 From: pasqu4le Date: Tue, 9 Jul 2019 16:27:28 +0200 Subject: [PATCH 35/39] Reduce function input to address' hash only where possible Problem: a lot of function take an Explorer.Chain.Address as an parameter, but only use its hash. This makes tracing the necessary scope of functions harder and is one of the cause for unnecessary queries/code execution. Solution: refactor this functions to take only an address' hash. --- CHANGELOG.md | 1 + .../address_coin_balance_controller.ex | 4 +- .../address_contract_controller.ex | 4 +- .../controllers/address_controller.ex | 12 +- .../address_decompiled_contract_controller.ex | 4 +- ...address_internal_transaction_controller.ex | 6 +- .../controllers/address_logs_controller.ex | 8 +- .../address_read_contract_controller.ex | 4 +- .../controllers/address_token_controller.ex | 4 +- .../address_token_transfer_controller.ex | 4 +- .../address_transaction_controller.ex | 6 +- .../address_validation_controller.ex | 11 +- .../block_scout_web/resolvers/transaction.ex | 4 +- .../templates/address/overview.html.eex | 4 +- .../tokens/overview/_details.html.eex | 2 +- .../lib/block_scout_web/views/address_view.ex | 12 +- .../views/address_view_test.exs | 2 +- apps/explorer/lib/explorer/chain.ex | 54 +++----- .../address_token_transfer_csv_exporter.ex | 16 +-- .../chain/address_transaction_csv_exporter.ex | 14 +- apps/explorer/lib/explorer/graphql.ex | 7 +- apps/explorer/test/explorer/chain_test.exs | 125 +++++++++--------- apps/explorer/test/explorer/graphql_test.exs | 18 +-- 23 files changed, 158 insertions(+), 168 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c18c34df3..9f08609d12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - [#2291](https://github.com/poanetwork/blockscout/pull/2291) - dashboard fix for md resolution, transactions load fix, block info row fix, addresses page issue, check mark issue ### Chore +- [#2325](https://github.com/poanetwork/blockscout/pull/2325) - Reduce function input to address' hash only where possible - [#2305](https://github.com/poanetwork/blockscout/pull/2305) - Improve Address controllers - [#2302](https://github.com/poanetwork/blockscout/pull/2302) - fix names for xDai source - [#2289](https://github.com/poanetwork/blockscout/pull/2289) - Optional websockets for dev environment diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_coin_balance_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_coin_balance_controller.ex index d43f99a382..33a01959c9 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_coin_balance_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_coin_balance_controller.ex @@ -64,8 +64,8 @@ defmodule BlockScoutWeb.AddressCoinBalanceController do address: address, coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address), exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), - transaction_count: transaction_count(address), - validation_count: validation_count(address), + transaction_count: transaction_count(address_hash), + validation_count: validation_count(address_hash), current_path: current_path(conn) ) end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_controller.ex index 34238a018d..bc4df8c4be 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_controller.ex @@ -16,8 +16,8 @@ defmodule BlockScoutWeb.AddressContractController do address: address, coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address), exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), - transaction_count: transaction_count(address), - validation_count: validation_count(address) + transaction_count: transaction_count(address_hash), + validation_count: validation_count(address_hash) ) else :error -> diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex index 6ce33a2773..9f955fa672 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex @@ -5,7 +5,7 @@ defmodule BlockScoutWeb.AddressController do alias BlockScoutWeb.AddressView alias Explorer.{Chain, Market} - alias Explorer.Chain.Address + alias Explorer.Chain.Hash alias Explorer.ExchangeRates.Token alias Phoenix.View @@ -45,7 +45,7 @@ defmodule BlockScoutWeb.AddressController do exchange_rate: exchange_rate, total_supply: total_supply, tx_count: tx_count, - validation_count: validation_count(address) + validation_count: validation_count(address.hash) ) end) @@ -69,11 +69,11 @@ defmodule BlockScoutWeb.AddressController do redirect(conn, to: address_transaction_path(conn, :index, id)) end - def transaction_count(%Address{} = address) do - Chain.total_transactions_sent_by_address(address) + def transaction_count(%Hash{byte_count: unquote(Hash.Address.byte_count())} = address_hash) do + Chain.total_transactions_sent_by_address(address_hash) end - def validation_count(%Address{} = address) do - Chain.address_to_validation_count(address) + def validation_count(%Hash{byte_count: unquote(Hash.Address.byte_count())} = address_hash) do + Chain.address_to_validation_count(address_hash) end end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_decompiled_contract_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_decompiled_contract_controller.ex index ddee462ba2..be591ce384 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_decompiled_contract_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_decompiled_contract_controller.ex @@ -16,8 +16,8 @@ defmodule BlockScoutWeb.AddressDecompiledContractController do address: address, coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address), exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), - transaction_count: transaction_count(address), - validation_count: validation_count(address) + transaction_count: transaction_count(address_hash), + validation_count: validation_count(address_hash) ) else :error -> diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex index fd5813a1d4..15aa87e69a 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex @@ -28,7 +28,7 @@ defmodule BlockScoutWeb.AddressInternalTransactionController do |> Keyword.merge(paging_options(params)) |> Keyword.merge(current_filter(params)) - internal_transactions_plus_one = Chain.address_to_internal_transactions(address, full_options) + internal_transactions_plus_one = Chain.address_to_internal_transactions(address_hash, full_options) {internal_transactions, next_page} = split_list_by_page(internal_transactions_plus_one) next_page_path = @@ -71,8 +71,8 @@ defmodule BlockScoutWeb.AddressInternalTransactionController do current_path: current_path(conn), exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), filter: params["filter"], - transaction_count: transaction_count(address), - validation_count: validation_count(address) + transaction_count: transaction_count(address_hash), + validation_count: validation_count(address_hash) ) else :error -> diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_logs_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_logs_controller.ex index 55070b4cd8..e349ecd9ef 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_logs_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_logs_controller.ex @@ -17,7 +17,7 @@ defmodule BlockScoutWeb.AddressLogsController do def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), {:ok, address} <- Chain.hash_to_address(address_hash, [], false) do - logs_plus_one = Chain.address_to_logs(address, paging_options(params)) + logs_plus_one = Chain.address_to_logs(address_hash, paging_options(params)) {results, next_page} = split_list_by_page(logs_plus_one) next_page_url = @@ -63,8 +63,8 @@ defmodule BlockScoutWeb.AddressLogsController do current_path: current_path(conn), coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address), exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), - transaction_count: transaction_count(address), - validation_count: validation_count(address) + transaction_count: transaction_count(address_hash), + validation_count: validation_count(address_hash) ) else _ -> @@ -79,7 +79,7 @@ defmodule BlockScoutWeb.AddressLogsController do formatted_topic = if String.starts_with?(topic, "0x"), do: topic, else: "0x" <> topic - logs_plus_one = Chain.address_to_logs(address, topic: formatted_topic) + logs_plus_one = Chain.address_to_logs(address_hash, topic: formatted_topic) {results, next_page} = split_list_by_page(logs_plus_one) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_read_contract_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_read_contract_controller.ex index a9a30cc0d0..d57aa30807 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_read_contract_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_read_contract_controller.ex @@ -23,8 +23,8 @@ defmodule BlockScoutWeb.AddressReadContractController do address: address, coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address), exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), - transaction_count: transaction_count(address), - validation_count: validation_count(address) + transaction_count: transaction_count(address_hash), + validation_count: validation_count(address_hash) ) else :error -> diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_controller.ex index 8d5a60a1ac..d77baa605a 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_controller.ex @@ -64,8 +64,8 @@ defmodule BlockScoutWeb.AddressTokenController do current_path: current_path(conn), coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address), exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), - transaction_count: transaction_count(address), - validation_count: validation_count(address) + transaction_count: transaction_count(address_hash), + validation_count: validation_count(address_hash) ) else :error -> diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex index 2a1e47b295..4e0023b067 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex @@ -85,8 +85,8 @@ defmodule BlockScoutWeb.AddressTokenTransferController do exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), current_path: current_path(conn), token: token, - transaction_count: transaction_count(address), - validation_count: validation_count(address) + transaction_count: transaction_count(address_hash), + validation_count: validation_count(address_hash) ) else :error -> diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex index f0ff5f3f12..dc71bed50b 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex @@ -38,7 +38,7 @@ defmodule BlockScoutWeb.AddressTransactionController do |> Keyword.merge(paging_options(params)) |> Keyword.merge(current_filter(params)) - results_plus_one = Chain.address_to_transactions_with_rewards(address, options) + results_plus_one = Chain.address_to_transactions_with_rewards(address_hash, options) {results, next_page} = split_list_by_page(results_plus_one) next_page_url = @@ -97,8 +97,8 @@ defmodule BlockScoutWeb.AddressTransactionController do coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address), exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), filter: params["filter"], - transaction_count: transaction_count(address), - validation_count: validation_count(address), + transaction_count: transaction_count(address_hash), + validation_count: validation_count(address_hash), current_path: current_path(conn) ) else diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex index 84036923de..7226dffcf8 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex @@ -17,7 +17,7 @@ defmodule BlockScoutWeb.AddressValidationController do def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), - {:ok, address} <- Chain.find_or_insert_address_from_hash(address_hash, [], false) do + {:ok, _} <- Chain.find_or_insert_address_from_hash(address_hash, [], false) do full_options = Keyword.merge( [ @@ -31,7 +31,7 @@ defmodule BlockScoutWeb.AddressValidationController do paging_options(params) ) - blocks_plus_one = Chain.get_blocks_validated_by_address(full_options, address) + blocks_plus_one = Chain.get_blocks_validated_by_address(full_options, address_hash) {blocks, next_page} = split_list_by_page(blocks_plus_one) next_page_path = @@ -63,9 +63,6 @@ defmodule BlockScoutWeb.AddressValidationController do else :error -> unprocessable_entity(conn) - - {:error, :not_found} -> - not_found(conn) end end @@ -78,8 +75,8 @@ defmodule BlockScoutWeb.AddressValidationController do address: address, coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address), current_path: current_path(conn), - transaction_count: transaction_count(address), - validation_count: validation_count(address), + transaction_count: transaction_count(address.hash), + validation_count: validation_count(address.hash), exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null() ) else diff --git a/apps/block_scout_web/lib/block_scout_web/resolvers/transaction.ex b/apps/block_scout_web/lib/block_scout_web/resolvers/transaction.ex index aa54a8e6da..fe96463794 100644 --- a/apps/block_scout_web/lib/block_scout_web/resolvers/transaction.ex +++ b/apps/block_scout_web/lib/block_scout_web/resolvers/transaction.ex @@ -12,8 +12,8 @@ defmodule BlockScoutWeb.Resolvers.Transaction do end end - def get_by(%Address{} = address, args, _) do - address + def get_by(%Address{hash: address_hash}, args, _) do + address_hash |> GraphQL.address_to_transactions_query() |> Connection.from_query(&Repo.all/1, args, options(args)) end diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex index e6178a4e72..3cb95a5331 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex @@ -74,7 +74,7 @@ <%= if contract?(@address) do %> <%= gettext(">=") %> - <%= incoming_transaction_count(@address) %> + <%= incoming_transaction_count(@address.hash) %> <%= gettext("Incoming Transactions") %> <% else %> @@ -146,7 +146,7 @@
diff --git a/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex b/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex index b507b9f158..f0c248c8fb 100644 --- a/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex +++ b/apps/explorer/lib/explorer/smart_contract/publisher_worker.ex @@ -8,7 +8,7 @@ defmodule Explorer.SmartContract.PublisherWorker do alias Explorer.Chain.Events.Publisher, as: EventsPublisher alias Explorer.SmartContract.Publisher - def perform({address_hash, params, external_libraries}) do + def perform({address_hash, params, external_libraries, conn}) do result = case Publisher.publish(address_hash, params, external_libraries) do {:ok, _contract} = result -> @@ -18,6 +18,6 @@ defmodule Explorer.SmartContract.PublisherWorker do {:error, changeset} end - EventsPublisher.broadcast([{:contract_verification_result, {address_hash, result}}], :on_demand) + EventsPublisher.broadcast([{:contract_verification_result, {address_hash, result, conn}}], :on_demand) end end From 92f0447c2db559f90df34c17273c9c5e7e297de0 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Wed, 10 Jul 2019 14:04:59 +0300 Subject: [PATCH 37/39] move rejection logic to private function --- .../market/history/source/crypto_compare.ex | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/apps/explorer/lib/explorer/market/history/source/crypto_compare.ex b/apps/explorer/lib/explorer/market/history/source/crypto_compare.ex index 09959f6cca..6888d83b2b 100644 --- a/apps/explorer/lib/explorer/market/history/source/crypto_compare.ex +++ b/apps/explorer/lib/explorer/market/history/source/crypto_compare.ex @@ -24,7 +24,12 @@ defmodule Explorer.Market.History.Source.CryptoCompare do case HTTPoison.get(url, headers) do {:ok, %Response{body: body, status_code: 200}} -> - {:ok, format_data(body)} + result = + body + |> format_data() + |> reject_zeros() + + {:ok, result} _ -> :error @@ -48,18 +53,13 @@ defmodule Explorer.Market.History.Source.CryptoCompare do defp format_data(data) do json = Jason.decode!(data) - items = - for item <- json["Data"] do - %{ - closing_price: Decimal.new(to_string(item["close"])), - date: date(item["time"]), - opening_price: Decimal.new(to_string(item["open"])) - } - end - - Enum.reject(items, fn item -> - Decimal.equal?(item.closing_price, 0) && Decimal.equal?(item.opening_price, 0) - end) + for item <- json["Data"] do + %{ + closing_price: Decimal.new(to_string(item["close"])), + date: date(item["time"]), + opening_price: Decimal.new(to_string(item["open"])) + } + end end @spec history_url(non_neg_integer()) :: String.t() @@ -72,4 +72,10 @@ defmodule Explorer.Market.History.Source.CryptoCompare do "#{base_url()}/data/histoday?#{URI.encode_query(query_params)}" end + + defp reject_zeros(items) do + Enum.reject(items, fn item -> + Decimal.equal?(item.closing_price, 0) && Decimal.equal?(item.opening_price, 0) + end) + end end From 10d5b69d8e632a62c0b8318d75c296cc1dd8b959 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Wed, 10 Jul 2019 17:07:33 +0300 Subject: [PATCH 38/39] fix transaction input --- apps/explorer/lib/explorer/chain/data.ex | 19 +++++++++++++++++++ .../test/explorer/chain/transaction_test.exs | 14 ++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/apps/explorer/lib/explorer/chain/data.ex b/apps/explorer/lib/explorer/chain/data.ex index ee03bdeb24..a3bec019af 100644 --- a/apps/explorer/lib/explorer/chain/data.ex +++ b/apps/explorer/lib/explorer/chain/data.ex @@ -7,6 +7,7 @@ defmodule Explorer.Chain.Data do """ alias Explorer.Chain.Data + alias Poison.Encoder.BitString @behaviour Ecto.Type @@ -380,4 +381,22 @@ defmodule Explorer.Chain.Data do @for.to_string(data) end end + + defimpl Poison.Encoder do + def encode(data, options) do + data + |> to_string() + |> BitString.encode(options) + end + end + + defimpl Jason.Encoder do + alias Jason.Encode + + def encode(data, opts) do + data + |> to_string() + |> Encode.string(opts) + end + end end diff --git a/apps/explorer/test/explorer/chain/transaction_test.exs b/apps/explorer/test/explorer/chain/transaction_test.exs index 08f30a0bfa..5fe6b9958c 100644 --- a/apps/explorer/test/explorer/chain/transaction_test.exs +++ b/apps/explorer/test/explorer/chain/transaction_test.exs @@ -286,4 +286,18 @@ defmodule Explorer.Chain.TransactionTest do assert Transaction.decoded_input_data(transaction) == {:ok, "60fe47b1", "set(uint256 x)", [{"x", "uint256", 10}]} end end + + describe "Poison.encode!/1" do + test "encodes transaction input" do + assert %{ + insert(:transaction) + | input: %Explorer.Chain.Data{ + bytes: + <<169, 5, 156, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 193, 108, 45, 196, 42, 228, 149, 239, 119, + 191, 128, 248>> + } + } + |> Poison.encode!() + end + end end From fd9db8eae9b1c93d7857b02683a1a825408a6801 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Wed, 10 Jul 2019 17:10:11 +0300 Subject: [PATCH 39/39] add CHANGELOG entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c18c34df3..de01af6032 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - [#2294](https://github.com/poanetwork/blockscout/pull/2294) - add healthy block period checking endpoint ### Fixes +- [#2341](https://github.com/poanetwork/blockscout/pull/2341) - fix transaction input json encoding - [#2310](https://github.com/poanetwork/blockscout/pull/2310) - parse url for api docs - [#2299](https://github.com/poanetwork/blockscout/pull/2299) - fix interpolation in error message - [#2303](https://github.com/poanetwork/blockscout/pull/2303) - fix transaction csv download link