fetch last not empty coin balance records

pull/2538/head
Ayrat Badykov 5 years ago
parent 994ac77837
commit 6fb93c0cdf
No known key found for this signature in database
GPG Key ID: B44668E265E9396F
  1. 4
      apps/explorer/lib/explorer/chain.ex
  2. 4
      apps/explorer/lib/explorer/chain/address/coin_balance.ex
  3. 28
      apps/explorer/test/explorer/chain/address/coin_balance_test.exs

@ -66,6 +66,8 @@ defmodule Explorer.Chain do
@max_incoming_transactions_count 10_000 @max_incoming_transactions_count 10_000
@coin_balance_records_count 90
@typedoc """ @typedoc """
The name of an association on the `t:Ecto.Schema.t/0` 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] @spec address_to_balances_by_day(Hash.Address.t()) :: [balance_by_day]
def address_to_balances_by_day(address_hash) do def address_to_balances_by_day(address_hash) do
address_hash address_hash
|> CoinBalance.balances_by_day() |> CoinBalance.balances_by_day(@coin_balance_records_count)
|> Repo.all() |> Repo.all()
|> normalize_balances_by_day() |> normalize_balances_by_day()
end end

@ -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 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. 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 CoinBalance
|> join(:inner, [cb], b in Block, on: cb.block_number == b.number) |> join(:inner, [cb], b in Block, on: cb.block_number == b.number)
|> where([cb], cb.address_hash == ^address_hash) |> 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)) |> group_by([cb, b], fragment("date_trunc('day', ?)", b.timestamp))
|> order_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)}) |> select([cb, b], %{date: type(fragment("date_trunc('day', ?)", b.timestamp), :date), value: max(cb.value)})
|> limit(^number)
end end
def changeset(%__MODULE__{} = balance, params) do def changeset(%__MODULE__{} = balance, params) do

@ -2,8 +2,8 @@ defmodule Explorer.Chain.Address.CoinBalanceTest do
use Explorer.DataCase use Explorer.DataCase
alias Ecto.Changeset alias Ecto.Changeset
alias Explorer.Chain.{Block, Wei}
alias Explorer.Chain.Address.CoinBalance alias Explorer.Chain.Address.CoinBalance
alias Explorer.Chain.{Block, Wei}
alias Explorer.PagingOptions alias Explorer.PagingOptions
describe "changeset/2" do describe "changeset/2" do
@ -225,7 +225,7 @@ defmodule Explorer.Chain.Address.CoinBalanceTest do
assert(length(result) == 1) 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)) assert(value == Wei.from(Decimal.new(3000), :wei))
end end
@ -247,7 +247,7 @@ defmodule Explorer.Chain.Address.CoinBalanceTest do
assert(length(result) == 1) 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)) assert(value == Wei.from(Decimal.new(3000), :wei))
end end
@ -269,9 +269,29 @@ defmodule Explorer.Chain.Address.CoinBalanceTest do
assert(length(result) == 1) 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)) assert(value == Wei.from(Decimal.new(3000), :wei))
end 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
end end

Loading…
Cancel
Save