From f62033c12b3feec1183841be7b12661cabb34501 Mon Sep 17 00:00:00 2001 From: Rogerio Pontual <44991200+jyeshe@users.noreply.github.com> Date: Wed, 29 Jun 2022 08:02:40 -0300 Subject: [PATCH] fix: use block/hash param on account balances (#745) --- lib/ae_mdw_web/controllers/aex9_controller.ex | 67 ++++++++++------- .../controllers/aex9_controller_test.exs | 72 ++++++++++++++----- 2 files changed, 96 insertions(+), 43 deletions(-) diff --git a/lib/ae_mdw_web/controllers/aex9_controller.ex b/lib/ae_mdw_web/controllers/aex9_controller.ex index 8064fd3e8..765341734 100644 --- a/lib/ae_mdw_web/controllers/aex9_controller.ex +++ b/lib/ae_mdw_web/controllers/aex9_controller.ex @@ -9,6 +9,8 @@ defmodule AeMdwWeb.Aex9Controller do alias AeMdw.AexnTokens alias AeMdw.AexnContracts alias AeMdw.Db.Contract + alias AeMdw.Db.Model + alias AeMdw.Db.State alias AeMdw.Db.Util alias AeMdw.Error.Input, as: ErrInput alias AeMdw.Node.Db, as: DBN @@ -24,6 +26,8 @@ defmodule AeMdwWeb.Aex9Controller do import AeMdwWeb.Helpers.AexnHelper import AeMdwWeb.AexnView + require Model + plug(PaginatedPlug) action_fallback(FallbackController) @@ -94,35 +98,37 @@ defmodule AeMdwWeb.Aex9Controller do ) @spec balances(Plug.Conn.t(), map()) :: Plug.Conn.t() - def balances(conn, %{"height" => height, "account_id" => account_id}), - do: - handle_input( - conn, - fn -> - account_pk = Validate.id!(account_id, [:account_pubkey]) - - txi = - Util.block_txi(Validate.nonneg_int!(height)) || - raise ErrInput.BlockIndex, value: height + def balances(conn, %{"height" => height, "account_id" => account_id}) do + handle_input( + conn, + fn -> + height = Validate.nonneg_int!(height) - account_balances_reply(conn, account_pk, txi) + if nil == Util.block_txi(height) do + raise ErrInput.BlockIndex, value: height end - ) - def balances(conn, %{"blockhash" => hash, "account_id" => account_id}), - do: - handle_input( - conn, - fn -> - account_pk = Validate.id!(account_id, [:account_pubkey]) + account_pk = Validate.id!(account_id, [:account_pubkey]) - bi = - Util.block_hash_to_bi(Validate.id!(hash)) || - raise ErrInput.Id, value: hash + account_balances_reply(conn, account_pk, {height, -1}) + end + ) + end - account_balances_reply(conn, account_pk, Util.block_txi(bi)) - end - ) + def balances(conn, %{"blockhash" => hash, "account_id" => account_id}) do + handle_input( + conn, + fn -> + account_pk = Validate.id!(account_id, [:account_pubkey]) + + block_index = + Util.block_hash_to_bi(Validate.id!(hash)) || + raise ErrInput.Id, value: hash + + account_balances_reply(conn, account_pk, block_index) + end + ) + end def balances(conn, %{"account_id" => account_id}), do: @@ -335,19 +341,26 @@ defmodule AeMdwWeb.Aex9Controller do json(conn, balances) end - defp account_balances_reply(%Conn{assigns: %{state: state}} = conn, account_pk, last_txi) do + defp account_balances_reply( + %Conn{assigns: %{state: state}} = conn, + account_pk, + {kbi, mbi} = block_index + ) do + {:ok, Model.block(tx_index: last_txi, hash: block_hash)} = + State.get(state, Model.Block, block_index) + contracts = account_pk |> Contract.aex9_search_contract(last_txi) |> Map.to_list() |> Enum.sort_by(fn {_ct_pk, txi_list} -> _call_txi = List.last(txi_list) end) - height_hash = DBN.top_height_hash(top?(conn)) + type = if mbi == -1, do: :key, else: :micro balances = contracts |> Enum.map(fn {contract_pk, txi_list} -> - {amount, _} = DBN.aex9_balance(contract_pk, account_pk, height_hash) + {amount, _} = DBN.aex9_balance(contract_pk, account_pk, {type, kbi, block_hash}) call_txi = List.last(txi_list) {amount, call_txi, contract_pk} end) diff --git a/test/integration/ae_mdw_web/controllers/aex9_controller_test.exs b/test/integration/ae_mdw_web/controllers/aex9_controller_test.exs index 2648774e1..beb4a2aca 100644 --- a/test/integration/ae_mdw_web/controllers/aex9_controller_test.exs +++ b/test/integration/ae_mdw_web/controllers/aex9_controller_test.exs @@ -348,34 +348,74 @@ defmodule Integration.AeMdwWeb.Aex9ControllerTest do assert height in [300_001, 400_002, 500_003] end) end + end - test "gets balances for hash and account", %{conn: conn} do - mb_height = 578_684 - mb_hash = "mh_2eSwMRK7KXtPZqkciBWU2o764yZ8QCttWUSxvh2aRWwDE15oVm" - account_id = "ak_QyFYYpgJ1vUGk1Lnk8d79WJEVcAtcfuNHqquuP2ADfxsL6yKx" + describe "block account balances" do + test "gets account balances up to a block", %{conn: conn} do + mb_height = 434_825 + mb_hash = "mh_iDZvfWrZ8QEFaBW9nGzrTv1KBPMh2dVW4z2Bn7NBALLqwFRB9" + account_id = "ak_3n5eTrEzg2VDQK7Y2XJdShVeaDsdpZggA8JvpukGpwEKkiorv" conn = get(conn, "/aex9/balances/hash/#{mb_hash}/account/#{account_id}") response_list = json_response(conn, 200) assert Enum.any?(response_list, fn balance -> balance == %{ - "amount" => 100_000_000_000_000_000_000_000_000, - "block_hash" => "mh_26Rfn9fBcaKc2YcpDKD11Aai8jMSdbuqt22DFdqisqLdS8sg6n", - "contract_id" => "ct_wi5be3qiXGWe1DbMTGVyBqkQiNz1K7kch7go9zJDeiHbbAMZ1", - "height" => 466_128, - "token_name" => "AVT", - "token_symbol" => "ae vegas token", - "tx_hash" => "th_2F529Nr3LQBjSwiiWSs2XHW2cNrKi4f9KedH34CBSBPSzbEcNP", - "tx_index" => 24_439_019, - "tx_type" => "contract_call_tx" + "amount" => 1_000_000_000_000_000_000_000_000_000_000_000_000, + "block_hash" => "mh_2am5eS1a8Y2Mo8Lj8a1Bn1UNDNpEeaACbGrGcs2pEBg8hLHaZA", + "contract_id" => "ct_27ZrSPGoNH2waapYtu4upxDnk2g39dbSzmmZiYP7SGJ4XPb6jM", + "height" => 434_825, + "token_name" => "Aeternity", + "token_symbol" => "Aeternity", + "tx_hash" => "th_ZoRHbdJbx6NM2nu3QBDFmPm2e1uX1RpdrhLVrwj67BYxMbTwe", + "tx_index" => 22_699_236, + "tx_type" => "contract_create_tx" } end) - assert Enum.all?(response_list, fn %{"height" => height, "tx_type" => "contract_call_tx"} -> - height < mb_height + assert Enum.all?(response_list, fn %{"height" => height} -> height <= mb_height end) + + assert length(response_list) == 10 + end + + test "gets account balances up to a height", %{conn: conn} do + kb_height = 434_825 + account_id = "ak_3n5eTrEzg2VDQK7Y2XJdShVeaDsdpZggA8JvpukGpwEKkiorv" + conn = get(conn, "/aex9/balances/gen/#{kb_height}/account/#{account_id}") + + response_list = json_response(conn, 200) + + refute Enum.any?(response_list, fn balance -> + balance == %{ + "amount" => 1_000_000_000_000_000_000_000_000_000_000_000_000, + "block_hash" => "mh_2am5eS1a8Y2Mo8Lj8a1Bn1UNDNpEeaACbGrGcs2pEBg8hLHaZA", + "contract_id" => "ct_27ZrSPGoNH2waapYtu4upxDnk2g39dbSzmmZiYP7SGJ4XPb6jM", + "height" => 434_825, + "token_name" => "Aeternity", + "token_symbol" => "Aeternity", + "tx_hash" => "th_ZoRHbdJbx6NM2nu3QBDFmPm2e1uX1RpdrhLVrwj67BYxMbTwe", + "tx_index" => 22_699_236, + "tx_type" => "contract_create_tx" + } end) - assert length(response_list) == 31 + assert Enum.any?(response_list, fn balance -> + balance == %{ + "amount" => 1_000_000_000_000_000_000_000_000_000_000_000_000_000, + "block_hash" => "mh_DqYipPQJzmffuG9FJjvmSEdydozWs4XuDKqayUSUXzeHrFx6Z", + "contract_id" => "ct_UU9BxMBjxLijyjCa6Cxeopd2xuB2G2pJfHAbvn8Ky6DSMPSXo", + "height" => 417_168, + "token_name" => "Air", + "token_symbol" => "Air", + "tx_hash" => "th_2g1n8V2o5K5gw1aVX7PRz5nJbnrMQefLmE1WVVYsiFwwwU2fF5", + "tx_index" => 21_297_040, + "tx_type" => "contract_create_tx" + } + end) + + assert Enum.all?(response_list, fn %{"height" => height} -> height < kb_height end) + + assert length(response_list) == 6 end end