diff --git a/lib/ae_mdw/aex9.ex b/lib/ae_mdw/aex9.ex index b3b4213d3..d65da55bd 100644 --- a/lib/ae_mdw/aex9.ex +++ b/lib/ae_mdw/aex9.ex @@ -284,25 +284,54 @@ defmodule AeMdw.Aex9 do nil -> {0, DbUtil.last_gen!(state)} end - streamer = fn - :forward when first_gen <= cursor and cursor <= last_gen -> cursor..last_gen - :backward when cursor == nil -> last_gen..first_gen - :backward when first_gen <= cursor and cursor <= last_gen -> cursor..first_gen - _dir -> first_gen..last_gen - end + streamer = + balance_history_streamer(%{ + account_pk: account_pk, + contract_pk: contract_pk, + range: {first_gen, last_gen}, + cursor: cursor + }) paginated_history = Collection.paginate( streamer, pagination, - &render_balance_history_item(contract_pk, account_pk, &1), - & &1 + &render_balance_history_item/1, + &serialize_history_cursor/1 ) {:ok, paginated_history} end end + defp balance_history_streamer(%{ + account_pk: account_pk, + contract_pk: contract_pk, + range: {first_gen, last_gen}, + cursor: cursor + }) do + fn direction -> + direction + |> case do + :forward when first_gen <= cursor and cursor <= last_gen -> cursor..last_gen + :backward when cursor == nil -> last_gen..first_gen + :backward when first_gen <= cursor and cursor <= last_gen -> cursor..first_gen + _dir -> first_gen..last_gen + end + |> Stream.flat_map(fn gen -> + type_height_hash = {:key, gen, DbUtil.height_hash(gen)} + + case Db.aex9_balance(contract_pk, account_pk, type_height_hash) do + {:ok, {amount_or_nil, _height_hash}} -> + [{contract_pk, account_pk, gen, amount_or_nil}] + + _invalid -> + [] + end + end) + end + end + defp serialize_account_balance_cursor(cursor), do: cursor |> :erlang.term_to_binary() |> Base.encode64(padding: false) @@ -335,15 +364,10 @@ defmodule AeMdw.Aex9 do } end - defp render_balance_history_item(contract_pk, account_pk, gen) do - type_height_hash = {:key, gen, DbUtil.height_hash(gen)} - - {:ok, {amount_or_nil, _height_hash}} = - Db.aex9_balance(contract_pk, account_pk, type_height_hash) - - balance = render_balance(contract_pk, {:address, account_pk}, amount_or_nil) - - Map.put(balance, :height, gen) + defp render_balance_history_item({contract_pk, account_pk, gen, amount_or_nil}) do + contract_pk + |> render_balance({:address, account_pk}, amount_or_nil) + |> Map.put(:height, gen) end defp render_account_balance(state, type_height_hash, {account_pk, contract_pk}) do @@ -385,6 +409,10 @@ defmodule AeMdw.Aex9 do end end + defp serialize_history_cursor({_contract_pk, _account_pk, gen, _amount_or_nil}) do + gen + end + defp serialize_event_balances_cursor({_contract_pk, account_pk}), do: encode_account(account_pk) defp deserialize_event_balances_cursor(nil), do: {:ok, nil}