feat: address transactions block number sorting (#11035)

* feat: address transactions block number sorting

* Add index ordering

Co-Authored-By: Kirill Fedoseev <kirill@blockscout.com>

---------

Co-authored-by: Kirill Fedoseev <kirill@blockscout.com>
pull/11057/head
Maxim Filonov 4 weeks ago committed by GitHub
parent b8768fdbcc
commit b2cc4669d6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      apps/block_scout_web/lib/block_scout_web/paging_helper.ex
  2. 77
      apps/block_scout_web/test/block_scout_web/controllers/api/v2/address_controller_test.exs
  3. 12
      apps/explorer/lib/explorer/chain/transaction.ex

@ -287,6 +287,8 @@ defmodule BlockScoutWeb.PagingHelper do
def address_transactions_sorting(_), do: []
defp do_address_transaction_sorting("block_number", "asc"), do: [asc: :block_number, asc: :index]
defp do_address_transaction_sorting("block_number", "desc"), do: [desc: :block_number, desc: :index]
defp do_address_transaction_sorting("value", "asc"), do: [asc: :value]
defp do_address_transaction_sorting("value", "desc"), do: [desc: :value]
defp do_address_transaction_sorting("fee", "asc"), do: [{:dynamic, :fee, :asc_nulls_first, Transaction.dynamic_fee()}]

@ -6,7 +6,6 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
alias ABI.{TypeDecoder, TypeEncoder}
alias Explorer.{Chain, Repo, TestHelper}
alias Explorer.Chain.Address.Counters
alias Explorer.Chain.Events.Subscriber
alias Explorer.Chain.{
Address,
@ -823,6 +822,82 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
check_paginated_response(response, response_2nd_page, transactions |> Enum.reverse())
end
test "can order and paginate by block number ascending", %{conn: conn} do
address = insert(:address)
transactions_from =
for _ <- 0..24, do: insert(:transaction, from_address: address) |> with_block()
transactions_to = for _ <- 0..25, do: insert(:transaction, to_address: address) |> with_block()
transactions =
(transactions_from ++ transactions_to)
|> Enum.sort_by(& &1.block.number)
request =
get(conn, "/api/v2/addresses/#{address.hash}/transactions", %{"sort" => "block_number", "order" => "asc"})
assert response = json_response(request, 200)
request_2nd_page =
get(
conn,
"/api/v2/addresses/#{address.hash}/transactions",
%{"sort" => "block_number", "order" => "asc"} |> Map.merge(response["next_page_params"])
)
assert response_2nd_page = json_response(request_2nd_page, 200)
assert Enum.count(response["items"]) == 50
assert response["next_page_params"] != nil
compare_item(Enum.at(transactions, 0), Enum.at(response["items"], 0))
compare_item(Enum.at(transactions, 49), Enum.at(response["items"], 49))
assert Enum.count(response_2nd_page["items"]) == 1
assert response_2nd_page["next_page_params"] == nil
compare_item(Enum.at(transactions, 50), Enum.at(response_2nd_page["items"], 0))
check_paginated_response(response, response_2nd_page, transactions |> Enum.reverse())
end
test "can order and paginate by block number descending", %{conn: conn} do
address = insert(:address)
transactions_from =
for _ <- 0..24, do: insert(:transaction, from_address: address) |> with_block()
transactions_to = for _ <- 0..25, do: insert(:transaction, to_address: address) |> with_block()
transactions =
(transactions_from ++ transactions_to)
|> Enum.sort_by(& &1.block.number, :desc)
request =
get(conn, "/api/v2/addresses/#{address.hash}/transactions", %{"sort" => "block_number", "order" => "desc"})
assert response = json_response(request, 200)
request_2nd_page =
get(
conn,
"/api/v2/addresses/#{address.hash}/transactions",
%{"sort" => "block_number", "order" => "desc"} |> Map.merge(response["next_page_params"])
)
assert response_2nd_page = json_response(request_2nd_page, 200)
assert Enum.count(response["items"]) == 50
assert response["next_page_params"] != nil
compare_item(Enum.at(transactions, 0), Enum.at(response["items"], 0))
compare_item(Enum.at(transactions, 49), Enum.at(response["items"], 49))
assert Enum.count(response_2nd_page["items"]) == 1
assert response_2nd_page["next_page_params"] == nil
compare_item(Enum.at(transactions, 50), Enum.at(response_2nd_page["items"], 0))
check_paginated_response(response, response_2nd_page, transactions |> Enum.reverse())
end
end
describe "/addresses/{address_hash}/token-transfers" do

@ -1581,6 +1581,18 @@ defmodule Explorer.Chain.Transaction do
end
end
defp compare_custom_sorting([{block_order, :block_number}, {index_order, :index}]) do
fn a, b ->
case {Helper.compare(a.block_number, b.block_number), Helper.compare(a.index, b.index)} do
{:eq, :eq} -> compare_default_sorting(a, b)
{:eq, :gt} -> index_order == :desc
{:eq, :lt} -> index_order == :asc
{:gt, _} -> block_order == :desc
{:lt, _} -> block_order == :asc
end
end
end
defp compare_custom_sorting([{:dynamic, :fee, order, _dynamic_fee}]) do
fn a, b ->
nil_case =

Loading…
Cancel
Save