Skip to content

Commit

Permalink
feat(rpc): return preapply errors
Browse files Browse the repository at this point in the history
  • Loading branch information
Awea committed Jun 13, 2024
1 parent 795324c commit 1299e2c
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 22 deletions.
82 changes: 64 additions & 18 deletions lib/rpc.ex
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,6 @@ defmodule Tezex.Rpc do
def fill_operation_fee(operation, preapplied_operations, opts \\ []) do
storage_limit = Keyword.get(opts, :storage_limit)

applied? =
Enum.all?(
preapplied_operations,
&(&1["metadata"]["operation_result"]["status"] == "applied")
)

unless applied? do
errors = Enum.map(preapplied_operations, & &1["metadata"]["operation_result"]["errors"])
raise inspect(errors)
end

number_contents = length(preapplied_operations)

contents =
Expand Down Expand Up @@ -165,13 +154,24 @@ defmodule Tezex.Rpc do
counter = get_next_counter_for_account(rpc, wallet_address)
operation = prepare_operation(transactions, wallet_address, counter, branch)

{:ok, [%{"contents" => preapplied_operations}]} =
preapply_operation(rpc, operation, encoded_private_key, protocol)
case preapply_operation(rpc, operation, encoded_private_key, protocol) do
{:ok, preapplied_operations} ->
operation = fill_operation_fee(operation, preapplied_operations, opts)

%{"contents" => [content]} = operation

operation = %{
operation
| "contents" => [%{content | "storage_limit" => "2000", "fee" => "500000"}]
}

payload = forge_and_sign_operation(operation, encoded_private_key)

operation = fill_operation_fee(operation, preapplied_operations, opts)
payload = forge_and_sign_operation(operation, encoded_private_key)
inject_operation(rpc, payload)

inject_operation(rpc, payload)
err ->
err
end
end

@doc """
Expand All @@ -195,12 +195,58 @@ defmodule Tezex.Rpc do
Simulate the application of the operations with the context of the given block and return the result of each operation application.
"""
@spec preapply_operation(t(), map(), encoded_private_key(), any()) ::
{:ok, any()} | {:error, Finch.Error.t()} | {:error, Jason.DecodeError.t()}
{:ok, any()}
| {:error, Finch.Error.t()}
| {:error, Jason.DecodeError.t()}
| {:error, term()}
def preapply_operation(%Rpc{} = rpc, operation, encoded_private_key, protocol) do
forged_operation = ForgeOperation.operation_group(operation)
signature = Crypto.sign_operation(encoded_private_key, forged_operation)
payload = [Map.merge(operation, %{"signature" => signature, "protocol" => protocol})]
post(rpc, "/blocks/head/helpers/preapply/operations", payload)

case post(rpc, "/blocks/head/helpers/preapply/operations", payload) do
{:ok, [%{"contents" => preapplied_operations}]} ->
applied? =
Enum.all?(
preapplied_operations,
&(&1["metadata"]["operation_result"]["status"] == "applied")
)

if applied? do
{:ok, preapplied_operations}
else
errors =
Enum.flat_map(
preapplied_operations,
fn
%{
"metadata" => %{
"internal_operation_results" => internal_operation_results
}
} ->
Enum.flat_map(internal_operation_results, & &1["result"]["errors"])

_ ->
[]
end
)

errors =
if Enum.empty?(errors) do
Enum.map(preapplied_operations, & &1["metadata"]["operation_result"]["errors"])
else
errors
end

{:error, errors}
end

{:ok, result} ->
{:error, result}

err ->
err
end
end

@spec get_counter_for_account(t(), nonempty_binary()) ::
Expand Down
23 changes: 19 additions & 4 deletions test/rpc_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ defmodule Tezex.RpcTest do
end

@tag :tezos
test "raise" do
test "return preapply errors" do
rpc = %Rpc{endpoint: @endpoint}

contents = [
Expand All @@ -478,8 +478,23 @@ defmodule Tezex.RpcTest do
}
]

assert_raise RuntimeError, fn ->
Rpc.send_operation(rpc, contents, @ghostnet_1_address, @ghostnet_1_pkey)
end
assert {:error,
[
[
%{
"amount" => "1000000000",
"balance" => "896799001",
"contract" => "tz1ZW1ZSN4ruXYc3nCon8EaTXp1t3tKWb9Ew",
"id" => "proto.019-PtParisB.contract.balance_too_low",
"kind" => "temporary"
},
%{
"amounts" => ["896799001", "1000000000"],
"id" => "proto.019-PtParisB.tez.subtraction_underflow",
"kind" => "temporary"
}
]
]} =
Rpc.send_operation(rpc, contents, @ghostnet_1_address, @ghostnet_1_pkey)
end
end

0 comments on commit 1299e2c

Please sign in to comment.