From c55a8aa75fbe49c098a8df5d75cbc175f923610b Mon Sep 17 00:00:00 2001 From: Valentin Atanasov Date: Tue, 29 Oct 2024 12:39:39 +0200 Subject: [PATCH] fix: transactions for account listing (#1993) --- .../db/mutations/write_fields_mutation.ex | 2 +- lib/ae_mdw/db/sync/inner_tx.ex | 4 +--- lib/ae_mdw/fields.ex | 10 ++++++--- lib/ae_mdw/node.ex | 21 +++++++++++++++++++ lib/ae_mdw/txs.ex | 20 +++++++++++++----- 5 files changed, 45 insertions(+), 12 deletions(-) diff --git a/lib/ae_mdw/db/mutations/write_fields_mutation.ex b/lib/ae_mdw/db/mutations/write_fields_mutation.ex index 6692c2ee1..868980996 100644 --- a/lib/ae_mdw/db/mutations/write_fields_mutation.ex +++ b/lib/ae_mdw/db/mutations/write_fields_mutation.ex @@ -15,7 +15,7 @@ defmodule AeMdw.Db.WriteFieldsMutation do require Model - @typep wrap_tx :: :ga_meta_tx | :paying_for_tx | nil + @typep wrap_tx :: Txs.wrap_tx_type() | nil @derive AeMdw.Db.Mutation defstruct [:type, :tx, :block_index, :txi, :wrap_tx] diff --git a/lib/ae_mdw/db/sync/inner_tx.ex b/lib/ae_mdw/db/sync/inner_tx.ex index 67b4a9eab..adfe38d66 100644 --- a/lib/ae_mdw/db/sync/inner_tx.ex +++ b/lib/ae_mdw/db/sync/inner_tx.ex @@ -10,9 +10,7 @@ defmodule AeMdw.Db.Sync.InnerTx do require Model - @typep wrapper_type() :: :ga_meta_tx | :paying_for_tx - - @spec signed_tx(wrapper_type(), Node.tx()) :: Node.signed_tx() + @spec signed_tx(Txs.wrap_tx_type(), Node.tx()) :: Node.signed_tx() def signed_tx(:ga_meta_tx, wrapper_tx), do: :aega_meta_tx.tx(wrapper_tx) def signed_tx(:paying_for_tx, wrapper_tx), do: :aec_paying_for_tx.tx(wrapper_tx) diff --git a/lib/ae_mdw/fields.ex b/lib/ae_mdw/fields.ex index 95c490074..6b1f4e664 100644 --- a/lib/ae_mdw/fields.ex +++ b/lib/ae_mdw/fields.ex @@ -64,9 +64,13 @@ defmodule AeMdw.Fields do end @spec field_pos_mask(Node.tx_type(), pos()) :: pos() - def field_pos_mask(:ga_meta_tx, pos), do: pos - 1 + @base_wraptx_field_pos - def field_pos_mask(:paying_for_tx, pos), do: pos - 1 + @base_wraptx_field_pos - def field_pos_mask(_tx_type, pos), do: pos + def field_pos_mask(type, pos) do + if type in Txs.wrap_tx_types() do + pos - 1 + @base_wraptx_field_pos + else + pos + end + end @spec mdw_field_pos(String.t()) :: pos() def mdw_field_pos("entrypoint"), do: @base_mdw_field_pos diff --git a/lib/ae_mdw/node.ex b/lib/ae_mdw/node.ex index 0bc75ff47..078449e47 100644 --- a/lib/ae_mdw/node.ex +++ b/lib/ae_mdw/node.ex @@ -11,9 +11,11 @@ defmodule AeMdw.Node do alias AeMdw.Contract alias AeMdw.Contracts alias AeMdw.Db.HardforkPresets + alias AeMdw.Fields alias AeMdw.Extract alias AeMdw.Extract.AbsCode alias AeMdw.Node.Db + alias AeMdw.Txs import AeMdw.Util.Memoize @@ -260,6 +262,25 @@ defmodule AeMdw.Node do Map.fetch!(tx_field_types, tx_field) end + @spec tx_ids_positions() :: %{Txs.wrap_tx_type() => [tx_field_pos()]} + defmemo wrapper_tx_positions() do + {wrapper_tx_types, non_wrapper_tx_types} = Map.split(tx_ids_positions(), Txs.wrap_tx_types()) + + internal_positions = + non_wrapper_tx_types + |> Enum.reduce(MapSet.new(), fn {_type, positions}, acc -> + MapSet.union(acc, MapSet.new(positions)) + end) + |> MapSet.to_list() + + Enum.into(wrapper_tx_types, %{}, fn {tx_type, wrapper_positions} -> + {tx_type, + Enum.reduce(internal_positions, wrapper_positions, fn p, acc -> + [Fields.field_pos_mask(tx_type, p) | acc] + end)} + end) + end + @spec tx_fields(tx_type()) :: [atom()] def tx_fields(tx_type) do {_tx_field_types, tx_fields, _tx_ids} = types_fields_ids() diff --git a/lib/ae_mdw/txs.ex b/lib/ae_mdw/txs.ex index d72dfa80a..6153e9c0a 100644 --- a/lib/ae_mdw/txs.ex +++ b/lib/ae_mdw/txs.ex @@ -42,6 +42,7 @@ defmodule AeMdw.Txs do | %{} @type opt() :: {:add_spendtx_details?, boolean()} | {:render_v3?, boolean()} @type opts() :: [opt()] + @type wrap_tx_type :: :ga_meta_tx | :paying_for_tx @typep state() :: State.t() @typep pagination :: Collection.direction_limit() @@ -60,6 +61,9 @@ defmodule AeMdw.Txs do @type_spend_tx "SpendTx" + @spec wrap_tx_types() :: [wrap_tx_type()] + def wrap_tx_types(), do: [:ga_meta_tx, :paying_for_tx] + @spec count(state(), range(), map()) :: {:ok, non_neg_integer()} | {:error, Error.t()} def count(state, nil, %{"tx_type" => tx_type} = params) do params = @@ -475,11 +479,17 @@ defmodule AeMdw.Txs do {:ok, Enum.flat_map(tx_types, fn tx_type -> - poss = tx_type |> Node.tx_ids_positions() |> Enum.map(&{tx_type, &1}) - # nil - for link - poss = if tx_type in @create_tx_types, do: [{tx_type, nil} | poss], else: poss - - if tx_type == :contract_create_tx, do: [{:contract_call_tx, nil} | poss], else: poss + if tx_type in wrap_tx_types() do + Node.wrapper_tx_positions() + |> Map.fetch!(tx_type) + |> Enum.map(fn pos -> {tx_type, pos} end) + else + poss = tx_type |> Node.tx_ids_positions() |> Enum.map(&{tx_type, &1}) + # nil - for link + poss = if tx_type in @create_tx_types, do: [{tx_type, nil} | poss], else: poss + + if tx_type == :contract_create_tx, do: [{:contract_call_tx, nil} | poss], else: poss + end end)} end