Merge pull request #3354 from poanetwork/vb-coin-balance-history-tx

Tx hash in EOA coin balance history
master-before-merging-stake
Victor Baranov 4 years ago committed by GitHub
commit 30109ca4bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 11
      apps/block_scout_web/lib/block_scout_web/templates/address_coin_balance/_coin_balances.html.eex
  3. 14
      apps/explorer/lib/explorer/chain.ex
  4. 38
      apps/explorer/lib/explorer/chain/address/coin_balance.ex

@ -1,6 +1,7 @@
## Current
### Features
- [#3354](https://github.com/poanetwork/blockscout/pull/3354) - Tx hash in EOA coin balance history
- [#3333](https://github.com/poanetwork/blockscout/pull/3333), [#3337](https://github.com/poanetwork/blockscout/pull/3337) - Dark forest contract custom theme
- [#3330](https://github.com/poanetwork/blockscout/pull/3330) - Caching of address transactions counter, remove query 10_000 rows limit

@ -1,15 +1,22 @@
<div class="tile tile-type-coin-balance fade-up" data-test="coin_balance" data-block-number="<%= to_string(@coin_balance.block_number) %>">
<div class="row justify-content align-items-center">
<div class="col-md-3 d-flex flex-column mt-3 mt-md-0">
<div class="col-md-6 d-flex flex-column mt-3 mt-md-0">
<%= link(
to: block_path(@conn, :show, @coin_balance.block_number),
class: "tile-title-lg"
) do %>
<%= gettext "Block" %> <%= @coin_balance.block_number %>
<% end %>
<%= if @coin_balance.transaction_hash do %>
<%= link(
to: transaction_path(@conn, :show, @coin_balance.transaction_hash)
) do %>
<%= @coin_balance.transaction_hash %>
<% end %>
<% end %>
<span data-from-now="<%= @coin_balance.block_timestamp %>"></span>
</div>
<div class="col-md-3 offset-md-3 d-flex flex-column text-md-right mt-3 mt-md-0">
<div class="col-md-3 d-flex flex-column text-md-right mt-3 mt-md-0">
<span class="tile-title-lg align-bottom" data-balance-change-sign="<%= delta_sign(@coin_balance.delta) %>">
<%= delta_arrow(@coin_balance.delta) %>
<%= format_delta(@coin_balance.delta) %>

@ -4338,13 +4338,25 @@ defmodule Explorer.Chain do
end
end
defp fetch_coin_balances(address_hash, paging_options) do
address = Repo.get_by(Address, hash: address_hash)
if contract?(address) do
address_hash
|> CoinBalance.fetch_coin_balances(paging_options)
else
address_hash
|> CoinBalance.fetch_coin_balances_with_txs(paging_options)
end
end
@spec address_to_coin_balances(Hash.Address.t(), [paging_options]) :: []
def address_to_coin_balances(address_hash, options) do
paging_options = Keyword.get(options, :paging_options, @default_paging_options)
balances_raw =
address_hash
|> CoinBalance.fetch_coin_balances(paging_options)
|> fetch_coin_balances(paging_options)
|> page_coin_balances(paging_options)
|> Repo.all()

@ -7,7 +7,7 @@ defmodule Explorer.Chain.Address.CoinBalance do
use Explorer.Schema
alias Explorer.PagingOptions
alias Explorer.Chain.{Address, Block, Hash, Wei}
alias Explorer.Chain.{Address, Block, Hash, Transaction, Wei}
alias Explorer.Chain.Address.CoinBalance
@optional_fields ~w(value value_fetched_at)a
@ -42,6 +42,8 @@ defmodule Explorer.Chain.Address.CoinBalance do
field(:value, Wei)
field(:value_fetched_at, :utc_datetime_usec)
field(:delta, Wei, virtual: true)
field(:transaction_hash, Hash.Full, virtual: true)
field(:transaction_value, Wei, virtual: true)
field(:block_timestamp, :utc_datetime_usec, virtual: true)
timestamps()
@ -78,14 +80,22 @@ defmodule Explorer.Chain.Address.CoinBalance do
The last coin balance from an Address is the last block indexed.
"""
def fetch_coin_balances(address_hash, %PagingOptions{page_size: page_size}) do
def fetch_coin_balances_with_txs(address_hash, %PagingOptions{page_size: page_size}) do
query =
from(
cb in CoinBalance,
left_join: tx in Transaction,
on:
cb.block_number == tx.block_number and tx.value > ^0 and
(cb.address_hash == tx.to_address_hash or cb.address_hash == tx.from_address_hash),
where: cb.address_hash == ^address_hash,
where: not is_nil(cb.value),
order_by: [desc: :block_number],
select_merge: %{delta: fragment("value - coalesce(lead(value, 1) over (order by block_number desc), 0)")}
select_merge: %{
delta: fragment("a0.value - coalesce(lead(a0.value, 1) over (order by a0.block_number desc), 0)"),
transaction_hash: tx.hash,
transaction_value: tx.value
}
)
from(balance in subquery(query),
@ -94,6 +104,28 @@ defmodule Explorer.Chain.Address.CoinBalance do
)
end
def fetch_coin_balances(address_hash, %PagingOptions{page_size: page_size}) do
query =
from(
cb in CoinBalance,
where: cb.address_hash == ^address_hash,
where: not is_nil(cb.value),
order_by: [desc: :block_number],
select_merge: %{
delta: fragment("a0.value - coalesce(lead(a0.value, 1) over (order by a0.block_number desc), 0)")
}
)
from(balance in subquery(query),
where: balance.delta != 0,
limit: ^page_size,
select_merge: %{
transaction_hash: nil,
transaction_value: nil
}
)
end
@doc """
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.

Loading…
Cancel
Save