Skip to content

Commit

Permalink
refactor: 🚧 use structs instead of maps with string keys
Browse files Browse the repository at this point in the history
  • Loading branch information
Awea committed May 7, 2024
1 parent 0237c08 commit c6368ee
Show file tree
Hide file tree
Showing 8 changed files with 410 additions and 521 deletions.
173 changes: 87 additions & 86 deletions lib/forge_operation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ defmodule Tezex.ForgeOperation do
# Checks if the content dictionary has parameters that are not the default 'Unit' type for 'default' entrypoint
defp has_parameters(content) do
case content do
%{"parameters" => %{"entrypoint" => "default", "value" => %{"prim" => "Unit"}}} -> false
%{"parameters" => _} -> true
_ -> false
%{parameters: %{"entrypoint" => "default", "value" => %{"prim" => "Unit"}}} -> false
%{parameters: nil} -> false
_ -> true
end
end

Expand All @@ -57,6 +57,7 @@ defmodule Tezex.ForgeOperation do
<<tag::size(8)>>
end

# 🚧 I think we could achieve something interesting with one struct per kind of operation - @awea 20240507
@spec operation(map()) :: nonempty_binary()
def operation(content) do
encoders = %{
Expand All @@ -74,10 +75,10 @@ defmodule Tezex.ForgeOperation do
"smart_rollup_execute_outbox_message" => &smart_rollup_execute_outbox_message/1
}

encoder = encoders[content["kind"]]
encoder = encoders[content.kind]

if is_nil(encoder) do
raise "No encoder for #{content["kind"]}"
raise "No encoder for #{content.kind}"
end

encoder.(content)
Expand All @@ -86,8 +87,8 @@ defmodule Tezex.ForgeOperation do
@spec operation_group(map()) :: nonempty_binary()
def operation_group(operation_group) do
[
Forge.forge_base58(operation_group["branch"]),
Enum.join(Enum.map(operation_group["contents"], &operation/1))
Forge.forge_base58(operation_group.branch),
Enum.join(Enum.map(operation_group.contents, &operation/1))
]
|> IO.iodata_to_binary()
|> Base.encode16(case: :lower)
Expand All @@ -96,40 +97,40 @@ defmodule Tezex.ForgeOperation do
@spec activate_account(map()) :: nonempty_binary()
def activate_account(content) do
[
forge_tag(@operation_tags[content["kind"]]),
binary_slice(Forge.forge_address(content["pkh"]), 2..-1//1),
Base.decode16!(content["secret"], case: :mixed)
forge_tag(@operation_tags[content.kind]),
binary_slice(Forge.forge_address(content.pkh), 2..-1//1),
Base.decode16!(content.secret, case: :mixed)
]
|> IO.iodata_to_binary()
end

@spec reveal(map()) :: nonempty_binary()
def reveal(content) do
[
forge_tag(@operation_tags[content["kind"]]),
Forge.forge_address(content["source"], :bytes, true),
Forge.forge_nat(String.to_integer(content["fee"])),
Forge.forge_nat(String.to_integer(content["counter"])),
Forge.forge_nat(String.to_integer(content["gas_limit"])),
Forge.forge_nat(String.to_integer(content["storage_limit"])),
Forge.forge_public_key(content["public_key"])
forge_tag(@operation_tags[content.kind]),
Forge.forge_address(content.source, :bytes, true),
Forge.forge_nat(content.fee),
Forge.forge_nat(content.counter),
Forge.forge_nat(content.gas_limit),
Forge.forge_nat(content.storage_limit),
Forge.forge_public_key(content.public_key)
]
|> IO.iodata_to_binary()
end

@spec transaction(map()) :: nonempty_binary()
def transaction(content) do
[
forge_tag(@operation_tags[content["kind"]]),
Forge.forge_address(content["source"], :bytes, true),
Forge.forge_nat(String.to_integer(content["fee"])),
Forge.forge_nat(String.to_integer(content["counter"])),
Forge.forge_nat(String.to_integer(content["gas_limit"])),
Forge.forge_nat(String.to_integer(content["storage_limit"])),
Forge.forge_nat(String.to_integer(content["amount"])),
Forge.forge_address(content["destination"]),
forge_tag(@operation_tags[content.kind]),
Forge.forge_address(content.source, :bytes, true),
Forge.forge_nat(content.fee),
Forge.forge_nat(content.counter),
Forge.forge_nat(content.gas_limit),
Forge.forge_nat(content.storage_limit),
Forge.forge_nat(content.amount),
Forge.forge_address(content.destination),
if has_parameters(content) do
params = content["parameters"]
params = content.parameters

[
Forge.forge_bool(true),
Expand All @@ -146,35 +147,35 @@ defmodule Tezex.ForgeOperation do
@spec origination(map()) :: nonempty_binary()
def origination(content) do
[
forge_tag(@operation_tags[content["kind"]]),
Forge.forge_address(content["source"], :bytes, true),
Forge.forge_nat(String.to_integer(content["fee"])),
Forge.forge_nat(String.to_integer(content["counter"])),
Forge.forge_nat(String.to_integer(content["gas_limit"])),
Forge.forge_nat(String.to_integer(content["storage_limit"])),
Forge.forge_nat(String.to_integer(content["balance"])),
case Map.get(content, "delegate") do
forge_tag(@operation_tags[content.kind]),
Forge.forge_address(content.source, :bytes, true),
Forge.forge_nat(content.fee),
Forge.forge_nat(content.counter),
Forge.forge_nat(content.gas_limit),
Forge.forge_nat(content.storage_limit),
Forge.forge_nat(content.balance),
case Map.get(content, :delegate) do
nil ->
Forge.forge_bool(false)

delegate ->
[Forge.forge_bool(true), Forge.forge_address(delegate, :bytes, true)]
end,
Forge.forge_script(content["script"])
Forge.forge_script(content.script)
]
|> IO.iodata_to_binary()
end

@spec delegation(map()) :: nonempty_binary()
def delegation(content) do
[
forge_tag(@operation_tags[content["kind"]]),
Forge.forge_address(content["source"], :bytes, true),
Forge.forge_nat(String.to_integer(content["fee"])),
Forge.forge_nat(String.to_integer(content["counter"])),
Forge.forge_nat(String.to_integer(content["gas_limit"])),
Forge.forge_nat(String.to_integer(content["storage_limit"])),
case Map.get(content, "delegate") do
forge_tag(@operation_tags[content.kind]),
Forge.forge_address(content.source, :bytes, true),
Forge.forge_nat(content.fee),
Forge.forge_nat(content.counter),
Forge.forge_nat(content.gas_limit),
Forge.forge_nat(content.storage_limit),
case Map.get(content, :delegate) do
nil ->
Forge.forge_bool(false)

Expand All @@ -187,81 +188,81 @@ defmodule Tezex.ForgeOperation do

@spec endorsement(map()) :: nonempty_binary()
def endorsement(content) do
[forge_tag(content["kind"]), Forge.forge_int32(String.to_integer(content["level"]))]
[forge_tag(content.kind), Forge.forge_int32(content.level)]
|> IO.iodata_to_binary()
end

@spec inline_endorsement(map()) :: nonempty_binary()
def inline_endorsement(content) do
[
Forge.forge_base58(content["branch"]),
Forge.forge_nat(@operation_tags[content["operations"]["kind"]]),
Forge.forge_int32(String.to_integer(content["operations"]["level"])),
Forge.forge_base58(content["signature"])
Forge.forge_base58(content.branch),
Forge.forge_nat(@operation_tags[content.operations.kind]),
Forge.forge_int32(content.operations.level),
Forge.forge_base58(content.signature)
]
|> IO.iodata_to_binary()
end

@spec endorsement_with_slot(map()) :: nonempty_binary()
def endorsement_with_slot(content) do
[
forge_tag(content["kind"]),
Forge.forge_array(inline_endorsement(content["endorsement"])),
Forge.forge_int16(String.to_integer(content["slot"]))
forge_tag(content.kind),
Forge.forge_array(inline_endorsement(content.endorsement)),
Forge.forge_int16(content.slot)
]
|> IO.iodata_to_binary()
end

@spec failing_noop(map()) :: nonempty_binary()
def failing_noop(content) do
[forge_tag(content["kind"]), Forge.forge_array(content["arbitrary"])] |> IO.iodata_to_binary()
[forge_tag(content.kind), Forge.forge_array(content.arbitrary)] |> IO.iodata_to_binary()
end

@spec register_global_constant(map()) :: nonempty_binary()
def register_global_constant(content) do
[
forge_tag(@operation_tags[content["kind"]]),
Forge.forge_address(content["source"], :bytes, true),
Forge.forge_nat(String.to_integer(content["fee"])),
Forge.forge_nat(String.to_integer(content["counter"])),
Forge.forge_nat(String.to_integer(content["gas_limit"])),
Forge.forge_nat(String.to_integer(content["storage_limit"])),
Forge.forge_array(Forge.forge_micheline(content["value"]))
forge_tag(@operation_tags[content.kind]),
Forge.forge_address(content.source, :bytes, true),
Forge.forge_nat(content.fee),
Forge.forge_nat(content.counter),
Forge.forge_nat(content.gas_limit),
Forge.forge_nat(content.storage_limit),
Forge.forge_array(Forge.forge_micheline(content.value))
]
|> IO.iodata_to_binary()
end

@spec transfer_ticket(map()) :: nonempty_binary()
def transfer_ticket(content) do
[
forge_tag(@operation_tags[content["kind"]]),
Forge.forge_address(content["source"], :bytes, true),
Forge.forge_nat(String.to_integer(content["fee"])),
Forge.forge_nat(String.to_integer(content["counter"])),
Forge.forge_nat(String.to_integer(content["gas_limit"])),
Forge.forge_nat(String.to_integer(content["storage_limit"])),
Forge.forge_array(Forge.forge_micheline(content["ticket_contents"])),
Forge.forge_array(Forge.forge_micheline(content["ticket_ty"])),
Forge.forge_address(content["ticket_ticketer"]),
Forge.forge_nat(String.to_integer(content["ticket_amount"])),
Forge.forge_address(content["destination"]),
Forge.forge_array(content["entrypoint"])
forge_tag(@operation_tags[content.kind]),
Forge.forge_address(content.source, :bytes, true),
Forge.forge_nat(content.fee),
Forge.forge_nat(content.counter),
Forge.forge_nat(content.gas_limit),
Forge.forge_nat(content.storage_limit),
Forge.forge_array(Forge.forge_micheline(content.ticket_contents)),
Forge.forge_array(Forge.forge_micheline(content.ticket_ty)),
Forge.forge_address(content.ticket_ticketer),
Forge.forge_nat(content.ticket_amount),
Forge.forge_address(content.destination),
Forge.forge_array(content.entrypoint)
]
|> IO.iodata_to_binary()
end

@spec smart_rollup_add_messages(map()) :: nonempty_binary()
def smart_rollup_add_messages(content) do
[
forge_tag(@operation_tags[content["kind"]]),
Forge.forge_address(content["source"], :bytes, true),
Forge.forge_nat(String.to_integer(content["fee"])),
Forge.forge_nat(String.to_integer(content["counter"])),
Forge.forge_nat(String.to_integer(content["gas_limit"])),
Forge.forge_nat(String.to_integer(content["storage_limit"])),
forge_tag(@operation_tags[content.kind]),
Forge.forge_address(content.source, :bytes, true),
Forge.forge_nat(content.fee),
Forge.forge_nat(content.counter),
Forge.forge_nat(content.gas_limit),
Forge.forge_nat(content.storage_limit),
Forge.forge_array(
Enum.join(
Enum.map(content["message"], &Forge.forge_array(:binary.decode_hex(&1))),
Enum.map(content.message, &Forge.forge_array(:binary.decode_hex(&1))),
""
)
)
Expand All @@ -272,15 +273,15 @@ defmodule Tezex.ForgeOperation do
@spec smart_rollup_execute_outbox_message(map()) :: nonempty_binary()
def smart_rollup_execute_outbox_message(content) do
[
forge_tag(@operation_tags[content["kind"]]),
Forge.forge_address(content["source"], :bytes, true),
Forge.forge_nat(String.to_integer(content["fee"])),
Forge.forge_nat(String.to_integer(content["counter"])),
Forge.forge_nat(String.to_integer(content["gas_limit"])),
Forge.forge_nat(String.to_integer(content["storage_limit"])),
Forge.forge_base58(content["rollup"]),
Forge.forge_base58(content["cemented_commitment"]),
Forge.forge_array(:binary.decode_hex(content["output_proof"]))
forge_tag(@operation_tags[content.kind]),
Forge.forge_address(content.source, :bytes, true),
Forge.forge_nat(content.fee),
Forge.forge_nat(content.counter),
Forge.forge_nat(content.gas_limit),
Forge.forge_nat(content.storage_limit),
Forge.forge_base58(content.rollup),
Forge.forge_base58(content.cemented_commitment),
Forge.forge_array(:binary.decode_hex(content.output_proof))
]
|> IO.iodata_to_binary()
end
Expand Down
10 changes: 10 additions & 0 deletions lib/operation.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
defmodule Tezex.Operation do
alias Tezex.Transaction

@type t() :: %__MODULE__{
branch: binary(),
contents: list(Transaction.t())
}

defstruct [:branch, :contents]
end
Loading

0 comments on commit c6368ee

Please sign in to comment.