Skip to content

Commit 0e81e25

Browse files
authored
chore: sorts aex9 account balances from last to first (#858)
1 parent dcd4c68 commit 0e81e25

File tree

3 files changed

+104
-13
lines changed

3 files changed

+104
-13
lines changed

lib/ae_mdw_web/controllers/aex9_controller.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ defmodule AeMdwWeb.Aex9Controller do
366366
[]
367367
end
368368
end)
369+
|> Enum.sort_by(fn {_amount, call_txi, _contract_pk} -> call_txi end, :desc)
369370
|> Enum.map(&balance_to_map(state, &1))
370371

371372
json(conn, balances)

lib/ae_mdw_web/views/aexn_view.ex

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ defmodule AeMdwWeb.AexnView do
33
Renders data for balance(s) endpoints.
44
"""
55

6-
alias AeMdw.Db.Format
6+
alias AeMdw.Db.Model
77
alias AeMdw.Db.Model
88
alias AeMdw.Db.State
99
alias AeMdw.Db.Util
10+
alias AeMdw.Node.Db, as: NodeDb
1011

1112
require Model
1213

@@ -22,19 +23,20 @@ defmodule AeMdwWeb.AexnView do
2223
@spec balance_to_map(State.t(), {non_neg_integer(), non_neg_integer(), pubkey()}) ::
2324
map()
2425
def balance_to_map(state, {amount, call_txi, contract_pk}) do
25-
tx_idx = Util.read_tx!(state, call_txi)
26-
info = Format.to_raw_map(state, tx_idx)
26+
Model.tx(id: tx_hash, block_index: {height, _mbi}) = Util.read_tx!(state, call_txi)
27+
28+
{block_hash, tx_type, _signed_tx, _tx_rec} = NodeDb.get_tx_data(tx_hash)
2729

2830
Model.aexn_contract(meta_info: {name, symbol, _decimals}) =
2931
State.fetch!(state, Model.AexnContract, {:aex9, contract_pk})
3032

3133
%{
3234
contract_id: enc_ct(contract_pk),
33-
block_hash: enc_block(:micro, info.block_hash),
34-
tx_hash: enc(:tx_hash, info.hash),
35+
block_hash: enc_block(:micro, block_hash),
36+
tx_hash: enc(:tx_hash, tx_hash),
3537
tx_index: call_txi,
36-
tx_type: info.tx.type,
37-
height: info.block_height,
38+
tx_type: tx_type,
39+
height: height,
3840
amount: amount,
3941
token_symbol: symbol,
4042
token_name: name

test/ae_mdw_web/controllers/aex9_controller_test.exs

Lines changed: 94 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ defmodule AeMdwWeb.Aex9ControllerTest do
33

44
alias AeMdw.Database
55
alias AeMdw.Db.Model
6+
alias AeMdw.Db.Store
67
alias AeMdw.Validate
78

8-
import AeMdwWeb.Helpers.AexnHelper, only: [enc_ct: 1]
9+
import AeMdwWeb.Helpers.AexnHelper, only: [enc_ct: 1, enc_id: 1, enc_block: 2]
10+
import Mock
911

1012
require Model
1113

@@ -27,7 +29,7 @@ defmodule AeMdwWeb.Aex9ControllerTest do
2729
end
2830

2931
describe "by_name" do
30-
test "it gets aex9 tokens by name", %{conn: conn} do
32+
test "gets aex9 tokens by name", %{conn: conn} do
3133
assert aex9_tokens = conn |> get("/aex9/by_name") |> json_response(200)
3234
assert length(aex9_tokens) > 0
3335

@@ -48,7 +50,7 @@ defmodule AeMdwWeb.Aex9ControllerTest do
4850
end)
4951
end
5052

51-
test "it gets aex9 tokens filtered by name prefix", %{conn: conn} do
53+
test "gets aex9 tokens filtered by name prefix", %{conn: conn} do
5254
prefix = "some-AEX"
5355

5456
assert aex9_tokens = conn |> get("/aex9/by_name", prefix: prefix) |> json_response(200)
@@ -63,7 +65,7 @@ defmodule AeMdwWeb.Aex9ControllerTest do
6365
end
6466

6567
describe "by_symbol" do
66-
test "it gets aex9 tokens by symbol", %{conn: conn} do
68+
test "gets aex9 tokens by symbol", %{conn: conn} do
6769
assert aex9_tokens = conn |> get("/aex9/by_symbol") |> json_response(200)
6870

6971
aex9_symbols = aex9_tokens |> Enum.map(fn %{"symbol" => symbol} -> symbol end)
@@ -83,7 +85,7 @@ defmodule AeMdwWeb.Aex9ControllerTest do
8385
end)
8486
end
8587

86-
test "it gets aex9 tokens filtered by symbol prefix", %{conn: conn} do
88+
test "gets aex9 tokens filtered by symbol prefix", %{conn: conn} do
8789
prefix = "SAEX9"
8890

8991
assert aex9_tokens = conn |> get("/aex9/by_symbol", prefix: prefix) |> json_response(200)
@@ -96,9 +98,95 @@ defmodule AeMdwWeb.Aex9ControllerTest do
9698
end
9799

98100
describe "by_contract" do
99-
test "it returns an aex9 token", %{conn: conn} do
101+
test "returns an aex9 token", %{conn: conn} do
100102
assert %{"data" => %{"contract_id" => @aex9_token_id}} =
101103
conn |> get("/aex9/by_contract/#{@aex9_token_id}") |> json_response(200)
102104
end
103105
end
106+
107+
describe "balances" do
108+
test "returns all account balances", %{conn: conn, store: store} do
109+
account_pk = :crypto.strong_rand_bytes(32)
110+
111+
expected_balances =
112+
for i <- 1..10 do
113+
txi = Enum.random(1_000_000..10_000_000)
114+
115+
%{
116+
"block_hash" => enc_block(:micro, :crypto.strong_rand_bytes(32)),
117+
"amount" => Enum.random(100_000_000..999_000_000),
118+
"contract_id" => enc_ct(:crypto.strong_rand_bytes(32)),
119+
"height" => div(txi, 1_000),
120+
"token_name" => "name#{i}",
121+
"token_symbol" => "symbol#{i}",
122+
"tx_hash" => :aeser_api_encoder.encode(:tx_hash, :crypto.strong_rand_bytes(32)),
123+
"tx_index" => txi,
124+
"tx_type" => "contract_call_tx"
125+
}
126+
end
127+
128+
store =
129+
Enum.reduce(expected_balances, store, fn %{
130+
"amount" => amount,
131+
"contract_id" => contract_id,
132+
"height" => height,
133+
"token_name" => token_name,
134+
"token_symbol" => token_symbol,
135+
"tx_hash" => tx_hash,
136+
"tx_index" => txi
137+
},
138+
store_acc ->
139+
contract_pk = Validate.id!(contract_id)
140+
tx_hash = Validate.id!(tx_hash)
141+
142+
m_contract =
143+
Model.aexn_contract(
144+
index: {:aex9, contract_pk},
145+
meta_info: {token_name, token_symbol, 18}
146+
)
147+
148+
m_balance =
149+
Model.aex9_balance(
150+
index: {contract_pk, account_pk},
151+
block_index: {height, 0},
152+
txi: txi,
153+
amount: amount
154+
)
155+
156+
m_presence = Model.aex9_account_presence(index: {account_pk, contract_pk}, txi: txi)
157+
158+
store_acc
159+
|> Store.put(Model.Tx, Model.tx(index: txi, id: tx_hash, block_index: {height, 0}))
160+
|> Store.put(Model.AexnContract, m_contract)
161+
|> Store.put(Model.Aex9Balance, m_balance)
162+
|> Store.put(Model.Aex9AccountPresence, m_presence)
163+
end)
164+
165+
with_mocks [
166+
{
167+
AeMdw.Node.Db,
168+
[],
169+
[
170+
get_tx_data: fn tx_hash_bin ->
171+
%{"block_hash" => block_hash} =
172+
Enum.find(expected_balances, fn %{"tx_hash" => tx_hash} ->
173+
tx_hash_bin == Validate.id!(tx_hash)
174+
end)
175+
176+
{Validate.id!(block_hash), :contract_call_tx, nil, nil}
177+
end
178+
]
179+
}
180+
] do
181+
assert balances_data =
182+
conn
183+
|> with_store(store)
184+
|> get("/aex9/balances/account/#{enc_id(account_pk)}")
185+
|> json_response(200)
186+
187+
assert ^balances_data = Enum.sort_by(balances_data, & &1["tx_index"], :desc)
188+
assert MapSet.new(balances_data) == MapSet.new(expected_balances)
189+
end
190+
end
191+
end
104192
end

0 commit comments

Comments
 (0)