Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: include source tx_hash on nested names endpoints #1104

Merged
merged 2 commits into from Jan 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 29 additions & 0 deletions lib/ae_mdw/db/format.ex
Expand Up @@ -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
Expand Down Expand Up @@ -524,4 +525,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
38 changes: 24 additions & 14 deletions lib/ae_mdw/db/util.ex
Expand Up @@ -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
Expand Down
15 changes: 12 additions & 3 deletions lib/ae_mdw/names.ex
Expand Up @@ -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
Expand Down
67 changes: 48 additions & 19 deletions 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
Expand Down Expand Up @@ -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(%{
Expand Down Expand Up @@ -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
]}
Expand All @@ -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
Expand Down Expand Up @@ -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
]}
Expand Down Expand Up @@ -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(%{
Expand Down Expand Up @@ -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
]}
Expand All @@ -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
Expand Down Expand Up @@ -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
]}
Expand Down Expand Up @@ -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
]}
Expand Down Expand Up @@ -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
Expand Down