diff --git a/CHANGELOG.md b/CHANGELOG.md index e577bbb25d..043d57d31f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ ### Fixes - [#2043](https://github.com/poanetwork/blockscout/pull/2043) - Fixed modal dialog width for 'verify other explorers' +- [#2025](https://github.com/poanetwork/blockscout/pull/2025) - Added a new color to display transactions' errors. - [#2033](https://github.com/poanetwork/blockscout/pull/2033) - Header nav. dropdown active element color issue - [#2019](https://github.com/poanetwork/blockscout/pull/2019) - Fixed the missing tx hashes. - [#2020](https://github.com/poanetwork/blockscout/pull/2020) - Fixed a bug triggered when a second click to a selected tab caused the other tabs to hide. @@ -40,6 +41,7 @@ - [#1960](https://github.com/poanetwork/blockscout/pull/1960) - do not remove bold text in decompiled contacts - [#1992](https://github.com/poanetwork/blockscout/pull/1992) - fix: support https for wobserver polling - [#1966](https://github.com/poanetwork/blockscout/pull/1966) - fix: add fields for contract filter performance +- [#2017](https://github.com/poanetwork/blockscout/pull/2017) - fix: fix to/from filters on tx list pages - [#2008](https://github.com/poanetwork/blockscout/pull/2008) - add new function clause for xDai network beneficiaries - [#2009](https://github.com/poanetwork/blockscout/pull/2009) - addresses page improvements diff --git a/apps/block_scout_web/assets/css/components/_tile.scss b/apps/block_scout_web/assets/css/components/_tile.scss index 4ed5bc6515..71cabbd1b3 100644 --- a/apps/block_scout_web/assets/css/components/_tile.scss +++ b/apps/block_scout_web/assets/css/components/_tile.scss @@ -11,22 +11,24 @@ $tile-type-unique-token-image-color: $orange !default; $tile-type-internal-transaction-color: $teal !default; $tile-type-api-documentation-color: $primary !default; $tile-type-progress-bar-color: $primary !default; - +$tile-status-error-reason: #ff7986 !default; +$tile-status-awaiting-internal-transactions: $warning !default; $tile-padding: 1rem; @mixin generate-tile-block($prefix, $color, $label-color: false) { + &#{ $prefix } { + border-left: 4px solid $color; - a { - @if ($label-color) { - color: $label-color; - } - @else { - color: $color; + .tile-transaction-type-block { + a { + @if ($label-color) { + color: $label-color; + } + @else { + color: $color; + } + } } - } - - &.tile-type-#{ $prefix } { - border-left: 4px solid $color; .tile-label { @if ($label-color) { @@ -182,18 +184,20 @@ $tile-padding: 1rem; line-height: 1.4rem; padding: $tile-padding; - @include generate-tile-block('block', $tile-type-block-color, darken($tile-type-block-color, 20%)); - @include generate-tile-block('uncle', $tile-type-uncle-color); - @include generate-tile-block('reorg', $tile-type-reorg-color); - @include generate-tile-block('emission-reward', $tile-type-emission-reward-color); - @include generate-tile-block('transaction', $tile-type-transaction-color); - @include generate-tile-block('contract-call', $tile-type-contract-call-color); - @include generate-tile-block('contract-creation', $tile-type-contract-creation-color); - @include generate-tile-block('token-transfer', $tile-type-token-transfer-color); - @include generate-tile-block('unique-token', $tile-type-unique-token-color); - @include generate-tile-block('unique-token-image', $tile-type-unique-token-image-color); - @include generate-tile-block('internal-transaction', $tile-type-internal-transaction-color); - @include generate-tile-block('api-documentation', $tile-type-api-documentation-color); + @include generate-tile-block('.tile-type-block', $tile-type-block-color, darken($tile-type-block-color, 20%)); + @include generate-tile-block('.tile-type-uncle', $tile-type-uncle-color); + @include generate-tile-block('.tile-type-reorg', $tile-type-reorg-color); + @include generate-tile-block('.tile-type-emission-reward', $tile-type-emission-reward-color); + @include generate-tile-block('.tile-type-transaction', $tile-type-transaction-color); + @include generate-tile-block('.tile-type-contract-call', $tile-type-contract-call-color); + @include generate-tile-block('.tile-type-contract-creation', $tile-type-contract-creation-color); + @include generate-tile-block('.tile-type-token-transfer', $tile-type-token-transfer-color); + @include generate-tile-block('.tile-type-unique-token', $tile-type-unique-token-color); + @include generate-tile-block('.tile-type-unique-token-image', $tile-type-unique-token-image-color); + @include generate-tile-block('.tile-type-internal-transaction', $tile-type-internal-transaction-color); + @include generate-tile-block('.tile-type-api-documentation', $tile-type-api-documentation-color); + @include generate-tile-block('[class*="status--error"]', $tile-status-error-reason); + @include generate-tile-block('.tile-status--awaiting-internal-transactions', $tile-status-awaiting-internal-transactions); &.n-p { padding: 0; @@ -256,26 +260,6 @@ $tile-padding: 1rem; width: 100%; } - .tile-status--error--reason { - border-bottom: 2px solid lighten($danger, 10%); - border-right: 2px solid lighten($danger, 10%); - border-top: 2px solid lighten($danger, 10%); - - .tile-status-label { - color: $danger; - } - } - - .tile-status--awaiting-internal-transactions { - border-bottom: 2px solid lighten($warning, 10%); - border-right: 2px solid lighten($warning, 10%); - border-top: 2px solid lighten($warning, 10%); - - .tile-status-label { - color: $warning; - } - } - /* Progress bar */ .progress { background-color: #f5f6fa; 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 f79d9aa08d..56be858452 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 @@ -6,13 +6,15 @@ defmodule BlockScoutWeb.AddressLogsController do import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1] import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1] + alias BlockScoutWeb.AddressLogsView alias Explorer.{Chain, Market} alias Explorer.ExchangeRates.Token alias Indexer.Fetcher.CoinBalanceOnDemand + alias Phoenix.View use BlockScoutWeb, :controller - def index(conn, %{"address_id" => address_hash_string} = params) 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) do logs_plus_one = Chain.address_to_logs(address, paging_options(params)) @@ -24,19 +26,45 @@ defmodule BlockScoutWeb.AddressLogsController do nil next_page_params -> - address_logs_path(conn, :index, address, next_page_params) + address_logs_path(conn, :index, address, Map.delete(next_page_params, "type")) end + items = + results + |> Enum.map(fn log -> + View.render_to_string( + AddressLogsView, + "_logs.html", + log: log, + conn: conn + ) + end) + + json( + conn, + %{ + items: items, + next_page_path: next_page_url + } + ) + else + _ -> + not_found(conn) + end + end + + def index(conn, %{"address_id" => address_hash_string}) do + with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), + {:ok, address} <- Chain.hash_to_address(address_hash) do render( conn, "index.html", address: address, - logs: results, + 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), - next_page_url: next_page_url + validation_count: validation_count(address) ) else _ -> 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 77db1b363f..312b90176b 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 @@ -1,29 +1,71 @@ defmodule BlockScoutWeb.AddressTokenController do use BlockScoutWeb, :controller + import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1] + import BlockScoutWeb.Chain, only: [next_page_params: 3, paging_options: 1, split_list_by_page: 1] + + alias BlockScoutWeb.AddressTokenView alias Explorer.{Chain, Market} alias Explorer.ExchangeRates.Token alias Indexer.Fetcher.CoinBalanceOnDemand + alias Phoenix.View - import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1] - import BlockScoutWeb.Chain, only: [next_page_params: 3, paging_options: 1, split_list_by_page: 1] - - def index(conn, %{"address_id" => address_hash_string} = params) 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) do tokens_plus_one = Chain.address_tokens_with_balance(address_hash, paging_options(params)) {tokens, next_page} = split_list_by_page(tokens_plus_one) + next_page_path = + case next_page_params(next_page, tokens, params) do + nil -> + nil + + next_page_params -> + address_token_path(conn, :index, address, Map.delete(next_page_params, "type")) + end + + items = + tokens + |> Market.add_price() + |> Enum.map(fn token -> + View.render_to_string( + AddressTokenView, + "_tokens.html", + token: token, + address: address, + conn: conn + ) + end) + + json( + conn, + %{ + items: items, + next_page_path: next_page_path + } + ) + else + :error -> + unprocessable_entity(conn) + + {:error, :not_found} -> + not_found(conn) + end + end + + def index(conn, %{"address_id" => address_hash_string} = _params) do + with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), + {:ok, address} <- Chain.hash_to_address(address_hash) do render( conn, "index.html", address: address, + 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), - next_page_params: next_page_params(next_page, tokens, params), - tokens: Market.add_price(tokens) + validation_count: validation_count(address) ) else :error -> diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/block_transaction_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/block_transaction_controller.ex index c61dff29b2..f54671e795 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/block_transaction_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/block_transaction_controller.ex @@ -5,20 +5,14 @@ defmodule BlockScoutWeb.BlockTransactionController do only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1] import Explorer.Chain, only: [hash_to_block: 2, number_to_block: 2, string_to_block_hash: 1] + + alias BlockScoutWeb.TransactionView alias Explorer.Chain + alias Phoenix.View - def index(conn, %{"block_hash_or_number" => formatted_block_hash_or_number} = params) do + def index(conn, %{"block_hash_or_number" => formatted_block_hash_or_number, "type" => "JSON"} = params) do with {:ok, block} <- - param_block_hash_or_number_to_block(formatted_block_hash_or_number, - necessity_by_association: %{ - [miner: :names] => :required, - :uncles => :optional, - :nephews => :optional, - :rewards => :optional - } - ) do - block_transaction_count = Chain.block_to_transaction_count(block) - + param_block_hash_or_number_to_block(formatted_block_hash_or_number, []) do full_options = Keyword.merge( [ @@ -36,13 +30,73 @@ defmodule BlockScoutWeb.BlockTransactionController do {transactions, next_page} = split_list_by_page(transactions_plus_one) + next_page_path = + case next_page_params(next_page, transactions, params) do + nil -> + nil + + next_page_params -> + block_transaction_path( + conn, + :index, + block, + Map.delete(next_page_params, "type") + ) + end + + items = + transactions + |> Enum.map(fn transaction -> + View.render_to_string( + TransactionView, + "_tile.html", + transaction: transaction + ) + end) + + json( + conn, + %{ + items: items, + next_page_path: next_page_path + } + ) + else + {:error, {:invalid, :hash}} -> + not_found(conn) + + {:error, {:invalid, :number}} -> + not_found(conn) + + {:error, :not_found} -> + conn + |> put_status(:not_found) + |> render( + "404.html", + block: nil, + block_above_tip: block_above_tip(formatted_block_hash_or_number) + ) + end + end + + def index(conn, %{"block_hash_or_number" => formatted_block_hash_or_number}) do + with {:ok, block} <- + param_block_hash_or_number_to_block(formatted_block_hash_or_number, + necessity_by_association: %{ + [miner: :names] => :required, + :uncles => :optional, + :nephews => :optional, + :rewards => :optional + } + ) do + block_transaction_count = Chain.block_to_transaction_count(block) + render( conn, "index.html", block: block, block_transaction_count: block_transaction_count, - next_page_params: next_page_params(next_page, transactions, params), - transactions: transactions + current_path: current_path(conn) ) else {:error, {:invalid, :hash}} -> diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/inventory_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/inventory_controller.ex index 321b377503..432c48742f 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/inventory_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/inventory_controller.ex @@ -1,12 +1,14 @@ defmodule BlockScoutWeb.Tokens.InventoryController do use BlockScoutWeb, :controller + alias BlockScoutWeb.Tokens.InventoryView alias Explorer.{Chain, Market} alias Explorer.Chain.TokenTransfer + alias Phoenix.View import BlockScoutWeb.Chain, only: [split_list_by_page: 1, default_paging_options: 0] - def index(conn, %{"token_id" => address_hash_string} = params) do + def index(conn, %{"token_id" => address_hash_string, "type" => "JSON"} = params) do with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), {:ok, token} <- Chain.token_from_address_hash(address_hash) do unique_tokens = @@ -17,14 +19,56 @@ defmodule BlockScoutWeb.Tokens.InventoryController do {unique_tokens_paginated, next_page} = split_list_by_page(unique_tokens) + next_page_path = + case unique_tokens_next_page(next_page, unique_tokens_paginated, params) do + nil -> + nil + + next_page_params -> + token_inventory_path( + conn, + :index, + address_hash_string, + Map.delete(next_page_params, "type") + ) + end + + items = + unique_tokens_paginated + |> Enum.map(fn token_transfer -> + View.render_to_string( + InventoryView, + "_token.html", + token_transfer: token_transfer + ) + end) + + json( + conn, + %{ + items: items, + next_page_path: next_page_path + } + ) + else + :error -> + not_found(conn) + + {:error, :not_found} -> + not_found(conn) + end + end + + def index(conn, %{"token_id" => address_hash_string}) do + with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), + {:ok, token} <- Chain.token_from_address_hash(address_hash) do render( conn, "index.html", + current_path: current_path(conn), token: Market.add_price(token), - unique_tokens: unique_tokens_paginated, total_token_transfers: Chain.count_token_transfers_from_token_hash(address_hash), - total_token_holders: token.holder_count || Chain.count_token_holders_from_token_hash(address_hash), - next_page_params: unique_tokens_next_page(next_page, unique_tokens_paginated, params) + total_token_holders: token.holder_count || Chain.count_token_holders_from_token_hash(address_hash) ) else :error -> diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/transaction_internal_transaction_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/transaction_internal_transaction_controller.ex index af011e3745..e318a74e78 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/transaction_internal_transaction_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/transaction_internal_transaction_controller.ex @@ -3,11 +3,12 @@ defmodule BlockScoutWeb.TransactionInternalTransactionController do import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1] - alias BlockScoutWeb.TransactionView + alias BlockScoutWeb.{InternalTransactionView, TransactionView} alias Explorer.{Chain, Market} alias Explorer.ExchangeRates.Token + alias Phoenix.View - def index(conn, %{"transaction_id" => hash_string} = params) do + def index(conn, %{"transaction_id" => hash_string, "type" => "JSON"} = params) do with {:ok, hash} <- Chain.string_to_transaction_hash(hash_string), {:ok, transaction} <- Chain.hash_to_transaction( @@ -37,14 +38,73 @@ defmodule BlockScoutWeb.TransactionInternalTransactionController do {internal_transactions, next_page} = split_list_by_page(internal_transactions_plus_one) + next_page_path = + case next_page_params(next_page, internal_transactions, params) do + nil -> + nil + + next_page_params -> + transaction_internal_transaction_path( + conn, + :index, + transaction, + Map.delete(next_page_params, "type") + ) + end + + items = + internal_transactions + |> Enum.map(fn internal_transaction -> + View.render_to_string( + InternalTransactionView, + "_tile.html", + internal_transaction: internal_transaction + ) + end) + + json( + conn, + %{ + items: items, + next_page_path: next_page_path + } + ) + else + :error -> + conn + |> put_status(422) + |> put_view(TransactionView) + |> render("invalid.html", transaction_hash: hash_string) + + {:error, :not_found} -> + conn + |> put_status(404) + |> put_view(TransactionView) + |> render("not_found.html", transaction_hash: hash_string) + end + end + + def index(conn, %{"transaction_id" => hash_string}) do + with {:ok, hash} <- Chain.string_to_transaction_hash(hash_string), + {:ok, transaction} <- + Chain.hash_to_transaction( + hash, + necessity_by_association: %{ + :block => :optional, + [created_contract_address: :names] => :optional, + [from_address: :names] => :optional, + [to_address: :names] => :optional, + [to_address: :smart_contract] => :optional, + :token_transfers => :optional + } + ) do render( conn, "index.html", exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), - internal_transactions: internal_transactions, + current_path: current_path(conn), block_height: Chain.block_height(), show_token_transfers: Chain.transaction_has_token_transfers?(hash), - next_page_params: next_page_params(next_page, internal_transactions, params), transaction: transaction ) else diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/transaction_log_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/transaction_log_controller.ex index 8b4e3877e0..0a87d12493 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/transaction_log_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/transaction_log_controller.ex @@ -3,24 +3,15 @@ defmodule BlockScoutWeb.TransactionLogController do import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1] - alias BlockScoutWeb.TransactionView + alias BlockScoutWeb.{TransactionLogView, TransactionView} alias Explorer.{Chain, Market} alias Explorer.ExchangeRates.Token + alias Phoenix.View - def index(conn, %{"transaction_id" => transaction_hash_string} = params) do + def index(conn, %{"transaction_id" => transaction_hash_string, "type" => "JSON"} = params) do with {:ok, transaction_hash} <- Chain.string_to_transaction_hash(transaction_hash_string), {:ok, transaction} <- - Chain.hash_to_transaction( - transaction_hash, - necessity_by_association: %{ - :block => :optional, - [created_contract_address: :names] => :optional, - [from_address: :names] => :required, - [to_address: :names] => :optional, - [to_address: :smart_contract] => :optional, - :token_transfers => :optional - } - ) do + Chain.hash_to_transaction(transaction_hash) do full_options = Keyword.merge( [ @@ -35,13 +26,69 @@ defmodule BlockScoutWeb.TransactionLogController do {logs, next_page} = split_list_by_page(logs_plus_one) + next_page_url = + case next_page_params(next_page, logs, params) do + nil -> + nil + + next_page_params -> + transaction_log_path(conn, :index, transaction, Map.delete(next_page_params, "type")) + end + + items = + logs + |> Enum.map(fn log -> + View.render_to_string( + TransactionLogView, + "_logs.html", + log: log, + conn: conn, + transaction: transaction + ) + end) + + json( + conn, + %{ + items: items, + next_page_path: next_page_url + } + ) + else + :error -> + conn + |> put_status(422) + |> put_view(TransactionView) + |> render("invalid.html", transaction_hash: transaction_hash_string) + + {:error, :not_found} -> + conn + |> put_status(404) + |> put_view(TransactionView) + |> render("not_found.html", transaction_hash: transaction_hash_string) + end + end + + def index(conn, %{"transaction_id" => transaction_hash_string}) do + with {:ok, transaction_hash} <- Chain.string_to_transaction_hash(transaction_hash_string), + {:ok, transaction} <- + Chain.hash_to_transaction( + transaction_hash, + necessity_by_association: %{ + :block => :optional, + [created_contract_address: :names] => :optional, + [from_address: :names] => :required, + [to_address: :names] => :optional, + [to_address: :smart_contract] => :optional, + :token_transfers => :optional + } + ) do render( conn, "index.html", - logs: logs, block_height: Chain.block_height(), show_token_transfers: Chain.transaction_has_token_transfers?(transaction_hash), - next_page_params: next_page_params(next_page, logs, params), + current_path: current_path(conn), transaction: transaction, exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null() ) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/transaction_token_transfer_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/transaction_token_transfer_controller.ex index baa36f1a2f..cfb215da3e 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/transaction_token_transfer_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/transaction_token_transfer_controller.ex @@ -3,24 +3,15 @@ defmodule BlockScoutWeb.TransactionTokenTransferController do import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1] - alias BlockScoutWeb.TransactionView + alias BlockScoutWeb.{TransactionTokenTransferView, TransactionView} alias Explorer.{Chain, Market} alias Explorer.ExchangeRates.Token + alias Phoenix.View - def index(conn, %{"transaction_id" => hash_string} = params) do + def index(conn, %{"transaction_id" => hash_string, "type" => "JSON"} = params) do with {:ok, hash} <- Chain.string_to_transaction_hash(hash_string), {:ok, transaction} <- - Chain.hash_to_transaction( - hash, - necessity_by_association: %{ - :block => :optional, - [created_contract_address: :names] => :optional, - [from_address: :names] => :optional, - [to_address: :names] => :optional, - [to_address: :smart_contract] => :optional, - :token_transfers => :optional - } - ) do + Chain.hash_to_transaction(hash) do full_options = Keyword.merge( [ @@ -37,13 +28,68 @@ defmodule BlockScoutWeb.TransactionTokenTransferController do {token_transfers, next_page} = split_list_by_page(token_transfers_plus_one) + next_page_url = + case next_page_params(next_page, token_transfers, params) do + nil -> + nil + + next_page_params -> + transaction_token_transfer_path(conn, :index, transaction, Map.delete(next_page_params, "type")) + end + + items = + token_transfers + |> Enum.map(fn transfer -> + View.render_to_string( + TransactionTokenTransferView, + "_token_transfer.html", + token_transfer: transfer, + conn: conn + ) + end) + + json( + conn, + %{ + items: items, + next_page_path: next_page_url + } + ) + else + :error -> + conn + |> put_status(422) + |> put_view(TransactionView) + |> render("invalid.html", transaction_hash: hash_string) + + {:error, :not_found} -> + conn + |> put_status(404) + |> put_view(TransactionView) + |> render("not_found.html", transaction_hash: hash_string) + end + end + + def index(conn, %{"transaction_id" => hash_string}) do + with {:ok, hash} <- Chain.string_to_transaction_hash(hash_string), + {:ok, transaction} <- + Chain.hash_to_transaction( + hash, + necessity_by_association: %{ + :block => :optional, + [created_contract_address: :names] => :optional, + [from_address: :names] => :optional, + [to_address: :names] => :optional, + [to_address: :smart_contract] => :optional, + :token_transfers => :optional + } + ) do render( conn, "index.html", exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), block_height: Chain.block_height(), - next_page_params: next_page_params(next_page, token_transfers, params), - token_transfers: token_transfers, + current_path: current_path(conn), show_token_transfers: true, transaction: transaction ) diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_logs/_logs.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_logs/_logs.html.eex new file mode 100644 index 0000000000..9d85567233 --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_logs/_logs.html.eex @@ -0,0 +1,54 @@ +
+
+
<%= gettext "Transaction" %>
+
+

+ <%= link( + @log.transaction, + to: transaction_path(@conn, :show, @log.transaction), + "data-test": "log_address_link", + "data-address-hash": @log.transaction + ) %> +

+
+
<%= gettext "Topics" %>
+
+
+ <%= unless is_nil(@log.first_topic) do %> +
+ [0] + <%= @log.first_topic %> +
+ <% end %> + <%= unless is_nil(@log.second_topic) do %> +
+ [1] + <%= @log.second_topic %> +
+ <% end %> + <%= unless is_nil(@log.third_topic) do %> +
+ [2] + <%= @log.third_topic %> +
+ <% end %> + <%= unless is_nil(@log.fourth_topic) do %> +
+ [3] + <%= @log.fourth_topic %> +
+ <% end %> +
+
+
+ <%= gettext "Data" %> +
+
+ <%= unless is_nil(@log.data) do %> +
+ <%= @log.data %> +
+ <% end %> +
+
+
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_logs/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_logs/index.html.eex index 22f446924f..9053158442 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_logs/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_logs/index.html.eex @@ -3,80 +3,26 @@
<%= render BlockScoutWeb.AddressView, "_tabs.html", assigns %> -
- +

<%= gettext "Logs" %>

- <%= if @next_page_url do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true, next_page_path: @next_page_url %> - <% end %> + <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %> - <%= if !@next_page_url do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true %> - <% end %> + - <%= if Enum.count(@logs) > 0 do %> - <%= for log <- @logs do %> -
-
-
<%= gettext "Transaction" %>
-
-

- <%= link( - log.transaction, - to: transaction_path(@conn, :show, log.transaction), - "data-test": "log_address_link", - "data-address-hash": log.transaction - ) %> -

-
-
<%= gettext "Topics" %>
-
-
- <%= unless is_nil(log.first_topic) do %> -
- [0] - <%= log.first_topic %> -
- <% end %> - <%= unless is_nil(log.second_topic) do %> -
- [1] - <%= log.second_topic %> -
- <% end %> - <%= unless is_nil(log.third_topic) do %> -
- [2] - <%= log.third_topic %> -
- <% end %> - <%= unless is_nil(log.fourth_topic) do %> -
- [3] - <%= log.fourth_topic %> -
- <% end %> -
-
-
- <%= gettext "Data" %> -
-
- <%= unless is_nil(log.data) do %> -
- <%= log.data %> -
- <% end %> -
-
+
+
+ <%= gettext "There are no logs for this address." %>
- <% end %> - <% else %> -
- <%= gettext "There are no logs for this address." %> -
- <% end %> +
+ +
+ + <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %> +
+
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_token/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_token/index.html.eex index 0f8ae6efb1..43457d3bc1 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_token/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_token/index.html.eex @@ -4,49 +4,24 @@
<%= render BlockScoutWeb.AddressView, "_tabs.html", assigns %> -
+

<%= gettext "Tokens" %>

- <%= if @next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true, next_page_path: address_token_path(@conn, :index, @address, @next_page_params) %> - <% end %> + <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %> - <%= if !@next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true %> - <% end %> + - <%= if Enum.any?(@tokens) do %> - <%= for token <- @tokens do %> - <%= render "_tokens.html", conn: @conn, token: token, address: @address %> - <% end %> - <% else %> -
- <%= gettext "There are no tokens for this address." %> +
+
+ <%= gettext "There are no tokens for this address." %>
- <% end %> +
- <%= if @next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true, next_page_path: address_token_path(@conn, :index, @address, @next_page_params) %> - <% end %> +
- <%= if !@next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true %> - <% end %> - - + <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %>
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/block_transaction/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/block_transaction/index.html.eex index eac466a3e5..a497ab1b7e 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/block_transaction/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/block_transaction/index.html.eex @@ -13,38 +13,26 @@ ) %>
-
-

<%= gettext "Transactions" %>

- - <%= if @next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true, next_page_path: transaction_path(@conn, :index, @next_page_params) %> - <% end %> - - <%= if !@next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true %> - <% end %> - - <%= if Enum.count(@transactions) > 0 do %> - - <%= for transaction <- @transactions do %> - <%= render BlockScoutWeb.TransactionView, "_tile.html", transaction: transaction %> - <% end %> - - <% else %> -
- <%= gettext "There are no transactions for this block." %> + +
+

<%= gettext "Transactions" %>

+ + <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %> + + + +
+
+ <%= gettext "There are no transactions for this block." %>
- <% end %> +
- <%= if @next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true, next_page_path: transaction_path(@conn, :index, @next_page_params) %> - <% end %> +
- <%= if !@next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true %> - <% end %> + <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %> -
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/tokens/inventory/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/tokens/inventory/index.html.eex index 4eb471e305..da834dbc88 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/tokens/inventory/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/tokens/inventory/index.html.eex @@ -12,28 +12,25 @@
<%= render OverviewView, "_tabs.html", assigns %> -
-

<%= gettext "Inventory" %>

- - <%= if Enum.any?(@unique_tokens) do %> - <%= for token_transfer <- @unique_tokens do %> - <%= render "_token.html", token_transfer: token_transfer %> - <% end %> - <% else %> -
- - <%= gettext "There are no tokens." %> - +
+

<%= gettext "Inventory" %>

+ + <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %> + + + +
+
+ <%= gettext "There are no tokens." %>
- <% end %> - - <%= if @next_page_params do %> - <%= link( - gettext("Next Page"), - class: "button button-secondary button-small float-right mt-4", - to: token_inventory_path(@conn, :index, @token.contract_address_hash, @next_page_params) - ) %> - <% end %> +
+ +
+ + <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %> +
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex index 42a89ea930..e6623b4061 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex @@ -2,49 +2,23 @@ <%= render BlockScoutWeb.TransactionView, "overview.html", assigns %>
<%= render BlockScoutWeb.TransactionView, "_tabs.html", assigns %> -
-

<%= gettext "Internal Transactions" %>

+
+

<%= gettext "Internal Transactions" %>

- <%= if @next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true, next_page_path: transaction_internal_transaction_path(@conn, :index, @transaction, @next_page_params) %> - <% end %> + <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %> - <%= if !@next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true %> - <% end %> - - <%= if Enum.count(@internal_transactions) > 0 do %> - <%= for internal_transaction <- @internal_transactions do %> - <%= render BlockScoutWeb.InternalTransactionView, "_tile.html", internal_transaction: internal_transaction %> - <% end %> - <% else %> -
- <%= gettext "There are no internal transactions for this transaction." %> + +
+
+ <%= gettext "There are no internal transactions for this transaction." %>
- <% end %> - - <%= if @next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true, next_page_path: transaction_internal_transaction_path(@conn, :index, @transaction, @next_page_params) %> - <% end %> +
- <%= if !@next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true %> - <% end %> +
- + <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %>
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/transaction_log/_logs.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/transaction_log/_logs.html.eex new file mode 100644 index 0000000000..5a52821601 --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/templates/transaction_log/_logs.html.eex @@ -0,0 +1,123 @@ +
+
+
<%= gettext "Address" %>
+
+

+ <%= link( + @log.address, + to: address_path(@conn, :show, @log.address), + "data-test": "log_address_link", + "data-address-hash": @log.address + ) %> +

+
+
<%= gettext "Decoded" %>
+
+ <%= case decode(@log, @transaction) do %> + <% {:error, :contract_not_verified} -> %> +
+ <%= gettext "To see decoded input data, the contract must be verified." %> + <%= case @transaction do %> + <% %{to_address: %{hash: hash}} -> %> + <%= gettext "Verify the contract " %><%= gettext "here" %> + <% _ -> %> + <%= nil %> + <% end %> +
+ <% {:error, :could_not_decode} -> %> +
+ <%= gettext "Failed to decode log data." %> +
+ <% {:ok, method_id, text, mapping} -> %> + + + + + + + + + +
Method Id0x<%= method_id %>
Call<%= text %>
+ " class="table thead-light table-bordered table-responsive"> + + + + + + + + <%= for {name, type, indexed?, value} <- mapping do %> + + + + + + + + <% end %> +
<%= gettext "Name" %><%= gettext "Type" %><%= gettext "Indexed?" %><%= gettext "Data" %>
+ <%= case BlockScoutWeb.ABIEncodedValueView.copy_text(type, value) do %> + <% :error -> %> + <%= nil %> + <% copy_text -> %> + + + + + + <% end %> + <%= name %><%= type %><%= indexed? %> +
<%= BlockScoutWeb.ABIEncodedValueView.value_html(type, value) %>
+
+ <% _ -> %> + <%= nil %> + <% end %> + +
<%= gettext "Topics" %>
+
+
+ <%= unless is_nil(@log.first_topic) do %> +
+ [0] + <%= @log.first_topic %> +
+ <% end %> + <%= unless is_nil(@log.second_topic) do %> +
+ [1] + <%= @log.second_topic %> +
+ <% end %> + <%= unless is_nil(@log.third_topic) do %> +
+ [2] + <%= @log.third_topic %> +
+ <% end %> + <%= unless is_nil(@log.fourth_topic) do %> +
+ [3] + <%= @log.fourth_topic %> +
+ <% end %> +
+
+
+ <%= gettext "Data" %> +
+
+ <%= unless is_nil(@log.data) do %> +
+ <%= @log.data %> +
+ <% end %> +
+
+
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/transaction_log/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/transaction_log/index.html.eex index b0e8260d4e..3c84e7c4f9 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/transaction_log/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/transaction_log/index.html.eex @@ -4,172 +4,25 @@
<%= render BlockScoutWeb.TransactionView, "_tabs.html", assigns %> -
+

<%= gettext "Logs" %>

- <%= if @next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true, next_page_path: transaction_log_path(@conn,:index, @transaction, @next_page_params) %> - <% end %> + <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %> - <%= if !@next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true %> - <% end %> + - <%= if Enum.count(@logs) > 0 do %> - <%= for log <- @logs do %> -
-
-
<%= gettext "Address" %>
-
-

- <%= link( - log.address, - to: address_path(@conn, :show, log.address), - "data-test": "log_address_link", - "data-address-hash": log.address - ) %> -

-
-
<%= gettext "Decoded" %>
-
- <%= case decode(log, @transaction) do %> - <% {:error, :contract_not_verified} -> %> -
- <%= gettext "To see decoded input data, the contract must be verified." %> - <%= case @transaction do %> - <% %{to_address: %{hash: hash}} -> %> - <%= gettext "Verify the contract " %><%= gettext "here" %> - <% _ -> %> - <%= nil %> - <% end %> -
- <% {:error, :could_not_decode} -> %> -
- <%= gettext "Failed to decode log data." %> -
- <% {:ok, method_id, text, mapping} -> %> - - - - - - - - - -
Method Id0x<%= method_id %>
Call<%= text %>
- " class="table thead-light table-bordered table-responsive"> - - - - - - - - <%= for {name, type, indexed?, value} <- mapping do %> - - - - - - - - <% end %> -
<%= gettext "Name" %><%= gettext "Type" %><%= gettext "Indexed?" %><%= gettext "Data" %>
- <%= case BlockScoutWeb.ABIEncodedValueView.copy_text(type, value) do %> - <% :error -> %> - <%= nil %> - <% copy_text -> %> - - - - - - <% end %> - <%= name %><%= type %><%= indexed? %> -
<%= BlockScoutWeb.ABIEncodedValueView.value_html(type, value) %>
-
- <% _ -> %> - <%= nil %> - <% end %> - -
-
<%= gettext "Topics" %>
-
-
- <%= unless is_nil(log.first_topic) do %> -
- [0] - <%= log.first_topic %> -
- <% end %> - <%= unless is_nil(log.second_topic) do %> -
- [1] - <%= log.second_topic %> -
- <% end %> - <%= unless is_nil(log.third_topic) do %> -
- [2] - <%= log.third_topic %> -
- <% end %> - <%= unless is_nil(log.fourth_topic) do %> -
- [3] - <%= log.fourth_topic %> -
- <% end %> -
-
-
- <%= gettext "Data" %> -
-
- <%= unless is_nil(log.data) do %> -
- <%= log.data %> -
- <% end %> -
-
+
+
+ <%= gettext "There are no logs for this transaction." %>
- <% end %> - <% else %> -
- <%= gettext "There are no logs for this transaction." %> -
- <% end %> +
- <%= if @next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true, next_page_path: transaction_log_path(@conn,:index, @transaction, @next_page_params) %> - <% end %> +
- <%= if !@next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true %> - <% end %> + <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %> -
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/transaction_token_transfer/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/transaction_token_transfer/index.html.eex index 53ef700b14..d40dedd414 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/transaction_token_transfer/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/transaction_token_transfer/index.html.eex @@ -3,34 +3,24 @@
<%= render BlockScoutWeb.TransactionView, "_tabs.html", assigns %> -
+

<%= gettext "Token Transfers" %>

- <%= if @next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true, next_page_path: transaction_token_transfer_path(@conn, :index, @transaction, @next_page_params) %> - <% end %> + <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %> - <%= if !@next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true %> - <% end %> + - <%= if Enum.any?(@token_transfers) do %> - <%= for token_transfer <- @token_transfers do %> - <%= render "_token_transfer.html", token_transfer: token_transfer, conn: @conn %> - <% end %> - <% else %> -
- <%= gettext "There are no token transfers for this transaction." %> +
+
+ <%= gettext "There are no token transfers for this transaction" %> +
- <% end %> - <%= if @next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true, next_page_path: transaction_token_transfer_path(@conn, :index, @transaction, @next_page_params) %> - <% end %> +
- <%= if !@next_page_params do %> - <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true %> - <% end %> + <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %>
diff --git a/apps/block_scout_web/priv/gettext/default.pot b/apps/block_scout_web/priv/gettext/default.pot index 9ba6b4c23b..c62c47d890 100644 --- a/apps/block_scout_web/priv/gettext/default.pot +++ b/apps/block_scout_web/priv/gettext/default.pot @@ -98,7 +98,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:16 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:22 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:3 #: lib/block_scout_web/views/address_view.ex:99 msgid "Address" msgstr "" @@ -327,10 +327,10 @@ msgid "Curl" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/index.html.eex:63 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:44 #: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:18 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:67 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:133 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:48 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:113 msgid "Data" msgstr "" @@ -500,7 +500,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/_tabs.html.eex:26 -#: lib/block_scout_web/templates/address_logs/index.html.eex:8 +#: lib/block_scout_web/templates/address_logs/index.html.eex:7 #: lib/block_scout_web/templates/transaction/_tabs.html.eex:17 #: lib/block_scout_web/templates/transaction_log/index.html.eex:8 #: lib/block_scout_web/views/address_view.ex:314 @@ -558,7 +558,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:52 #: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:16 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:64 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:45 msgid "Name" msgstr "" @@ -567,23 +567,6 @@ msgstr "" msgid "New Smart Contract" msgstr "" -#, elixir-format -#: -#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:37 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:162 -msgid "Newer" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/address_token/index.html.eex:39 -msgid "Next" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:32 -msgid "Next Page" -msgstr "" - #, elixir-format #: lib/block_scout_web/templates/address_contract_verification/new.html.eex:40 msgid "No" @@ -743,12 +726,12 @@ msgstr "" #, elixir-format #: -#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:22 +#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:15 msgid "There are no internal transactions for this transaction." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction_log/index.html.eex:147 +#: lib/block_scout_web/templates/transaction_log/index.html.eex:18 msgid "There are no logs for this transaction." msgstr "" @@ -758,17 +741,12 @@ msgid "There are no token transfers for this address." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:23 -msgid "There are no token transfers for this transaction." -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/address_token/index.html.eex:24 +#: lib/block_scout_web/templates/address_token/index.html.eex:18 msgid "There are no tokens for this address." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:25 +#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:26 msgid "There are no tokens." msgstr "" @@ -778,7 +756,7 @@ msgid "There are no transactions for this address." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block_transaction/index.html.eex:35 +#: lib/block_scout_web/templates/block_transaction/index.html.eex:28 msgid "There are no transactions for this block." msgstr "" @@ -855,8 +833,8 @@ msgid "Top Accounts - %{subnetwork} Explorer" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/index.html.eex:33 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:103 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:14 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:83 msgid "Topics" msgstr "" @@ -876,7 +854,7 @@ msgid "Total transactions" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/index.html.eex:22 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:3 #: lib/block_scout_web/views/transaction_view.ex:287 msgid "Transaction" msgstr "" @@ -900,7 +878,7 @@ msgstr "" #: lib/block_scout_web/templates/address/_tabs.html.eex:3 #: lib/block_scout_web/templates/address_transaction/index.html.eex:15 #: lib/block_scout_web/templates/block_transaction/index.html.eex:10 -#: lib/block_scout_web/templates/block_transaction/index.html.eex:17 +#: lib/block_scout_web/templates/block_transaction/index.html.eex:18 #: lib/block_scout_web/templates/chain/show.html.eex:108 #: lib/block_scout_web/templates/layout/_topnav.html.eex:35 #: lib/block_scout_web/views/address_view.ex:307 @@ -1163,18 +1141,18 @@ msgid "Static Call" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction_log/index.html.eex:33 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:14 msgid "Decoded" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction_log/index.html.eex:66 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:47 msgid "Indexed?" msgstr "" #, elixir-format #: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:17 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:65 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:46 msgid "Type" msgstr "" @@ -1184,7 +1162,7 @@ msgid "Method Id" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction_log/index.html.eex:38 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:19 msgid "To see decoded input data, the contract must be verified." msgstr "" @@ -1200,13 +1178,13 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:11 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:41 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:22 msgid "Verify the contract " msgstr "" #, elixir-format #: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:11 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:41 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:22 msgid "here" msgstr "" @@ -1222,31 +1200,38 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:28 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:77 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:58 msgid "Copy Value" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction_log/index.html.eex:48 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:29 msgid "Failed to decode log data." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction_log/index.html.eex:61 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:42 msgid "Log Data" msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_coin_balance/index.html.eex:34 #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:61 +#: lib/block_scout_web/templates/address_logs/index.html.eex:12 +#: lib/block_scout_web/templates/address_token/index.html.eex:13 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:20 #: lib/block_scout_web/templates/address_transaction/index.html.eex:57 #: lib/block_scout_web/templates/address_validation/index.html.eex:22 +#: lib/block_scout_web/templates/block_transaction/index.html.eex:23 #: lib/block_scout_web/templates/chain/show.html.eex:91 #: lib/block_scout_web/templates/pending_transaction/index.html.eex:19 #: lib/block_scout_web/templates/tokens/holder/index.html.eex:21 +#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:21 #: lib/block_scout_web/templates/tokens/transfer/index.html.eex:20 #: lib/block_scout_web/templates/transaction/index.html.eex:20 +#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:11 +#: lib/block_scout_web/templates/transaction_log/index.html.eex:13 +#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:12 msgid "Something went wrong, click to reload." msgstr "" @@ -1697,15 +1682,10 @@ msgid "Displaying the init data provided of the creating transaction." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/index.html.eex:77 +#: lib/block_scout_web/templates/address_logs/index.html.eex:17 msgid "There are no logs for this address." msgstr "" -#, elixir-format -#: lib/block_scout_web/templates/transaction/not_found.html.eex:7 -msgid "Sorry, We are unable to locate this transaction Hash" -msgstr "" - #, elixir-format #: lib/block_scout_web/templates/transaction/not_found.html.eex:12 msgid "If you have just submitted this transaction please wait for at least 30 seconds before refreshing this page." @@ -1730,3 +1710,13 @@ msgstr "" #: lib/block_scout_web/templates/transaction/not_found.html.eex:16 msgid "It could still be in the TX Pool of a different node, waiting to be broadcasted." msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/transaction/not_found.html.eex:7 +msgid "Sorry, We are unable to locate this transaction Hash" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:17 +msgid "There are no token transfers for this transaction" +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 d40a699752..23a85c844b 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 @@ -98,7 +98,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:16 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:22 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:3 #: lib/block_scout_web/views/address_view.ex:99 msgid "Address" msgstr "" @@ -327,10 +327,10 @@ msgid "Curl" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/index.html.eex:63 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:44 #: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:18 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:67 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:133 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:48 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:113 msgid "Data" msgstr "" @@ -500,7 +500,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/_tabs.html.eex:26 -#: lib/block_scout_web/templates/address_logs/index.html.eex:8 +#: lib/block_scout_web/templates/address_logs/index.html.eex:7 #: lib/block_scout_web/templates/transaction/_tabs.html.eex:17 #: lib/block_scout_web/templates/transaction_log/index.html.eex:8 #: lib/block_scout_web/views/address_view.ex:309 @@ -558,7 +558,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:52 #: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:16 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:64 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:45 msgid "Name" msgstr "" @@ -567,23 +567,6 @@ msgstr "" msgid "New Smart Contract" msgstr "" -#, elixir-format -#: -#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:37 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:162 -msgid "Newer" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/address_token/index.html.eex:39 -msgid "Next" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:32 -msgid "Next Page" -msgstr "" - #, elixir-format #: lib/block_scout_web/templates/address_contract_verification/new.html.eex:40 msgid "No" @@ -743,12 +726,12 @@ msgstr "" #, elixir-format #: -#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:22 +#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:15 msgid "There are no internal transactions for this transaction." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction_log/index.html.eex:147 +#: lib/block_scout_web/templates/transaction_log/index.html.eex:18 msgid "There are no logs for this transaction." msgstr "" @@ -758,17 +741,12 @@ msgid "There are no token transfers for this address." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:23 -msgid "There are no token transfers for this transaction." -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/address_token/index.html.eex:24 +#: lib/block_scout_web/templates/address_token/index.html.eex:18 msgid "There are no tokens for this address." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:25 +#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:26 msgid "There are no tokens." msgstr "" @@ -778,7 +756,7 @@ msgid "There are no transactions for this address." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block_transaction/index.html.eex:35 +#: lib/block_scout_web/templates/block_transaction/index.html.eex:28 msgid "There are no transactions for this block." msgstr "" @@ -855,8 +833,8 @@ msgid "Top Accounts - %{subnetwork} Explorer" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/index.html.eex:33 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:103 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:14 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:83 msgid "Topics" msgstr "" @@ -876,7 +854,7 @@ msgid "Total transactions" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/index.html.eex:22 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:3 #: lib/block_scout_web/views/transaction_view.ex:287 msgid "Transaction" msgstr "" @@ -900,7 +878,7 @@ msgstr "" #: lib/block_scout_web/templates/address/_tabs.html.eex:3 #: lib/block_scout_web/templates/address_transaction/index.html.eex:15 #: lib/block_scout_web/templates/block_transaction/index.html.eex:10 -#: lib/block_scout_web/templates/block_transaction/index.html.eex:17 +#: lib/block_scout_web/templates/block_transaction/index.html.eex:18 #: lib/block_scout_web/templates/chain/show.html.eex:108 #: lib/block_scout_web/templates/layout/_topnav.html.eex:35 #: lib/block_scout_web/views/address_view.ex:302 @@ -1163,18 +1141,18 @@ msgid "Static Call" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction_log/index.html.eex:33 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:14 msgid "Decoded" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction_log/index.html.eex:66 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:47 msgid "Indexed?" msgstr "" #, elixir-format #: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:17 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:65 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:46 msgid "Type" msgstr "" @@ -1184,7 +1162,7 @@ msgid "Method Id" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction_log/index.html.eex:38 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:19 msgid "To see decoded input data, the contract must be verified." msgstr "" @@ -1200,13 +1178,13 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:11 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:41 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:22 msgid "Verify the contract " msgstr "" #, elixir-format #: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:11 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:41 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:22 msgid "here" msgstr "" @@ -1222,31 +1200,38 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:28 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:77 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:58 msgid "Copy Value" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction_log/index.html.eex:48 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:29 msgid "Failed to decode log data." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction_log/index.html.eex:61 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:42 msgid "Log Data" msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_coin_balance/index.html.eex:34 #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:61 +#: lib/block_scout_web/templates/address_logs/index.html.eex:12 +#: lib/block_scout_web/templates/address_token/index.html.eex:13 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:20 #: lib/block_scout_web/templates/address_transaction/index.html.eex:57 #: lib/block_scout_web/templates/address_validation/index.html.eex:22 +#: lib/block_scout_web/templates/block_transaction/index.html.eex:23 #: lib/block_scout_web/templates/chain/show.html.eex:91 #: lib/block_scout_web/templates/pending_transaction/index.html.eex:19 #: lib/block_scout_web/templates/tokens/holder/index.html.eex:21 +#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:21 #: lib/block_scout_web/templates/tokens/transfer/index.html.eex:20 #: lib/block_scout_web/templates/transaction/index.html.eex:20 +#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:11 +#: lib/block_scout_web/templates/transaction_log/index.html.eex:13 +#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:12 msgid "Something went wrong, click to reload." msgstr "" @@ -1697,15 +1682,10 @@ msgid "Displaying the init data provided of the creating transaction." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/index.html.eex:77 +#: lib/block_scout_web/templates/address_logs/index.html.eex:17 msgid "There are no logs for this address." msgstr "" -#, elixir-format -#: lib/block_scout_web/templates/transaction/not_found.html.eex:7 -msgid "Sorry, We are unable to locate this transaction Hash" -msgstr "" - #, elixir-format #: lib/block_scout_web/templates/transaction/not_found.html.eex:12 msgid "If you have just submitted this transaction please wait for at least 30 seconds before refreshing this page." @@ -1729,4 +1709,14 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/transaction/not_found.html.eex:16 msgid "It could still be in the TX Pool of a different node, waiting to be broadcasted." -msgstr "" \ No newline at end of file +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/transaction/not_found.html.eex:7 +msgid "Sorry, We are unable to locate this transaction Hash" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:17 +msgid "There are no token transfers for this transaction" +msgstr "" diff --git a/apps/block_scout_web/test/block_scout_web/controllers/address_token_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/address_token_controller_test.exs index 0b4008611f..31a1c2c5cf 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/address_token_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/address_token_controller_test.exs @@ -57,15 +57,15 @@ defmodule BlockScoutWeb.AddressTokenControllerTest do to_address: address ) - conn = get(conn, address_token_path(conn, :index, address)) + conn = get(conn, address_token_path(conn, :index, address), type: "JSON") - actual_token_hashes = - conn.assigns.tokens - |> Enum.map(& &1.contract_address_hash) + {:ok, %{"items" => items}} = + conn.resp_body + |> Poison.decode() - assert html_response(conn, 200) - assert Enum.member?(actual_token_hashes, token1.contract_address_hash) - refute Enum.member?(actual_token_hashes, token2.contract_address_hash) + assert json_response(conn, 200) + assert Enum.any?(items, fn item -> String.contains?(item, to_string(token1.contract_address_hash)) end) + refute Enum.any?(items, fn item -> String.contains?(item, to_string(token2.contract_address_hash)) end) end test "returns next page of results based on last seen token", %{conn: conn} do @@ -102,15 +102,17 @@ defmodule BlockScoutWeb.AddressTokenControllerTest do get(conn, address_token_path(BlockScoutWeb.Endpoint, :index, address.hash), %{ "token_name" => name, "token_type" => type, - "token_inserted_at" => inserted_at + "token_inserted_at" => inserted_at, + "type" => "JSON" }) - actual_tokens = - conn.assigns.tokens - |> Enum.map(& &1.name) - |> Enum.sort() + {:ok, %{"items" => items}} = + conn.resp_body + |> Poison.decode() - assert second_page_tokens == actual_tokens + assert Enum.any?(items, fn item -> + Enum.any?(second_page_tokens, fn token_name -> String.contains?(item, token_name) end) + end) end test "next_page_params exists if not on last page", %{conn: conn} do @@ -129,9 +131,13 @@ defmodule BlockScoutWeb.AddressTokenControllerTest do insert(:token_transfer, token_contract_address: token.contract_address, from_address: address) end) - conn = get(conn, address_token_path(BlockScoutWeb.Endpoint, :index, address.hash)) + conn = get(conn, address_token_path(BlockScoutWeb.Endpoint, :index, address.hash), type: "JSON") + + {:ok, %{"next_page_path" => next_page_path}} = + conn.resp_body + |> Poison.decode() - assert conn.assigns.next_page_params + assert next_page_path end test "next_page_params are empty if on last page", %{conn: conn} do @@ -139,9 +145,13 @@ defmodule BlockScoutWeb.AddressTokenControllerTest do token = insert(:token) insert(:token_transfer, token_contract_address: token.contract_address, from_address: address) - conn = get(conn, address_token_path(BlockScoutWeb.Endpoint, :index, address.hash)) + conn = get(conn, address_token_path(BlockScoutWeb.Endpoint, :index, address.hash), type: "JSON") + + {:ok, %{"next_page_path" => next_page_path}} = + conn.resp_body + |> Poison.decode() - refute conn.assigns.next_page_params + refute next_page_path end end end diff --git a/apps/block_scout_web/test/block_scout_web/controllers/block_transaction_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/block_transaction_controller_test.exs index b8f6233e49..5b1ae46705 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/block_transaction_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/block_transaction_controller_test.exs @@ -39,10 +39,15 @@ defmodule BlockScoutWeb.BlockTransactionControllerTest do |> with_block(block) |> with_contract_creation(insert(:contract_address)) - conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, block.number)) + conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, block), %{type: "JSON"}) - assert html_response(conn, 200) - assert 2 == Enum.count(conn.assigns.transactions) + assert json_response(conn, 200) + + {:ok, %{"items" => items}} = + conn.resp_body + |> Poison.decode() + + assert Enum.count(items) == 2 end test "non-consensus block number without consensus blocks is treated as consensus number above tip", %{conn: conn} do @@ -77,10 +82,15 @@ defmodule BlockScoutWeb.BlockTransactionControllerTest do |> insert() |> with_block(block) - conn = get(conn, block_transaction_path(conn, :index, block.hash)) + conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, block), %{type: "JSON"}) + + assert json_response(conn, 200) - assert html_response(conn, 200) - assert Enum.count(conn.assigns.transactions) == 1 + {:ok, %{"items" => items}} = + conn.resp_body + |> Poison.decode() + + assert Enum.count(items) == 1 end test "does not return transactions for non-consensus block hash", %{conn: conn} do @@ -89,10 +99,15 @@ defmodule BlockScoutWeb.BlockTransactionControllerTest do transaction = insert(:transaction) insert(:transaction_fork, hash: transaction.hash, uncle_hash: block.hash) - conn = get(conn, block_transaction_path(conn, :index, block.hash)) + conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, block), %{type: "JSON"}) + + assert json_response(conn, 200) + + {:ok, %{"items" => items}} = + conn.resp_body + |> Poison.decode() - assert html_response(conn, 200) - assert Enum.count(conn.assigns.transactions) == 0 + assert Enum.empty?(items) end test "does not return transactions for invalid block hash", %{conn: conn} do @@ -111,44 +126,62 @@ defmodule BlockScoutWeb.BlockTransactionControllerTest do insert(:transaction) block = insert(:block) - conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, block)) + conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, block), %{type: "JSON"}) - assert html_response(conn, 200) - assert Enum.empty?(conn.assigns.transactions) + assert json_response(conn, 200) + + {:ok, %{"items" => items}} = + conn.resp_body + |> Poison.decode() + + assert Enum.empty?(items) end test "does not return related transactions without a block", %{conn: conn} do block = insert(:block) insert(:transaction) - conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, block)) + conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, block), %{type: "JSON"}) + + assert json_response(conn, 200) - assert html_response(conn, 200) - assert Enum.empty?(conn.assigns.transactions) + {:ok, %{"items" => items}} = + conn.resp_body + |> Poison.decode() + + assert Enum.empty?(items) end - test "next_page_params exist if not on last page", %{conn: conn} do + test "next_page_path exists if not on last page", %{conn: conn} do block = %Block{number: number} = insert(:block) 60 |> insert_list(:transaction) |> with_block(block) - conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, block)) + conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, block), %{type: "JSON"}) + + {:ok, %{"next_page_path" => next_page_path}} = + conn.resp_body + |> Poison.decode() - assert %{"block_number" => ^number, "index" => 10} = conn.assigns.next_page_params + assert next_page_path end - test "next_page_params are empty if on last page", %{conn: conn} do + test "next_page_path is empty if on last page", %{conn: conn} do block = insert(:block) :transaction |> insert() |> with_block(block) - conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, block)) + conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, block), %{type: "JSON"}) + + {:ok, %{"next_page_path" => next_page_path}} = + conn.resp_body + |> Poison.decode() - refute conn.assigns.next_page_params + refute next_page_path end test "displays miner primary address name", %{conn: conn} do diff --git a/apps/block_scout_web/test/block_scout_web/controllers/tokens/inventory_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/tokens/inventory_controller_test.exs index 1c131df177..f343353d45 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/tokens/inventory_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/tokens/inventory_controller_test.exs @@ -62,13 +62,20 @@ defmodule BlockScoutWeb.Tokens.InventoryControllerTest do conn = get(conn, token_inventory_path(conn, :index, token.contract_address_hash), %{ - "token_id" => "999" + "token_id" => "999", + "type" => "JSON" }) - assert Enum.map(conn.assigns.unique_tokens, & &1.token_id) == Enum.map(second_page_token_balances, & &1.token_id) + conn = get(conn, token_inventory_path(conn, :index, token.contract_address_hash), %{type: "JSON"}) + + {:ok, %{"items" => items}} = + conn.resp_body + |> Poison.decode() + + assert Enum.count(items) == Enum.count(second_page_token_balances) end - test "next_page_params exists if not on last page", %{conn: conn} do + test "next_page_path exists if not on last page", %{conn: conn} do token = insert(:token, type: "ERC-721") transaction = @@ -87,17 +94,16 @@ defmodule BlockScoutWeb.Tokens.InventoryControllerTest do ) ) - expected_next_page_params = %{ - "token_id" => to_string(token.contract_address_hash), - "unique_token" => 1050 - } + conn = get(conn, token_inventory_path(conn, :index, token.contract_address_hash), %{type: "JSON"}) - conn = get(conn, token_inventory_path(conn, :index, token.contract_address_hash)) + {:ok, %{"next_page_path" => next_page_path}} = + conn.resp_body + |> Poison.decode() - assert conn.assigns.next_page_params == expected_next_page_params + assert next_page_path end - test "next_page_params are empty if on last page", %{conn: conn} do + test "next_page_path is empty if on last page", %{conn: conn} do token = insert(:token, type: "ERC-721") transaction = @@ -113,9 +119,13 @@ defmodule BlockScoutWeb.Tokens.InventoryControllerTest do token_id: 1000 ) - conn = get(conn, token_inventory_path(conn, :index, token.contract_address_hash)) + conn = get(conn, token_inventory_path(conn, :index, token.contract_address_hash), %{type: "JSON"}) + + {:ok, %{"next_page_path" => next_page_path}} = + conn.resp_body + |> Poison.decode() - refute conn.assigns.next_page_params + refute next_page_path end end end diff --git a/apps/block_scout_web/test/block_scout_web/controllers/transaction_internal_transaction_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/transaction_internal_transaction_controller_test.exs index cf8016a774..6b9a32d280 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/transaction_internal_transaction_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/transaction_internal_transaction_controller_test.exs @@ -3,7 +3,7 @@ defmodule BlockScoutWeb.TransactionInternalTransactionControllerTest do import BlockScoutWeb.Router.Helpers, only: [transaction_internal_transaction_path: 3] - alias Explorer.Chain.{Block, InternalTransaction, Transaction} + alias Explorer.Chain.InternalTransaction alias Explorer.ExchangeRates.Token describe "GET index/3" do @@ -40,13 +40,12 @@ defmodule BlockScoutWeb.TransactionInternalTransactionControllerTest do |> insert() |> with_block(insert(:block, number: 1)) - expected_internal_transaction = - insert(:internal_transaction, - transaction: transaction, - index: 0, - block_number: transaction.block_number, - transaction_index: transaction.index - ) + insert(:internal_transaction, + transaction: transaction, + index: 0, + block_number: transaction.block_number, + transaction_index: transaction.index + ) insert(:internal_transaction, transaction: transaction, @@ -57,14 +56,15 @@ defmodule BlockScoutWeb.TransactionInternalTransactionControllerTest do path = transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, transaction.hash) - conn = get(conn, path) + conn = get(conn, path, %{type: "JSON"}) - actual_internal_transaction_primary_keys = - Enum.map(conn.assigns.internal_transactions, &{&1.transaction_hash, &1.index}) + {:ok, %{"items" => items}} = + conn.resp_body + |> Poison.decode() - assert html_response(conn, 200) + assert json_response(conn, 200) - assert {expected_internal_transaction.transaction_hash, expected_internal_transaction.index} in actual_internal_transaction_primary_keys + assert Enum.count(items) == 2 end test "includes USD exchange rate value for address in assigns", %{conn: conn} do @@ -135,21 +135,21 @@ defmodule BlockScoutWeb.TransactionInternalTransactionControllerTest do conn = get(conn, transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, transaction.hash), %{ - "index" => Integer.to_string(index) + "index" => Integer.to_string(index), + "type" => "JSON" }) - actual_indexes = - conn.assigns.internal_transactions - |> Enum.map(& &1.index) + {:ok, %{"items" => items}} = + conn.resp_body + |> Poison.decode() - assert second_page_indexes == actual_indexes + assert Enum.count(items) == Enum.count(second_page_indexes) end - test "next_page_params exist if not on last page", %{conn: conn} do - block = %Block{number: number} = insert(:block, number: 7000) + test "next_page_path exists if not on last page", %{conn: conn} do + block = insert(:block, number: 7000) transaction = - %Transaction{index: transaction_index} = :transaction |> insert() |> with_block(block) @@ -165,13 +165,19 @@ defmodule BlockScoutWeb.TransactionInternalTransactionControllerTest do ) end) - conn = get(conn, transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, transaction.hash)) + conn = + get(conn, transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, transaction.hash), %{ + type: "JSON" + }) + + {:ok, %{"next_page_path" => next_page_path}} = + conn.resp_body + |> Poison.decode() - assert %{"block_number" => ^number, "index" => 50, "transaction_index" => ^transaction_index} = - conn.assigns.next_page_params + assert next_page_path end - test "next_page_params are empty if on last page", %{conn: conn} do + test "next_page_path is empty if on last page", %{conn: conn} do transaction = :transaction |> insert() @@ -188,9 +194,16 @@ defmodule BlockScoutWeb.TransactionInternalTransactionControllerTest do ) end) - conn = get(conn, transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, transaction.hash)) + conn = + get(conn, transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, transaction.hash), %{ + type: "JSON" + }) + + {:ok, %{"next_page_path" => next_page_path}} = + conn.resp_body + |> Poison.decode() - refute conn.assigns.next_page_params + refute next_page_path end end end diff --git a/apps/block_scout_web/test/block_scout_web/controllers/transaction_log_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/transaction_log_controller_test.exs index e87405804e..05c7638d52 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/transaction_log_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/transaction_log_controller_test.exs @@ -31,11 +31,12 @@ defmodule BlockScoutWeb.TransactionLogControllerTest do address = insert(:address) insert(:log, address: address, transaction: transaction) - conn = get(conn, transaction_log_path(conn, :index, transaction)) + conn = get(conn, transaction_log_path(conn, :index, transaction), %{type: "JSON"}) - first_log = List.first(conn.assigns.logs) + {:ok, %{"items" => items}} = conn.resp_body |> Poison.decode() + first_log = List.first(items) - assert first_log.transaction_hash == transaction.hash + assert String.contains?(first_log, to_string(address.hash)) end test "returns logs for the transaction with nil to_address", %{conn: conn} do @@ -47,20 +48,23 @@ defmodule BlockScoutWeb.TransactionLogControllerTest do address = insert(:address) insert(:log, address: address, transaction: transaction) - conn = get(conn, transaction_log_path(conn, :index, transaction)) + conn = get(conn, transaction_log_path(conn, :index, transaction), %{type: "JSON"}) - first_log = List.first(conn.assigns.logs) + {:ok, %{"items" => items}} = conn.resp_body |> Poison.decode() + first_log = List.first(items) - assert first_log.transaction_hash == transaction.hash + assert String.contains?(first_log, to_string(address.hash)) end test "assigns no logs when there are none", %{conn: conn} do transaction = insert(:transaction) path = transaction_log_path(conn, :index, transaction) - conn = get(conn, path) + conn = get(conn, path, %{type: "JSON"}) - assert Enum.count(conn.assigns.logs) == 0 + {:ok, %{"items" => items}} = conn.resp_body |> Poison.decode() + + assert Enum.empty?(items) end test "returns next page of results based on last seen transaction log", %{conn: conn} do @@ -78,15 +82,16 @@ defmodule BlockScoutWeb.TransactionLogControllerTest do conn = get(conn, transaction_log_path(conn, :index, transaction), %{ - "index" => Integer.to_string(log.index) + "index" => Integer.to_string(log.index), + "type" => "JSON" }) - actual_indexes = Enum.map(conn.assigns.logs, & &1.index) + {:ok, %{"items" => items}} = conn.resp_body |> Poison.decode() - assert second_page_indexes == actual_indexes + assert Enum.count(items) == Enum.count(second_page_indexes) end - test "next_page_params exist if not on last page", %{conn: conn} do + test "next_page_path exists if not on last page", %{conn: conn} do transaction = :transaction |> insert() @@ -95,20 +100,24 @@ defmodule BlockScoutWeb.TransactionLogControllerTest do 1..60 |> Enum.map(fn index -> insert(:log, transaction: transaction, index: index) end) - conn = get(conn, transaction_log_path(conn, :index, transaction)) + conn = get(conn, transaction_log_path(conn, :index, transaction), %{type: "JSON"}) + + {:ok, %{"next_page_path" => path}} = conn.resp_body |> Poison.decode() - assert %{"index" => 50} = conn.assigns.next_page_params + assert path end - test "next_page_params are empty if on last page", %{conn: conn} do + test "next_page_path is empty if on last page", %{conn: conn} do transaction = :transaction |> insert() |> with_block() - conn = get(conn, transaction_log_path(conn, :index, transaction)) + conn = get(conn, transaction_log_path(conn, :index, transaction), %{type: "JSON"}) + + {:ok, %{"next_page_path" => path}} = conn.resp_body |> Poison.decode() - refute conn.assigns.next_page_params + refute path end end diff --git a/apps/block_scout_web/test/block_scout_web/controllers/transaction_token_transfer_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/transaction_token_transfer_controller_test.exs index 4ff1801610..ca183f5289 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/transaction_token_transfer_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/transaction_token_transfer_controller_test.exs @@ -48,24 +48,19 @@ defmodule BlockScoutWeb.TransactionTokenTransferControllerTest do test "includes token transfers for the transaction", %{conn: conn} do transaction = insert(:transaction) - expected_token_transfer = insert(:token_transfer, transaction: transaction) + insert(:token_transfer, transaction: transaction) insert(:token_transfer, transaction: transaction) path = transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, transaction.hash) - conn = get(conn, path) + conn = get(conn, path, %{type: "JSON"}) - actual_token_transfer_primary_keys = - conn.assigns.token_transfers - |> Enum.map(&{&1.transaction_hash, &1.log_index}) + assert json_response(conn, 200) - assert html_response(conn, 200) + {:ok, %{"items" => items}} = conn.resp_body |> Poison.decode() - assert Enum.member?( - actual_token_transfer_primary_keys, - {expected_token_transfer.transaction_hash, expected_token_transfer.log_index} - ) + assert Enum.count(items) == 2 end test "includes USD exchange rate value for address in assigns", %{conn: conn} do @@ -82,7 +77,7 @@ defmodule BlockScoutWeb.TransactionTokenTransferControllerTest do |> insert() |> with_block() - token_transfer = insert(:token_transfer, transaction: transaction, block_number: 1000, log_index: 1) + insert(:token_transfer, transaction: transaction, block_number: 1000, log_index: 1) Enum.each(2..5, fn item -> insert(:token_transfer, transaction: transaction, block_number: item + 1001, log_index: item + 1) @@ -91,15 +86,16 @@ defmodule BlockScoutWeb.TransactionTokenTransferControllerTest do conn = get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, transaction.hash), %{ "block_number" => "1000", - "index" => "1" + "index" => "1", + "type" => "JSON" }) - actual_log_indexes = Enum.map(conn.assigns.token_transfers, & &1.log_index) + {:ok, %{"items" => items}} = conn.resp_body |> Poison.decode() - refute Enum.any?(actual_log_indexes, fn log_index -> log_index == token_transfer.log_index end) + refute Enum.count(items) == 3 end - test "next_page_params exist if not on last page", %{conn: conn} do + test "next_page_path exists if not on last page", %{conn: conn} do transaction = :transaction |> insert() @@ -114,12 +110,15 @@ defmodule BlockScoutWeb.TransactionTokenTransferControllerTest do ) end) - conn = get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, transaction.hash)) + conn = + get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, transaction.hash), %{type: "JSON"}) - assert Enum.any?(conn.assigns.next_page_params) + {:ok, %{"next_page_path" => path}} = conn.resp_body |> Poison.decode() + + assert path end - test "next_page_params are empty if on last page", %{conn: conn} do + test "next_page_path is empty if on last page", %{conn: conn} do transaction = :transaction |> insert() @@ -134,9 +133,12 @@ defmodule BlockScoutWeb.TransactionTokenTransferControllerTest do ) end) - conn = get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, transaction.hash)) + conn = + get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, transaction.hash), %{type: "JSON"}) + + {:ok, %{"next_page_path" => path}} = conn.resp_body |> Poison.decode() - assert is_nil(conn.assigns.next_page_params) + refute path end test "preloads to_address smart contract verified", %{conn: conn} do diff --git a/apps/explorer/lib/explorer/chain/token_transfer.ex b/apps/explorer/lib/explorer/chain/token_transfer.ex index 6dd5a547d7..fa7ba99347 100644 --- a/apps/explorer/lib/explorer/chain/token_transfer.ex +++ b/apps/explorer/lib/explorer/chain/token_transfer.ex @@ -175,7 +175,7 @@ defmodule Explorer.Chain.TokenTransfer do from( tt in TokenTransfer, where: tt.to_address_hash == ^address_hash, - select: tt.transaction_hash + select: type(tt.transaction_hash, :binary) ) query @@ -189,7 +189,7 @@ defmodule Explorer.Chain.TokenTransfer do from( tt in TokenTransfer, where: tt.from_address_hash == ^address_hash, - select: tt.transaction_hash + select: type(tt.transaction_hash, :binary) ) query diff --git a/apps/explorer/test/explorer/chain/token_transfer_test.exs b/apps/explorer/test/explorer/chain/token_transfer_test.exs index 35741b78b9..5d9608e66b 100644 --- a/apps/explorer/test/explorer/chain/token_transfer_test.exs +++ b/apps/explorer/test/explorer/chain/token_transfer_test.exs @@ -247,9 +247,11 @@ defmodule Explorer.Chain.TokenTransferTest do amount: 1 ) + {:ok, transaction_bytes} = Explorer.Chain.Hash.Full.dump(transaction.hash) + transactions_hashes = TokenTransfer.where_any_address_fields_match(:to, paul.hash, %PagingOptions{page_size: 1}) - assert Enum.member?(transactions_hashes, transaction.hash) == true + assert Enum.member?(transactions_hashes, transaction_bytes) == true end test "when from_address_hash match returns transactions hashes list" do @@ -283,9 +285,11 @@ defmodule Explorer.Chain.TokenTransferTest do amount: 1 ) + {:ok, transaction_bytes} = Explorer.Chain.Hash.Full.dump(transaction.hash) + transactions_hashes = TokenTransfer.where_any_address_fields_match(:from, john.hash, %PagingOptions{page_size: 1}) - assert Enum.member?(transactions_hashes, transaction.hash) == true + assert Enum.member?(transactions_hashes, transaction_bytes) == true end test "when to_from_address_hash or from_address_hash match returns transactions hashes list" do