diff --git a/lib/ae_mdw/db/format.ex b/lib/ae_mdw/db/format.ex index ec785d74e..9e80c8ec2 100644 --- a/lib/ae_mdw/db/format.ex +++ b/lib/ae_mdw/db/format.ex @@ -11,6 +11,7 @@ defmodule AeMdw.Db.Format do alias AeMdw.Db.State alias AeMdw.Db.Util, as: DbUtil alias AeMdw.Names + alias AeMdw.Node alias AeMdw.Txs require Model @@ -525,4 +526,32 @@ defmodule AeMdw.Db.Format do do: update_in(tx, ["tx", "tx", "pointers"], &encode_pointers/1) defp maybe_encode_inner_tx_pointers(tx), do: tx + + # Once we move to 6.7+ we can use :aetx.type_to_swagger_name/1 + @spec type_to_swagger_name(Node.tx_type()) :: String.t() + def type_to_swagger_name(:spend_tx), do: "SpendTx" + def type_to_swagger_name(:oracle_register_tx), do: "OracleRegisterTx" + def type_to_swagger_name(:oracle_extend_tx), do: "OracleExtendTx" + def type_to_swagger_name(:oracle_query_tx), do: "OracleQueryTx" + def type_to_swagger_name(:oracle_response_tx), do: "OracleRespondTx" + def type_to_swagger_name(:name_preclaim_tx), do: "NamePreclaimTx" + def type_to_swagger_name(:name_claim_tx), do: "NameClaimTx" + def type_to_swagger_name(:name_transfer_tx), do: "NameTransferTx" + def type_to_swagger_name(:name_update_tx), do: "NameUpdateTx" + def type_to_swagger_name(:name_revoke_tx), do: "NameRevokeTx" + def type_to_swagger_name(:contract_call_tx), do: "ContractCallTx" + def type_to_swagger_name(:contract_create_tx), do: "ContractCreateTx" + def type_to_swagger_name(:ga_attach_tx), do: "GAAttachTx" + def type_to_swagger_name(:ga_meta_tx), do: "GAMetaTx" + def type_to_swagger_name(:paying_for_tx), do: "PayingForTx" + def type_to_swagger_name(:channel_create_tx), do: "ChannelCreateTx" + def type_to_swagger_name(:channel_deposit_tx), do: "ChannelDepositTx" + def type_to_swagger_name(:channel_withdraw_tx), do: "ChannelWithdrawTx" + def type_to_swagger_name(:channel_force_progress_tx), do: "ChannelForceProgressTx" + def type_to_swagger_name(:channel_close_solo_tx), do: "ChannelCloseSoloTx" + def type_to_swagger_name(:channel_close_mutual_tx), do: "ChannelCloseMutualTx" + def type_to_swagger_name(:channel_slash_tx), do: "ChannelSlashTx" + def type_to_swagger_name(:channel_settle_tx), do: "ChannelSettleTx" + def type_to_swagger_name(:channel_snapshot_solo_tx), do: "ChannelSnapshotSoloTx" + def type_to_swagger_name(:channel_set_delegates_tx), do: "ChannelSetDelegatesTx" end diff --git a/lib/ae_mdw/db/util.ex b/lib/ae_mdw/db/util.ex index f90a9bd37..e9497ab61 100644 --- a/lib/ae_mdw/db/util.ex +++ b/lib/ae_mdw/db/util.ex @@ -157,30 +157,40 @@ defmodule AeMdw.Db.Util do end @spec read_node_tx(state(), Txs.txi_idx()) :: Node.tx() - def read_node_tx(state, {txi, -1}) do - Model.tx(id: tx_hash) = State.fetch!(state, Model.Tx, txi) + def read_node_tx(state, txi_idx) do + {tx, _tx_hash, _tx_type} = read_node_tx_details(state, txi_idx) + tx + end - case Db.get_tx_data(tx_hash) do - {_block_hash, tx_type, _signed_tx, tx_rec} when tx_type in [:ga_meta_tx, :paying_for_tx] -> - {_type, tx} = - tx_type - |> InnerTx.signed_tx(tx_rec) - |> :aetx_sign.tx() - |> :aetx.specialize_type() + @spec read_node_tx_details(state(), Txs.txi_idx()) :: {Node.tx(), Txs.tx_hash(), Node.tx_type()} + def read_node_tx_details(state, {txi, -1}) do + Model.tx(id: tx_hash) = State.fetch!(state, Model.Tx, txi) + {_block_hash, tx_type, _signed_tx, tx_rec} = Db.get_tx_data(tx_hash) - tx + if tx_type in [:ga_meta_tx, :paying_for_tx] do + {_type, tx} = + tx_type + |> InnerTx.signed_tx(tx_rec) + |> :aetx_sign.tx() + |> :aetx.specialize_type() - {_block_hash, _tx_type, _signed_tx, tx_rec} -> - tx_rec + {tx, tx_hash, tx_type} + else + {tx_rec, tx_hash, tx_type} end end - def read_node_tx(state, {txi, local_idx}) do + def read_node_tx_details(state, {txi, local_idx}) do + Model.tx(id: tx_hash) = State.fetch!(state, Model.Tx, txi) + Model.int_contract_call(tx: aetx) = State.fetch!(state, Model.IntContractCall, {txi, local_idx}) + {_block_hash, tx_type, _signed_tx, _tx_rec} = Db.get_tx_data(tx_hash) + {_type, tx} = :aetx.specialize_type(aetx) - tx + + {tx, tx_hash, tx_type} end defp extract_height_hash(state, type, hash) do diff --git a/lib/ae_mdw/names.ex b/lib/ae_mdw/names.ex index d9eb0332b..cbe29f501 100644 --- a/lib/ae_mdw/names.ex +++ b/lib/ae_mdw/names.ex @@ -598,33 +598,42 @@ defmodule AeMdw.Names do defp render_claim(state, {{height, _mbi} = block_index, txi_idx}) do block_hash = Blocks.block_index_to_hash(state, block_index) - claim_aetx = DbUtil.read_node_tx(state, txi_idx) + {claim_aetx, tx_hash, tx_type} = DbUtil.read_node_tx_details(state, txi_idx) %{ height: height, block_hash: Enc.encode(:micro_block_hash, block_hash), + source_tx_hash: Enc.encode(:tx_hash, tx_hash), + source_tx_type: Format.type_to_swagger_name(tx_type), + internal_source: tx_type != :name_claim_tx, tx: :aens_claim_tx.for_client(claim_aetx) } end defp render_update(state, {{height, _mbi} = block_index, txi_idx}) do block_hash = Blocks.block_index_to_hash(state, block_index) - update_aetx = DbUtil.read_node_tx(state, txi_idx) + {update_aetx, tx_hash, tx_type} = DbUtil.read_node_tx_details(state, txi_idx) %{ height: height, block_hash: Enc.encode(:micro_block_hash, block_hash), + source_tx_hash: Enc.encode(:tx_hash, tx_hash), + source_tx_type: Format.type_to_swagger_name(tx_type), + internal_source: tx_type != :name_update_tx, tx: :aens_update_tx.for_client(update_aetx) } end defp render_transfer(state, {{height, _mbi} = block_index, txi_idx}) do block_hash = Blocks.block_index_to_hash(state, block_index) - transfer_aetx = DbUtil.read_node_tx(state, txi_idx) + {transfer_aetx, tx_hash, tx_type} = DbUtil.read_node_tx_details(state, txi_idx) %{ height: height, block_hash: Enc.encode(:micro_block_hash, block_hash), + source_tx_hash: Enc.encode(:tx_hash, tx_hash), + source_tx_type: Format.type_to_swagger_name(tx_type), + internal_source: tx_type != :name_transfer_tx, tx: :aens_transfer_tx.for_client(transfer_aetx) } end diff --git a/test/ae_mdw_web/controllers/name_controller_test.exs b/test/ae_mdw_web/controllers/name_controller_test.exs index 6388571cc..fb4ebc28a 100644 --- a/test/ae_mdw_web/controllers/name_controller_test.exs +++ b/test/ae_mdw_web/controllers/name_controller_test.exs @@ -1,6 +1,7 @@ defmodule AeMdwWeb.NameControllerTest do use AeMdwWeb.ConnCase + alias :aeser_api_encoder, as: Enc alias AeMdw.Db.Model alias AeMdw.Db.Model.ActiveName alias AeMdw.Db.Model.ActiveNameActivation @@ -1743,6 +1744,9 @@ defmodule AeMdwWeb.NameControllerTest do store = name_claims_store(store, plain_name) conn = with_store(conn, store) + tx1_hash_enc = Enc.encode(:tx_hash, <<0::256>>) + tx2_hash_enc = Enc.encode(:tx_hash, <<1::256>>) + tx3_hash_enc = Enc.encode(:tx_hash, <<2::256>>) {:ok, aetx1} = :aens_claim_tx.new(%{ @@ -1787,13 +1791,13 @@ defmodule AeMdwWeb.NameControllerTest do {Db, [], [ get_tx_data: fn - "tx1-hash" -> + <<0::256>> -> {"", :name_claim_tx, :aetx_sign.new(aetx1, []), tx1} - "tx2-hash" -> + <<1::256>> -> {"", :name_claim_tx, :aetx_sign.new(aetx2, []), tx2} - "tx3-hash" -> + <<2::256>> -> {"", :name_claim_tx, :aetx_sign.new(aetx3, []), tx3} end ]} @@ -1804,14 +1808,35 @@ defmodule AeMdwWeb.NameControllerTest do |> json_response(200) refute is_nil(next_url) - assert %{"height" => 124, "tx" => %{"fee" => 333_333}} = claim3 - assert %{"height" => 123, "tx" => %{"fee" => 222_222}} = claim2 + + assert %{ + "height" => 124, + "source_tx_type" => "NameClaimTx", + "source_tx_hash" => ^tx3_hash_enc, + "internal_source" => false, + "tx" => %{"fee" => 333_333} + } = claim3 + + assert %{ + "height" => 123, + "source_tx_type" => "NameClaimTx", + "source_tx_hash" => ^tx2_hash_enc, + "internal_source" => false, + "tx" => %{"fee" => 222_222} + } = claim2 assert %{"data" => [claim1], "prev" => prev_url} = conn |> get(next_url) |> json_response(200) refute is_nil(prev_url) - assert %{"height" => 123, "tx" => %{"fee" => 111_111}} = claim1 + + assert %{ + "height" => 123, + "source_tx_type" => "NameClaimTx", + "source_tx_hash" => ^tx1_hash_enc, + "internal_source" => false, + "tx" => %{"fee" => 111_111} + } = claim1 assert %{"data" => ^claims} = conn |> get(prev_url) |> json_response(200) end @@ -1868,13 +1893,13 @@ defmodule AeMdwWeb.NameControllerTest do {Db, [], [ get_tx_data: fn - "tx1-hash" -> + <<0::256>> -> {"", :name_claim_tx, :aetx_sign.new(aetx1, []), tx1} - "tx2-hash" -> + <<1::256>> -> {"", :name_claim_tx, :aetx_sign.new(aetx2, []), tx2} - "tx3-hash" -> + <<2::256>> -> {"", :name_claim_tx, :aetx_sign.new(aetx3, []), tx3} end ]} @@ -1916,6 +1941,7 @@ defmodule AeMdwWeb.NameControllerTest do contract_id = :aeser_id.create(:contract, contract_pk) plain_name = "asd.chain" call_txi = 567 + tx1_hash_enc = Enc.encode(:tx_hash, <<0::256>>) {:ok, contract_call_aetx} = :aect_call_tx.new(%{ @@ -1959,7 +1985,7 @@ defmodule AeMdwWeb.NameControllerTest do {Db, [], [ get_tx_data: fn - "tx1-hash" -> + <<0::256>> -> {"", :contract_call_tx, :aetx_sign.new(contract_call_aetx, []), contract_call_tx} end ]} @@ -1972,6 +1998,9 @@ defmodule AeMdwWeb.NameControllerTest do assert %{ "height" => 123, + "source_tx_hash" => ^tx1_hash_enc, + "source_tx_type" => "ContractCallTx", + "internal_source" => true, "tx" => %{"fee" => 111_111, "name" => ^plain_name} } = claim1 end @@ -2031,13 +2060,13 @@ defmodule AeMdwWeb.NameControllerTest do {Db, [], [ get_tx_data: fn - "tx1-hash" -> + <<0::256>> -> {"", :name_transfer_tx, :aetx_sign.new(aetx1, []), tx1} - "tx2-hash" -> + <<1::256>> -> {"", :name_transfer_tx, :aetx_sign.new(aetx2, []), tx2} - "tx3-hash" -> + <<2::256>> -> {"", :name_transfer_tx, :aetx_sign.new(aetx3, []), tx3} end ]} @@ -2127,13 +2156,13 @@ defmodule AeMdwWeb.NameControllerTest do {Db, [], [ get_tx_data: fn - "tx1-hash" -> + <<0::256>> -> {"", :name_update_tx, :aetx_sign.new(aetx1, []), tx1} - "tx2-hash" -> + <<1::256>> -> {"", :name_update_tx, :aetx_sign.new(aetx2, []), tx2} - "tx3-hash" -> + <<2::256>> -> {"", :name_update_tx, :aetx_sign.new(aetx3, []), tx3} end ]} @@ -2188,9 +2217,9 @@ defmodule AeMdwWeb.NameControllerTest do store |> Store.put(Model.ActiveName, name) - |> Store.put(Model.Tx, Model.tx(index: 567, id: "tx1-hash")) - |> Store.put(Model.Tx, Model.tx(index: 678, id: "tx2-hash")) - |> Store.put(Model.Tx, Model.tx(index: 788, id: "tx3-hash")) + |> Store.put(Model.Tx, Model.tx(index: 567, id: <<0::256>>)) + |> Store.put(Model.Tx, Model.tx(index: 678, id: <<1::256>>)) + |> Store.put(Model.Tx, Model.tx(index: 788, id: <<2::256>>)) |> Store.put(Model.Block, Model.block(index: {123, 0}, hash: "mb1-hash")) |> Store.put(Model.Block, Model.block(index: {124, 1}, hash: "mb2-hash")) end