Skip to content

Commit

Permalink
feat: add total accounts total stats
Browse files Browse the repository at this point in the history
  • Loading branch information
vatanasov committed Dec 20, 2024
1 parent 07b50b7 commit df4c8b3
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 27 deletions.
7 changes: 5 additions & 2 deletions lib/ae_mdw/accounts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ defmodule AeMdw.Accounts do

require Model

@spec maybe_increase_creation_statistics(State.t(), Db.pubkey(), Blocks.time()) :: State.t()
def maybe_increase_creation_statistics(state, pubkey, time) do
@spec maybe_increase_creation_statistics(State.t(), Db.pubkey(), Blocks.time(), Blocks.height()) ::
State.t()
def maybe_increase_creation_statistics(state, pubkey, time, height) do
state
|> State.get(Model.AccountCreation, pubkey)
|> case do
Expand All @@ -23,6 +24,8 @@ defmodule AeMdw.Accounts do
Model.account_creation(index: pubkey, creation_time: time)
)
|> SyncStats.increment_statistics(:total_accounts, time, 1)
|> SyncStats.increment_height_statistics(:total_accounts, height, 1)
|> State.inc_stat(:total_accounts)

_account_creation ->
state
Expand Down
6 changes: 4 additions & 2 deletions lib/ae_mdw/db/model.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1206,7 +1206,8 @@ defmodule AeMdw.Db.Model do
burned_in_auctions: 0,
channels_opened: 0,
channels_closed: 0,
locked_in_channels: 0
locked_in_channels: 0,
total_accounts: 0
]
defrecord :delta_stat, @delta_stat_defaults

Expand All @@ -1227,7 +1228,8 @@ defmodule AeMdw.Db.Model do
burned_in_auctions: integer(),
channels_opened: non_neg_integer(),
channels_closed: non_neg_integer(),
locked_in_channels: integer()
locked_in_channels: integer(),
total_accounts: non_neg_integer()
)

# summarized statistics
Expand Down
16 changes: 9 additions & 7 deletions lib/ae_mdw/db/mutations/account_creation_mutation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,28 @@ defmodule AeMdw.Db.AccountCreationMutation do
alias AeMdw.Node.Db

@derive AeMdw.Db.Mutation
defstruct [:account_pk, :time]
defstruct [:account_pk, :time, :height]

@opaque t() :: %__MODULE__{
account_pk: Db.pubkey(),
time: Blocks.time()
time: Blocks.time(),
height: Blocks.height()
}

@spec new(Db.pubkey(), Blocks.time()) :: t()
def new(account_pk, time) do
%__MODULE__{account_pk: account_pk, time: time}
@spec new(Db.pubkey(), Blocks.time(), Blocks.height()) :: t()
def new(account_pk, time, height) do
%__MODULE__{account_pk: account_pk, time: time, height: height}
end

@spec execute(t(), State.t()) :: State.t()
def execute(
%__MODULE__{
account_pk: account_pk,
time: time
time: time,
height: height
},
state
) do
Accounts.maybe_increase_creation_statistics(state, account_pk, time)
Accounts.maybe_increase_creation_statistics(state, account_pk, time, height)
end
end
12 changes: 10 additions & 2 deletions lib/ae_mdw/db/mutations/stats_mutation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ defmodule AeMdw.Db.StatsMutation do
burned_in_auctions: get(state, :burned_in_auctions, 0),
channels_opened: get(state, :channels_opened, 0),
channels_closed: get(state, :channels_closed, 0),
locked_in_channels: get(state, :locked_in_channels, 0)
locked_in_channels: get(state, :locked_in_channels, 0),
total_accounts: get(state, :total_accounts, 0)
)
end

Expand Down Expand Up @@ -160,6 +161,12 @@ defmodule AeMdw.Db.StatsMutation do
locked_in_auctions = spent_in_auctions - refund_in_auctions
locked_in_channels = height_int_amount(state, height, :lock_channel)

total_accounts =
case State.get(state, Model.Statistic, {:total_accounts, :height, height}) do
{:ok, Model.statistic(count: count)} -> count
:not_found -> 0
end

Model.delta_stat(
index: height,
auctions_started: max(0, current_active_auctions - prev_active_auctions),
Expand All @@ -175,7 +182,8 @@ defmodule AeMdw.Db.StatsMutation do
burned_in_auctions: burned_in_auctions,
channels_opened: channels_opened,
channels_closed: channels_closed,
locked_in_channels: locked_in_channels
locked_in_channels: locked_in_channels,
total_accounts: total_accounts
)
end

Expand Down
20 changes: 20 additions & 0 deletions lib/ae_mdw/db/sync/stats.ex
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,26 @@ defmodule AeMdw.Db.Sync.Stats do
end)
end

@spec increment_height_statistics(
State.t(),
Stats.statistic_tag(),
Blocks.height(),
pos_integer()
) :: State.t()
def increment_height_statistics(state, key, height, increment) do
index = {key, :height, height}

State.update(
state,
Model.Statistic,
index,
fn Model.statistic(count: count) = statistics ->
Model.statistic(statistics, count: count + increment)
end,
Model.statistic(index: index, count: 0)
)
end

defp increment_collection_nfts(state, contract_pk, nil),
do: update_stat_counter(state, Stats.nfts_count_key(contract_pk))

Expand Down
19 changes: 11 additions & 8 deletions lib/ae_mdw/stats.ex
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ defmodule AeMdw.Stats do
| :hashrate
| :contracts
| :total_accounts
@type interval_by() :: :day | :week | :month
@type interval_by() :: :day | :week | :month | :height
@type interval_start() :: non_neg_integer()

@tps_stat_key :max_tps
Expand All @@ -72,7 +72,8 @@ defmodule AeMdw.Stats do
@interval_by_mapping %{
"day" => :day,
"week" => :week,
"month" => :month
"month" => :month,
"height" => :height
}

@spec max_tps_key() :: atom()
Expand Down Expand Up @@ -166,10 +167,6 @@ defmodule AeMdw.Stats do
def fetch_delta_stat!(state, height),
do: render_delta_stat(state, State.fetch!(state, Model.DeltaStat, height))

@spec fetch_total_stat!(State.t(), height()) :: total_stat()
def fetch_total_stat!(state, height),
do: render_total_stat(state, State.fetch!(state, Model.TotalStat, height))

@spec fetch_nft_stats(State.t(), pubkey()) :: nft_stats()
def fetch_nft_stats(state, contract_pk) do
with {:ok, Model.stat(payload: nfts_count)} <-
Expand Down Expand Up @@ -496,6 +493,10 @@ defmodule AeMdw.Stats do

defp render_total_stats(state, gens), do: Enum.map(gens, &fetch_total_stat!(state, &1))

@spec fetch_total_stat!(State.t(), height()) :: total_stat()
defp fetch_total_stat!(state, height),
do: render_total_stat(state, State.fetch!(state, Model.TotalStat, height))

defp render_delta_stat(
state,
Model.delta_stat(
Expand All @@ -513,7 +514,8 @@ defmodule AeMdw.Stats do
burned_in_auctions: burned_in_auctions,
channels_opened: channels_opened,
channels_closed: channels_closed,
locked_in_channels: locked_in_channels
locked_in_channels: locked_in_channels,
total_accounts: total_accounts
)
) do
%{
Expand All @@ -532,7 +534,8 @@ defmodule AeMdw.Stats do
channels_opened: channels_opened,
channels_closed: channels_closed,
locked_in_channels: locked_in_channels,
last_tx_hash: fetch_last_tx_hash!(state, height)
last_tx_hash: fetch_last_tx_hash!(state, height),
total_accounts: total_accounts
}
end

Expand Down
13 changes: 7 additions & 6 deletions lib/ae_mdw/sync/server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ defmodule AeMdw.Sync.Server do
new_state =
gens_mutations
|> Enum.reduce(initial_state, fn {height, blocks_mutations}, state ->
blocks_mutations = maybe_add_accounts_balance_mutations(blocks_mutations)
blocks_mutations = maybe_add_accounts_balance_mutations(blocks_mutations, height)
{ts, new_state} = :timer.tc(fn -> exec_db_height(state, blocks_mutations, clear_mem?) end)

:ok = profile_sync("sync_db", height, ts, blocks_mutations)
Expand All @@ -340,7 +340,7 @@ defmodule AeMdw.Sync.Server do
end)
end

defp maybe_add_accounts_balance_mutations(gen_mutations) do
defp maybe_add_accounts_balance_mutations(gen_mutations, height) do
accounts_set =
Enum.reduce(gen_mutations, MapSet.new(), fn
{{_height, -1}, _block, _mutations}, set ->
Expand All @@ -365,7 +365,7 @@ defmodule AeMdw.Sync.Server do
account_statistics_mutations =
Enum.flat_map(accounts_set, fn pubkey ->
[
{block_index, mblock, AccountCreationMutation.new(pubkey, time)},
{block_index, mblock, AccountCreationMutation.new(pubkey, time, height)},
{block_index, mblock, AccountActivityMutation.new(pubkey, time)}
]
end)
Expand Down Expand Up @@ -409,7 +409,7 @@ defmodule AeMdw.Sync.Server do
# start syncing from memory, then anticipates commit to avoid committing only after 10 gens
if from_height == AeMdw.Db.Util.synced_height(State.mem_state()) do
Enum.reduce(gens_mutations, empty_state, fn {height, gen_mutations}, state ->
gen_mutations = maybe_add_accounts_balance_mutations(gen_mutations)
gen_mutations = maybe_add_accounts_balance_mutations(gen_mutations, height)

{ts, commited_state} =
:timer.tc(fn ->
Expand All @@ -433,8 +433,9 @@ defmodule AeMdw.Sync.Server do
defp exec_all_mem_mutations(state, gens_mutations) do
blocks_mutations =
gens_mutations
|> Enum.flat_map(fn {_height, blocks_mutations} -> blocks_mutations end)
|> maybe_add_accounts_balance_mutations()
|> Enum.flat_map(fn {height, blocks_mutations} ->
maybe_add_accounts_balance_mutations(blocks_mutations, height)
end)

{{height, _mbi}, _block, _mutations} = List.last(blocks_mutations)
Log.info("[sync_mem] exec until height=#{height}")
Expand Down
91 changes: 91 additions & 0 deletions test/integration/ae_mdw_web/controllers/stats_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ defmodule Integration.AeMdwWeb.StatsControllerTest do
alias AeMdw.Db.Model
alias AeMdw.Db.State
alias AeMdw.Db.Util
alias AeMdw.IntegrationUtil

@moduletag :integration

Expand Down Expand Up @@ -285,4 +286,94 @@ defmodule Integration.AeMdwWeb.StatsControllerTest do
)
end
end

describe "stats" do
test "it returns stats", %{conn: conn} do
assert %{
"miners_count" => _miners_count,
"fees_trend" => _fees_trend,
"last_24hs_average_transaction_fees" => _last_24hs_average_transaction_fees,
"last_24hs_transactions" => _last_24hs_transactions,
"max_transactions_per_second" => _max_transactions_per_second,
"max_transactions_per_second_block_hash" =>
_max_transactions_per_second_block_hash,
"milliseconds_per_block" => _milliseconds_per_block,
"transactions_trend" => _transactions_trend
} =
conn
|> get("/v3/stats")
|> json_response(200)
end
end

describe "miners_stats" do
test "it returns miners stats", %{conn: conn} do
assert %{
"data" => [
%{
"miner" => _miner,
"total_reward" => _total_reward
}
| _rest_of_data
]
} =
conn
|> get("/v3/stats/miners")
|> json_response(200)
end

test "pagination works", %{conn: conn} do
IntegrationUtil.test_pagination(conn, %IntegrationUtil.PaginationParams{
url: "/v3/stats/miners"
})
end
end

describe "transaction_stats" do
test "it returns transaction stats", %{conn: conn} do
assert %{
"data" => [
%{
"count" => _count,
"end_date" => _end_date,
"start_date" => _start_date
}
| _rest_of_data
]
} =
conn
|> get("/v3/stats/transactions")
|> json_response(200)
end

test "pagination works", %{conn: conn} do
IntegrationUtil.test_pagination(conn, %IntegrationUtil.PaginationParams{
url: "/v3/stats/transactions"
})
end
end

describe "blocks_stats" do
test "it returns blocks stats", %{conn: conn} do
assert %{
"data" => [
%{
"count" => _count,
"end_date" => _end_date,
"start_date" => _start_date
}
| _rest_of_data
]
} =
conn
|> get("/v3/stats/blocks")
|> json_response(200)
end

test "pagination works", %{conn: conn} do
IntegrationUtil.test_pagination(conn, %IntegrationUtil.PaginationParams{
url: "/v3/stats/blocks"
})
end
end
end

0 comments on commit df4c8b3

Please sign in to comment.