Skip to content

Commit

Permalink
feat: add endpoint to get the total count of transactions for a given…
Browse files Browse the repository at this point in the history
… period
  • Loading branch information
yaboiishere committed Jan 23, 2025
1 parent 19cfbd0 commit 5cae66c
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 3 deletions.
41 changes: 41 additions & 0 deletions docs/swagger_v3/stats.spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,47 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/stats/transactions/total:
get:
deprecated: false
description: Get the count of transactions for the given period.
operationId: GetTotalTransactionsStats
parameters:
- name: min_start_date
description: The minimum start date in YYYY-MM-DD format.
in: query
required: false
schema:
type: string
example: "2023-01-01"
- name: max_start_date
description: The maximum start date in YYYY-MM-DD format.
in: query
required: false
schema:
type: string
example: "2024-01-01"
- name: tx_type
description: The type of the transactions
in: query
required: false
schema:
type: string
example: contract_call
responses:
'200':
description: Returns the count of transactions for the given period
content:
application/json:
schema:
type: integer
example: 100
'400':
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/stats/total-accounts:
get:
deprecated: false
Expand Down
36 changes: 34 additions & 2 deletions lib/ae_mdw/stats.ex
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,25 @@ defmodule AeMdw.Stats do
end
end

@spec fetch_transactions_total_stats(State.t(), query(), range()) ::
{:ok, non_neg_integer()}
def fetch_transactions_total_stats(state, query, range) do
with {:ok, filters} <- Util.convert_params(query, &convert_transactions_param/1) do
tx_tag = Map.get(filters, :tx_type, :all)

streamer =
build_statistics_streamer(state, {:transactions, tx_tag}, filters, range, nil, false)

:backward
|> streamer.()
|> Enum.reduce(0, fn index, acc ->
Model.statistic(count: count) = State.fetch!(state, Model.Statistic, index)
acc + count
end)
|> then(&{:ok, &1})
end
end

@spec fetch_blocks_stats(State.t(), pagination(), query(), range(), cursor()) ::
{:ok, {pagination_cursor(), [statistic()], pagination_cursor()}} | {:error, reason()}
def fetch_blocks_stats(state, pagination, query, range, cursor) do
Expand Down Expand Up @@ -325,7 +344,14 @@ defmodule AeMdw.Stats do
end
end

defp build_statistics_streamer(state, tag, filters, range, cursor) do
defp build_statistics_streamer(
state,
tag,
filters,
range,
cursor,
fill_dates \\ true
) do
interval_by = Map.get(filters, :interval_by, :day)
{start_network_date, end_network_date} = DbUtil.network_date_interval(state)
min_date = filters |> Map.get(:min_start_date, start_network_date) |> to_interval(interval_by)
Expand Down Expand Up @@ -367,7 +393,13 @@ defmodule AeMdw.Stats do
fn direction ->
state
|> Collection.stream(Model.Statistic, direction, key_boundary, cursor)
|> fill_missing_dates(tag, interval_by, direction, cursor, min_date, max_date)
|> then(fn stream ->
if fill_dates do
fill_missing_dates(stream, tag, interval_by, direction, cursor, min_date, max_date)
else
stream
end
end)
end
end

Expand Down
10 changes: 10 additions & 0 deletions lib/ae_mdw_web/controllers/stats_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,16 @@ defmodule AeMdwWeb.StatsController do
end
end

@spec transactions_total_stats(Conn.t(), map()) :: Conn.t()
def transactions_total_stats(%Conn{assigns: assigns} = conn, _params) do
%{state: state, query: query, scope: scope} = assigns

with {:ok, count} <-
Stats.fetch_transactions_total_stats(state, query, scope) do
format_json(conn, count)
end
end

@spec blocks_stats(Conn.t(), map()) :: Conn.t()
def blocks_stats(%Conn{assigns: assigns} = conn, _params) do
%{state: state, pagination: pagination, query: query, scope: scope, cursor: cursor} = assigns
Expand Down
1 change: 1 addition & 0 deletions lib/ae_mdw_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ defmodule AeMdwWeb.Router do
get "/accounts/:id/transactions/count", TxController, :count_id

get "/stats/transactions", StatsController, :transactions_stats
get "/stats/transactions/total", StatsController, :transactions_total_stats
get "/stats/blocks", StatsController, :blocks_stats
get "/stats/difficulty", StatsController, :difficulty_stats
get "/stats/hashrate", StatsController, :hashrate_stats
Expand Down
60 changes: 59 additions & 1 deletion test/ae_mdw_web/controllers/stats_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ defmodule AeMdwWeb.StatsControllerTest do
conn
|> get(prev_url)
|> json_response(200)

assert 9 ==
conn
|> get("/v3/stats/transactions/total")
|> json_response(200)
end

test "it returns the count of transactions filtered by a tx type", %{conn: conn, store: store} do
Expand All @@ -167,17 +172,21 @@ defmodule AeMdwWeb.StatsControllerTest do
st3_index = {{:transactions, :spend_tx}, :day, 0}
st4_index = {{:transactions, :spend_tx}, :day, 1}
st5_index = {{:transactions, :spend_tx}, :day, 3}
st6_index = {{:transactions, :all}, :day, 1}
st7_index = {{:transactions, :all}, :day, 3}
{network_start_time, network_end_time} = network_time_interval()

store =
store
|> Store.put(Model.Time, Model.time(index: {network_start_time, 0}))
|> Store.put(Model.Time, Model.time(index: {network_end_time, 200}))
|> Store.put(Model.Statistic, Model.statistic(index: st1_index, count: 1))
|> Store.put(Model.Statistic, Model.statistic(index: st1_index, count: 2))
|> Store.put(Model.Statistic, Model.statistic(index: st2_index, count: 1))
|> Store.put(Model.Statistic, Model.statistic(index: st3_index, count: 1))
|> Store.put(Model.Statistic, Model.statistic(index: st4_index, count: 5))
|> Store.put(Model.Statistic, Model.statistic(index: st5_index, count: 3))
|> Store.put(Model.Statistic, Model.statistic(index: st6_index, count: 5))
|> Store.put(Model.Statistic, Model.statistic(index: st7_index, count: 3))

conn = with_store(conn, store)

Expand Down Expand Up @@ -205,6 +214,21 @@ defmodule AeMdwWeb.StatsControllerTest do
conn
|> get(prev_url)
|> json_response(200)

assert 10 ==
conn
|> get("/v3/stats/transactions/total")
|> json_response(200)

assert 9 ==
conn
|> get("/v3/stats/transactions/total", tx_type: "spend")
|> json_response(200)

assert 1 ==
conn
|> get("/v3/stats/transactions/total", tx_type: "oracle_register")
|> json_response(200)
end

test "when interval_by = week, it returns the count of transactions for the latest weekly periods",
Expand All @@ -215,6 +239,9 @@ defmodule AeMdwWeb.StatsControllerTest do
st1_index = {{:transactions, :all}, :week, 2}
st2_index = {{:transactions, :all}, :week, 3}
st3_index = {{:transactions, :all}, :week, 4}
st4_index = {{:transactions, :all}, :day, 2}
st5_index = {{:transactions, :all}, :day, 9}
st6_index = {{:transactions, :all}, :day, 16}
{network_start_time, network_end_time} = network_time_interval()

store =
Expand All @@ -224,6 +251,9 @@ defmodule AeMdwWeb.StatsControllerTest do
|> Store.put(Model.Statistic, Model.statistic(index: st1_index, count: 1))
|> Store.put(Model.Statistic, Model.statistic(index: st2_index, count: 5))
|> Store.put(Model.Statistic, Model.statistic(index: st3_index, count: 3))
|> Store.put(Model.Statistic, Model.statistic(index: st4_index, count: 1))
|> Store.put(Model.Statistic, Model.statistic(index: st5_index, count: 3))
|> Store.put(Model.Statistic, Model.statistic(index: st6_index, count: 5))

conn = with_store(conn, store)

Expand All @@ -247,6 +277,29 @@ defmodule AeMdwWeb.StatsControllerTest do
conn
|> get(prev_url)
|> json_response(200)

assert 9 ==
conn
|> get("/v3/stats/transactions/total")
|> json_response(200)

assert 4 ==
conn
|> get("/v3/stats/transactions/total", max_start_date: "1970-01-10")
|> json_response(200)

assert 3 ==
conn
|> get("/v3/stats/transactions/total",
max_start_date: "1970-01-10",
min_start_date: "1970-01-08"
)
|> json_response(200)

assert 5 ==
conn
|> get("/v3/stats/transactions/total", min_start_date: "1970-01-11")
|> json_response(200)
end

test "when interval_by = month, it returns the count of transactions for the latest monthly periods",
Expand Down Expand Up @@ -329,6 +382,11 @@ defmodule AeMdwWeb.StatsControllerTest do
conn
|> get(prev_url)
|> json_response(200)

assert 0 ==
conn
|> get("/v3/stats/transactions/total")
|> json_response(200)
end
end

Expand Down

0 comments on commit 5cae66c

Please sign in to comment.