Merge pull request #2237 from poanetwork/ab-fix-rsk-total-supply

fix rsk total_supply
pull/2290/head
Victor Baranov 5 years ago committed by GitHub
commit 9f7816848b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 2
      apps/block_scout_web/assets/js/pages/chain.js
  3. 12
      apps/explorer/lib/explorer/application.ex
  4. 92
      apps/explorer/lib/explorer/chain/supply/rsk.ex
  5. 82
      apps/explorer/test/explorer/chain/supply/rsk_test.exs

@ -61,6 +61,7 @@
- [#2173](https://github.com/poanetwork/blockscout/pull/2173) - handle correctly empty transactions
- [#2174](https://github.com/poanetwork/blockscout/pull/2174) - fix reward channel joining
- [#2186](https://github.com/poanetwork/blockscout/pull/2186) - fix net version test
- [#2237](https://github.com/poanetwork/blockscout/pull/2237) - fix rsk total_supply
- [#2198](https://github.com/poanetwork/blockscout/pull/2198) - reduce transaction status and error constraint
- [#2167](https://github.com/poanetwork/blockscout/pull/2167) - feat: document eth rpc api mimicking endpoints
- [#2225](https://github.com/poanetwork/blockscout/pull/2225) - fix metadata decoding in Solidity 0.5.9 smart contract verification

@ -142,7 +142,7 @@ const elements = {
chart = createMarketHistoryChart($el[0])
},
render ($el, state, oldState) {
if (!chart || (oldState.availableSupply === state.availableSupply && oldState.marketHistoryData === state.marketHistoryData)) return
if (!chart || (oldState.availableSupply === state.availableSupply && oldState.marketHistoryData === state.marketHistoryData) || !state.availableSupply) return
chart.update(state.availableSupply, state.marketHistoryData)
}
},

@ -16,6 +16,8 @@ defmodule Explorer.Application do
TransactionsCache
}
alias Explorer.Chain.Supply.RSK
alias Explorer.Market.MarketHistoryCache
alias Explorer.Repo.PrometheusLogger
@ -44,6 +46,7 @@ defmodule Explorer.Application do
con_cache_child_spec(BlocksCache.cache_name()),
con_cache_child_spec(NetVersionCache.cache_name()),
con_cache_child_spec(MarketHistoryCache.cache_name()),
con_cache_child_spec(RSK.cache_name(), ttl_check_interval: :timer.minutes(1), global_ttl: :timer.minutes(30)),
con_cache_child_spec(TransactionsCache.cache_name())
]
@ -93,14 +96,13 @@ defmodule Explorer.Application do
]
end
defp con_cache_child_spec(name) do
defp con_cache_child_spec(name, params \\ [ttl_check_interval: false]) do
params = Keyword.put(params, :name, name)
Supervisor.child_spec(
{
ConCache,
[
name: name,
ttl_check_interval: false
]
params
},
id: {ConCache, name}
)

@ -6,14 +6,20 @@ defmodule Explorer.Chain.Supply.RSK do
use Explorer.Chain.Supply
import Ecto.Query, only: [from: 2]
import EthereumJSONRPC, only: [integer_to_quantity: 1]
alias EthereumJSONRPC.FetchedBalances
alias Explorer.Chain.Address.CoinBalance
alias Explorer.Chain.{Block, Wei}
alias Explorer.ExchangeRates.Token
alias Explorer.{Market, Repo}
alias Explorer.Chain.{Block, BlockNumberCache, Wei}
alias Explorer.Repo
@cache_name :rsk_balance
@balance_key :balance
def market_cap(exchange_rate) do
circulating() * exchange_rate.usd_value
btc = circulating()
Decimal.mult(btc, exchange_rate.usd_value)
end
@doc "Equivalent to getting the circulating value "
@ -60,13 +66,16 @@ defmodule Explorer.Chain.Supply.RSK do
|> Timex.shift(days: i)
|> Timex.to_date()
case Map.get(by_day, date) do
nil ->
{Map.put(days, date, last), last}
cur_value =
case Map.get(by_day, date) do
nil ->
last
value ->
value.value
end
value ->
{Map.put(days, date, value.value), value.value}
end
{Map.put(days, date, calculate_value(cur_value)), cur_value}
end)
|> elem(0)
@ -74,18 +83,48 @@ defmodule Explorer.Chain.Supply.RSK do
end
def circulating do
query =
from(balance in CoinBalance,
join: block in Block,
on: block.number == balance.block_number,
where: block.consensus == true,
where: balance.address_hash == ^"0x0000000000000000000000000000000001000006",
order_by: [desc: block.timestamp],
limit: 1,
select: balance.value
)
value = ConCache.get(@cache_name, @balance_key)
if is_nil(value) do
updated_value = fetch_circulating_value()
Repo.one(query) || wei!(0)
ConCache.put(@cache_name, @balance_key, updated_value)
updated_value
else
value
end
end
def cache_name, do: @cache_name
defp fetch_circulating_value do
max_number = BlockNumberCache.max_number()
params = [
%{block_quantity: integer_to_quantity(max_number), hash_data: "0x0000000000000000000000000000000001000006"}
]
json_rpc_named_argumens = Application.get_env(:explorer, :json_rpc_named_arguments)
case EthereumJSONRPC.fetch_balances(params, json_rpc_named_argumens) do
{:ok,
%FetchedBalances{
errors: [],
params_list: [
%{
address_hash: "0x0000000000000000000000000000000001000006",
value: value
}
]
}} ->
calculate_value(value)
_ ->
Decimal.new(0)
end
rescue
_ -> Decimal.new(0)
end
defp wei!(value) do
@ -94,10 +133,15 @@ defmodule Explorer.Chain.Supply.RSK do
end
def total do
21_000_000
Decimal.new(21_000_000)
end
def exchange_rate do
Market.get_exchange_rate(Explorer.coin()) || Token.null()
defp calculate_value(val) do
sub =
val
|> Decimal.new()
|> Decimal.div(Decimal.new(1_000_000_000_000_000_000))
Decimal.sub(total(), sub)
end
end

@ -1,32 +1,30 @@
defmodule Explorer.Chain.Supply.RSKTest do
use Explorer.DataCase
import Mox
alias Explorer.Chain.Supply.RSK
alias Explorer.Chain.Wei
alias Explorer.ExchangeRates.Token
@coin_address "0x0000000000000000000000000000000001000006"
defp wei!(value) do
{:ok, wei} = Wei.cast(value)
wei
end
@mult 1_000_000_000_000_000_000
test "total is 21_000_000" do
assert RSK.total() == 21_000_000
assert Decimal.equal?(RSK.total(), Decimal.new(21_000_000))
end
describe "circulating/0" do
test "with no balance" do
assert RSK.circulating() == wei!(0)
end
test "with a balance" do
address = insert(:address, hash: @coin_address)
insert(:block, number: 0)
describe "market_cap/1" do
@tag :no_parity
@tag :no_geth
test "calculates market_cap" do
EthereumJSONRPC.Mox
|> expect(:json_rpc, fn [%{id: id, method: "eth_getBalance"}], _options ->
{:ok, [%{id: id, result: "20999999999900000000000000"}]}
end)
insert(:fetched_balance, value: 10, address_hash: address.hash, block_number: 0)
exchange_rate = %{Token.null() | usd_value: Decimal.new(1_000_000)}
assert RSK.circulating() == wei!(10)
assert Decimal.equal?(RSK.market_cap(exchange_rate), Decimal.new(100.0000))
end
end
@ -47,9 +45,9 @@ defmodule Explorer.Chain.Supply.RSKTest do
assert RSK.supply_for_days(2) ==
{:ok,
%{
date(now, days: -2) => dec(0),
date(now, days: -1) => dec(0),
date(now) => dec(0)
date(now, days: -2) => dec(21_000_000),
date(now, days: -1) => dec(21_000_000),
date(now) => dec(21_000_000)
}}
end
@ -59,14 +57,14 @@ defmodule Explorer.Chain.Supply.RSKTest do
insert(:block, number: 0, timestamp: Timex.shift(now, days: -10))
insert(:fetched_balance, value: 10, address_hash: address.hash, block_number: 0)
insert(:fetched_balance, value: 10 * @mult, address_hash: address.hash, block_number: 0)
assert RSK.supply_for_days(2) ==
{:ok,
%{
date(now, days: -2) => dec(10),
date(now, days: -1) => dec(10),
date(now) => dec(10)
date(now, days: -2) => dec(20_999_990),
date(now, days: -1) => dec(20_999_990),
date(now) => dec(20_999_990)
}}
end
@ -77,16 +75,16 @@ defmodule Explorer.Chain.Supply.RSKTest do
insert(:block, number: 0, timestamp: Timex.shift(now, days: -10))
insert(:block, number: 1, timestamp: Timex.shift(now, days: -1))
insert(:fetched_balance, value: 10, address_hash: address.hash, block_number: 0)
insert(:fetched_balance, value: 10 * @mult, address_hash: address.hash, block_number: 0)
insert(:fetched_balance, value: 20, address_hash: address.hash, block_number: 1)
insert(:fetched_balance, value: 20 * @mult, address_hash: address.hash, block_number: 1)
assert RSK.supply_for_days(2) ==
{:ok,
%{
date(now, days: -2) => dec(10),
date(now, days: -1) => dec(20),
date(now) => dec(20)
date(now, days: -2) => dec(20_999_990),
date(now, days: -1) => dec(20_999_980),
date(now) => dec(20_999_980)
}}
end
@ -98,18 +96,18 @@ defmodule Explorer.Chain.Supply.RSKTest do
insert(:block, number: 1, timestamp: Timex.shift(now, days: -2))
insert(:block, number: 2, timestamp: Timex.shift(now, days: -1))
insert(:fetched_balance, value: 5, address_hash: address.hash, block_number: 0)
insert(:fetched_balance, value: 5 * @mult, address_hash: address.hash, block_number: 0)
insert(:fetched_balance, value: 10, address_hash: address.hash, block_number: 1)
insert(:fetched_balance, value: 10 * @mult, address_hash: address.hash, block_number: 1)
insert(:fetched_balance, value: 20, address_hash: address.hash, block_number: 2)
insert(:fetched_balance, value: 20 * @mult, address_hash: address.hash, block_number: 2)
assert RSK.supply_for_days(2) ==
{:ok,
%{
date(now, days: -2) => dec(10),
date(now, days: -1) => dec(20),
date(now) => dec(20)
date(now, days: -2) => dec(20_999_990),
date(now, days: -1) => dec(20_999_980),
date(now) => dec(20_999_980)
}}
end
@ -122,17 +120,17 @@ defmodule Explorer.Chain.Supply.RSKTest do
insert(:block, number: 2, timestamp: Timex.shift(now, days: -1))
insert(:block, number: 3, timestamp: now)
insert(:fetched_balance, value: 5, address_hash: address.hash, block_number: 0)
insert(:fetched_balance, value: 10, address_hash: address.hash, block_number: 1)
insert(:fetched_balance, value: 20, address_hash: address.hash, block_number: 2)
insert(:fetched_balance, value: 30, address_hash: address.hash, block_number: 3)
insert(:fetched_balance, value: 5 * @mult, address_hash: address.hash, block_number: 0)
insert(:fetched_balance, value: 10 * @mult, address_hash: address.hash, block_number: 1)
insert(:fetched_balance, value: 20 * @mult, address_hash: address.hash, block_number: 2)
insert(:fetched_balance, value: 30 * @mult, address_hash: address.hash, block_number: 3)
assert RSK.supply_for_days(2) ==
{:ok,
%{
date(now, days: -2) => dec(10),
date(now, days: -1) => dec(20),
date(now) => dec(30)
date(now, days: -2) => dec(20_999_990),
date(now, days: -1) => dec(20_999_980),
date(now) => dec(20_999_970)
}}
end
end

Loading…
Cancel
Save