Skip to content

Commit

Permalink
Add stacktrace to decode
Browse files Browse the repository at this point in the history
  • Loading branch information
avilagaston9 committed Apr 22, 2024
1 parent ee95d06 commit 5be55fb
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 25 deletions.
17 changes: 11 additions & 6 deletions lib/ssz_ex/decode.ex
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ defmodule SszEx.Decode do
def decode(binary, module) when is_atom(module) do
with {:ok, result} <-
if(Utils.variable_size?(module),
do: decode_variable_container(binary, module),
else: decode_fixed_container(binary, module)
do: decode_variable_container(binary, module) |> Utils.add_trace("#{module}"),
else: decode_fixed_container(binary, module) |> Utils.add_trace("#{module}")
) do
if exported?(module, :decode_ex, 1) do
{:ok, module.decode_ex(result)}
Expand Down Expand Up @@ -337,14 +337,17 @@ defmodule SszEx.Decode do
:ok ->
size = next_offset - offset
<<chunk::binary-size(size), rest::bitstring>> = rest_bytes
{:cont, {rest, [{key, decode(chunk, schema)} | acc_variable_parts]}}

{:cont,
{rest, [{key, decode(chunk, schema) |> Utils.add_trace(key)} | acc_variable_parts]}}

error ->
{:halt, {<<>>, [{key, error} | acc_variable_parts]}}
end

[{_offset, {key, schema}}], {rest_bytes, acc_variable_parts} ->
{:cont, {<<>>, [{key, decode(rest_bytes, schema)} | acc_variable_parts]}}
{:cont,
{<<>>, [{key, decode(rest_bytes, schema) |> Utils.add_trace(key)} | acc_variable_parts]}}
end)
|> then(fn {<<>>, variable_parts} ->
flatten_container_results(variable_parts)
Expand All @@ -363,7 +366,9 @@ defmodule SszEx.Decode do
else
ssz_fixed_len = Utils.get_fixed_size(schema)
<<chunk::binary-size(ssz_fixed_len), rest::bitstring>> = binary
{rest, [{key, decode(chunk, schema)} | fixed_parts], offsets, items_index + ssz_fixed_len}

{rest, [{key, decode(chunk, schema) |> Utils.add_trace(key)} | fixed_parts], offsets,
items_index + ssz_fixed_len}
end
end)
|> then(fn {_rest_bytes, fixed_parts, offsets, items_index} ->
Expand Down Expand Up @@ -455,7 +460,7 @@ defmodule SszEx.Decode do
case Enum.group_by(results, fn {_, {type, _}} -> type end, fn {key, {_, result}} ->
{key, result}
end) do
%{error: errors} -> {:error, errors}
%{error: [first_error | _rest]} -> {:error, first_error}
summary -> {:ok, Map.get(summary, :ok, [])}
end
end
Expand Down
11 changes: 4 additions & 7 deletions lib/ssz_ex/encode.ex
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ defmodule SszEx.Encode do
do: encode_bitvector(value, size)

def encode(container, module) when is_map(container) do
encode_container(container, module.schema()) |> add_trace("#{module}")
encode_container(container, module.schema()) |> Utils.add_trace("#{module}")
end

defp encode_int(value, size) when is_integer(value), do: {:ok, <<value::size(size)-little>>}
Expand Down Expand Up @@ -172,7 +172,9 @@ defmodule SszEx.Encode do
end

defp encode_schemas(tuple_values) do
Enum.map(tuple_values, fn {value, key, schema} -> encode(value, schema) |> add_trace(key) end)
Enum.map(tuple_values, fn {value, key, schema} ->
encode(value, schema) |> Utils.add_trace(key)
end)
|> Utils.flatten_results()
end

Expand Down Expand Up @@ -210,9 +212,4 @@ defmodule SszEx.Encode do
}}
end
end

defp add_trace({:error, %Error{} = error}, module),
do: {:error, Error.add_trace(error, module)}

defp add_trace(value, _module), do: value
end
6 changes: 6 additions & 0 deletions lib/ssz_ex/utils.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ defmodule SszEx.Utils do

alias LambdaEthereumConsensus.Utils.BitList
alias LambdaEthereumConsensus.Utils.BitVector
alias SszEx.Error

@allowed_uints [8, 16, 32, 64, 128, 256]
@bits_per_byte 8
Expand Down Expand Up @@ -114,4 +115,9 @@ defmodule SszEx.Utils do
def size_of(:bool), do: @bytes_per_boolean

def size_of({:int, size}), do: size |> div(@bits_per_byte)

def add_trace({:error, %Error{} = error}, module),
do: {:error, Error.add_trace(error, module)}

def add_trace(value, _module), do: value
end
20 changes: 8 additions & 12 deletions test/unit/ssz_ex_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -738,24 +738,20 @@ defmodule Unit.SSZExTest do
encoded_checkpoint =
<<0, 0, 0>>

assert SszEx.decode(encoded_checkpoint, Checkpoint) ==
{:error,
%Error{
message:
"Invalid binary length while decoding Elixir.Types.Checkpoint. \nExpected 40. \nFound 3.\n"
}}
{:error, error} = SszEx.decode(encoded_checkpoint, Checkpoint)

assert "#{error}" ==
"Invalid binary length while decoding Elixir.Types.Checkpoint. \nExpected 40. \nFound 3.\nStacktrace: Elixir.Types.Checkpoint"
end

test "decode longer checkpoint" do
encoded_checkpoint =
<<0::size(41 * 8)>>

assert SszEx.decode(encoded_checkpoint, Checkpoint) ==
{:error,
%Error{
message:
"Invalid binary length while decoding Elixir.Types.Checkpoint. \nExpected 40. \nFound 41.\n"
}}
{:error, error} = SszEx.decode(encoded_checkpoint, Checkpoint)

assert "#{error}" ==
"Invalid binary length while decoding Elixir.Types.Checkpoint. \nExpected 40. \nFound 41.\nStacktrace: Elixir.Types.Checkpoint"
end

test "hash tree root of list exceeding max size" do
Expand Down

0 comments on commit 5be55fb

Please sign in to comment.