From 6fb93c0cdf252090466346d7bf6d8fe8383dda8e Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Fri, 9 Aug 2019 13:34:30 +0300 Subject: [PATCH] fetch last not empty coin balance records --- apps/explorer/lib/explorer/chain.ex | 4 ++- .../explorer/chain/address/coin_balance.ex | 4 +-- .../chain/address/coin_balance_test.exs | 28 ++++++++++++++++--- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index e6ffcbd9c5..aa1ab8aae1 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -66,6 +66,8 @@ defmodule Explorer.Chain do @max_incoming_transactions_count 10_000 + @coin_balance_records_count 90 + @typedoc """ The name of an association on the `t:Ecto.Schema.t/0` """ @@ -2976,7 +2978,7 @@ defmodule Explorer.Chain do @spec address_to_balances_by_day(Hash.Address.t()) :: [balance_by_day] def address_to_balances_by_day(address_hash) do address_hash - |> CoinBalance.balances_by_day() + |> CoinBalance.balances_by_day(@coin_balance_records_count) |> Repo.all() |> normalize_balances_by_day() end diff --git a/apps/explorer/lib/explorer/chain/address/coin_balance.ex b/apps/explorer/lib/explorer/chain/address/coin_balance.ex index af12491247..6402b31b80 100644 --- a/apps/explorer/lib/explorer/chain/address/coin_balance.ex +++ b/apps/explorer/lib/explorer/chain/address/coin_balance.ex @@ -89,14 +89,14 @@ defmodule Explorer.Chain.Address.CoinBalance do Builds an `Ecto.Query` to fetch a series of balances by day for the given account. Each element in the series corresponds to the maximum balance in that day. Only the last 90 days of data are used. """ - def balances_by_day(address_hash) do + def balances_by_day(address_hash, number \\ 60) do CoinBalance |> join(:inner, [cb], b in Block, on: cb.block_number == b.number) |> where([cb], cb.address_hash == ^address_hash) - |> where([cb, b], b.timestamp >= fragment("date_trunc('day', now()) - interval '90 days'")) |> group_by([cb, b], fragment("date_trunc('day', ?)", b.timestamp)) |> order_by([cb, b], fragment("date_trunc('day', ?)", b.timestamp)) |> select([cb, b], %{date: type(fragment("date_trunc('day', ?)", b.timestamp), :date), value: max(cb.value)}) + |> limit(^number) end def changeset(%__MODULE__{} = balance, params) do diff --git a/apps/explorer/test/explorer/chain/address/coin_balance_test.exs b/apps/explorer/test/explorer/chain/address/coin_balance_test.exs index 87ed80a94c..a5ce968b39 100644 --- a/apps/explorer/test/explorer/chain/address/coin_balance_test.exs +++ b/apps/explorer/test/explorer/chain/address/coin_balance_test.exs @@ -2,8 +2,8 @@ defmodule Explorer.Chain.Address.CoinBalanceTest do use Explorer.DataCase alias Ecto.Changeset - alias Explorer.Chain.{Block, Wei} alias Explorer.Chain.Address.CoinBalance + alias Explorer.Chain.{Block, Wei} alias Explorer.PagingOptions describe "changeset/2" do @@ -225,7 +225,7 @@ defmodule Explorer.Chain.Address.CoinBalanceTest do assert(length(result) == 1) - value = List.first(result) |> Map.get(:value) + value = result |> List.first() |> Map.get(:value) assert(value == Wei.from(Decimal.new(3000), :wei)) end @@ -247,7 +247,7 @@ defmodule Explorer.Chain.Address.CoinBalanceTest do assert(length(result) == 1) - value = List.first(result) |> Map.get(:value) + value = result |> List.first() |> Map.get(:value) assert(value == Wei.from(Decimal.new(3000), :wei)) end @@ -269,9 +269,29 @@ defmodule Explorer.Chain.Address.CoinBalanceTest do assert(length(result) == 1) - value = List.first(result) |> Map.get(:value) + value = result |> List.first() |> Map.get(:value) assert(value == Wei.from(Decimal.new(3000), :wei)) end + + test "fetches old records" do + address = insert(:address) + noon = Timex.now() |> Timex.beginning_of_day() |> Timex.set(hour: 12) + block = insert(:block, timestamp: noon) + old_block = insert(:block, timestamp: Timex.shift(noon, days: -700)) + insert(:fetched_balance, address_hash: address.hash, value: 1000, block_number: block.number) + insert(:fetched_balance, address_hash: address.hash, value: 2000, block_number: old_block.number) + + result = + address.hash + |> CoinBalance.balances_by_day() + |> Repo.all() + + assert(length(result) == 2) + + value = result |> List.first() |> Map.get(:value) + + assert(value == Wei.from(Decimal.new(2000), :wei)) + end end end