From 0a9bad0dc701165c43c9d80bc8b0823f27314ff5 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Mon, 22 Apr 2024 11:58:44 -0300 Subject: [PATCH 01/10] feat: add stacktrace to merkleization --- lib/ssz_ex/error.ex | 18 +++++++++++++++--- lib/ssz_ex/merkleization.ex | 14 +++++++++++--- test/unit/ssz_ex_test.exs | 27 +++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/lib/ssz_ex/error.ex b/lib/ssz_ex/error.ex index fa20dfa41..a09b048d8 100644 --- a/lib/ssz_ex/error.ex +++ b/lib/ssz_ex/error.ex @@ -3,11 +3,23 @@ defmodule SszEx.Error do Error messages for SszEx domain. """ alias SszEx.Error - defstruct [:message] - @type t :: %__MODULE__{message: String.t()} + defstruct [:message, :stacktrace] + @type t :: %__MODULE__{message: String.t(), stacktrace: list()} - def format(%Error{message: message}) do + def format(%Error{message: message, stacktrace: nil}), do: "#{message}" + + def format(%Error{message: message, stacktrace: stacktrace}) do "#{message}" + formatted_stacktrace = stacktrace |> Enum.reverse() |> Enum.join("\n") + "#{message}Stacktrace: #{formatted_stacktrace}" + end + + def add_trace(%Error{message: message, stacktrace: nil}, new_trace) do + %Error{message: message, stacktrace: [new_trace]} + end + + def add_trace(%Error{message: message, stacktrace: stacktrace}, new_trace) do + %Error{message: message, stacktrace: [new_trace | stacktrace]} end defimpl String.Chars, for: __MODULE__ do diff --git a/lib/ssz_ex/merkleization.ex b/lib/ssz_ex/merkleization.ex index 777593593..8e77b1f2a 100644 --- a/lib/ssz_ex/merkleization.ex +++ b/lib/ssz_ex/merkleization.ex @@ -39,6 +39,14 @@ defmodule SszEx.Merkleization do @spec hash_tree_root(binary, {:byte_vector, non_neg_integer}) :: {:ok, Types.root()} + def hash_tree_root(value, {:byte_vector, size}) when byte_size(value) != size, + do: + {:error, + %Error{ + message: + "Invalid binary length while merkleizing byte_vector.\nExpected size: #{size}.\nFound: #{byte_size(value)}\n" + }} + def hash_tree_root(value, {:byte_vector, _size}) do packed_chunks = pack_bytes(value) leaf_count = packed_chunks |> get_chunks_len() |> next_pow_of_two() @@ -118,7 +126,7 @@ defmodule SszEx.Merkleization do case hash_tree_root(value, schema) do {:ok, root} -> {:cont, {:ok, acc_root <> root}} - {:error, %Error{}} = error -> {:halt, error} + {:error, %Error{} = error} -> {:halt, {:error, Error.add_trace(error, key)}} end end) @@ -130,8 +138,8 @@ defmodule SszEx.Merkleization do root = chunks |> merkleize_chunks_with_virtual_padding(leaf_count) {:ok, root} - {:error, %Error{}} -> - value + {:error, %Error{} = error} -> + {:error, Error.add_trace(error, "#{module}")} end end diff --git a/test/unit/ssz_ex_test.exs b/test/unit/ssz_ex_test.exs index 5f2a32e3c..2563a3864 100644 --- a/test/unit/ssz_ex_test.exs +++ b/test/unit/ssz_ex_test.exs @@ -766,4 +766,31 @@ defmodule Unit.SSZExTest do {:error, result} = SszEx.hash_tree_root(initial_list, {:list, {:int, 8}, 2}) assert error == "#{result}" end + + test "stacktrace in hash_tree_root with invalid logs_bloom" do + execution_payload = %ExecutionPayload{ + parent_hash: @default_hash, + fee_recipient: <<0::size(20 * 8)>>, + state_root: @default_root, + receipts_root: @default_root, + logs_bloom: <<0, 0, 0>>, + prev_randao: <<0::size(32 * 8)>>, + block_number: 0, + gas_limit: 0, + gas_used: 0, + timestamp: 0, + extra_data: <<>>, + base_fee_per_gas: 0, + block_hash: @default_hash, + transactions: [], + withdrawals: [], + blob_gas_used: 0, + excess_blob_gas: 0 + } + + {:error, error} = SszEx.hash_tree_root(execution_payload, ExecutionPayload) + + assert "#{error}" == + "Invalid binary length while merkleizing byte_vector.\nExpected size: 256.\nFound: 3\nStacktrace: logs_bloom\nElixir.Types.ExecutionPayload" + end end From ee95d061db7feecd06612077b72c74f7b230d9c7 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Mon, 22 Apr 2024 16:12:37 -0300 Subject: [PATCH 02/10] Add stacktrace to encode --- lib/ssz_ex/encode.ex | 23 ++++++++++++++--------- lib/ssz_ex/utils.ex | 2 +- test/unit/ssz_ex_test.exs | 13 +++++++++++++ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/lib/ssz_ex/encode.ex b/lib/ssz_ex/encode.ex index 7345cdbe8..71eeb24fb 100644 --- a/lib/ssz_ex/encode.ex +++ b/lib/ssz_ex/encode.ex @@ -41,8 +41,9 @@ defmodule SszEx.Encode do def encode(value, {:bitvector, size}) when is_bitvector(value), do: encode_bitvector(value, size) - def encode(container, module) when is_map(container), - do: encode_container(container, module.schema()) + def encode(container, module) when is_map(container) do + encode_container(container, module.schema()) |> add_trace("#{module}") + end defp encode_int(value, size) when is_integer(value), do: {:ok, <>} defp encode_bool(true), do: {:ok, "\x01"} @@ -83,7 +84,7 @@ defmodule SszEx.Encode do {:error, %Error{ message: - "Invalid binary length while encoding BitVector. \nExpected: #{size}.\nFound: #{bit_vector_size(bit_vector)}." + "Invalid binary length while encoding BitVector. \nExpected: #{size}.\nFound: #{bit_vector_size(bit_vector)}.\n" }} defp encode_bitvector(bit_vector, _size), @@ -147,8 +148,7 @@ defmodule SszEx.Encode do Enum.reduce(variable_parts, 0, fn part, acc -> byte_size(part) + acc end), :ok <- check_length(fixed_length, variable_length), {:ok, fixed_parts} <- - replace_offsets(fixed_size_values, offsets) - |> encode_schemas() do + replace_offsets(fixed_size_values, offsets) |> encode_schemas() do (fixed_parts ++ variable_parts) |> Enum.join() |> then(&{:ok, &1}) @@ -163,23 +163,23 @@ defmodule SszEx.Encode do if Utils.variable_size?(schema) do {[:offset | acc_fixed_size_values], @bytes_per_length_offset + acc_fixed_length, - [{value, schema} | acc_variable_values]} + [{value, key, schema} | acc_variable_values]} else - {[{value, schema} | acc_fixed_size_values], + {[{value, key, schema} | acc_fixed_size_values], acc_fixed_length + Utils.get_fixed_size(schema), acc_variable_values} end end) end defp encode_schemas(tuple_values) do - Enum.map(tuple_values, fn {value, schema} -> encode(value, schema) end) + Enum.map(tuple_values, fn {value, key, schema} -> encode(value, schema) |> add_trace(key) end) |> Utils.flatten_results() end defp calculate_offsets(variable_parts, fixed_length) do {offsets, _} = Enum.reduce(variable_parts, {[], fixed_length}, fn element, {res, acc} -> - {[{acc, {:int, 32}} | res], byte_size(element) + acc} + {[{acc, :offset, {:int, 32}} | res], byte_size(element) + acc} end) offsets @@ -210,4 +210,9 @@ 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 diff --git a/lib/ssz_ex/utils.ex b/lib/ssz_ex/utils.ex index 68b639e46..099bb7ad0 100644 --- a/lib/ssz_ex/utils.ex +++ b/lib/ssz_ex/utils.ex @@ -67,7 +67,7 @@ defmodule SszEx.Utils do def flatten_results_by(results, fun) do case Enum.group_by(results, fn {type, _} -> type end, fn {_, result} -> result end) do - %{error: errors} -> {:error, errors} + %{error: [first_error | _rest]} -> {:error, first_error} summary -> {:ok, fun.(Map.get(summary, :ok, []))} end end diff --git a/test/unit/ssz_ex_test.exs b/test/unit/ssz_ex_test.exs index 2563a3864..56b3e44bd 100644 --- a/test/unit/ssz_ex_test.exs +++ b/test/unit/ssz_ex_test.exs @@ -1,4 +1,5 @@ defmodule Unit.SSZExTest do + alias LambdaEthereumConsensus.Utils.BitVector alias LambdaEthereumConsensus.Utils.Diff alias SszEx.Error alias SszEx.Merkleization @@ -793,4 +794,16 @@ defmodule Unit.SSZExTest do assert "#{error}" == "Invalid binary length while merkleizing byte_vector.\nExpected size: 256.\nFound: 3\nStacktrace: logs_bloom\nElixir.Types.ExecutionPayload" end + + test "stacktrace in encode with invalid sync_committee_bits" do + sync_aggregate = %SyncAggregate{ + sync_committee_bits: BitVector.new(2), + sync_committee_signature: <<0::size(32 * 8)>> + } + + {:error, error} = SszEx.encode(sync_aggregate) + + assert "#{error}" == + "Invalid binary length while encoding BitVector. \nExpected: 512.\nFound: 2.\nStacktrace: sync_committee_bits\nElixir.Types.SyncAggregate" + end end From 5be55fb1e290eb808c6e637b97eef26d2a8a5637 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Mon, 22 Apr 2024 17:26:22 -0300 Subject: [PATCH 03/10] Add stacktrace to decode --- lib/ssz_ex/decode.ex | 17 +++++++++++------ lib/ssz_ex/encode.ex | 11 ++++------- lib/ssz_ex/utils.ex | 6 ++++++ test/unit/ssz_ex_test.exs | 20 ++++++++------------ 4 files changed, 29 insertions(+), 25 deletions(-) diff --git a/lib/ssz_ex/decode.ex b/lib/ssz_ex/decode.ex index 2dd49671f..8efc49c50 100644 --- a/lib/ssz_ex/decode.ex +++ b/lib/ssz_ex/decode.ex @@ -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)} @@ -337,14 +337,17 @@ defmodule SszEx.Decode do :ok -> size = next_offset - offset <> = 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) @@ -363,7 +366,9 @@ defmodule SszEx.Decode do else ssz_fixed_len = Utils.get_fixed_size(schema) <> = 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} -> @@ -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 diff --git a/lib/ssz_ex/encode.ex b/lib/ssz_ex/encode.ex index 71eeb24fb..e32caec3c 100644 --- a/lib/ssz_ex/encode.ex +++ b/lib/ssz_ex/encode.ex @@ -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, <>} @@ -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 @@ -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 diff --git a/lib/ssz_ex/utils.ex b/lib/ssz_ex/utils.ex index 099bb7ad0..edb52f845 100644 --- a/lib/ssz_ex/utils.ex +++ b/lib/ssz_ex/utils.ex @@ -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 @@ -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 diff --git a/test/unit/ssz_ex_test.exs b/test/unit/ssz_ex_test.exs index 56b3e44bd..c009ea604 100644 --- a/test/unit/ssz_ex_test.exs +++ b/test/unit/ssz_ex_test.exs @@ -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 From 76c7536cd092acd94f706cac17ec457c89840c04 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Tue, 23 Apr 2024 11:23:07 -0300 Subject: [PATCH 04/10] Add nested containers tests --- lib/ssz_ex/decode.ex | 10 ++-- lib/ssz_ex/encode.ex | 4 +- lib/ssz_ex/error.ex | 7 ++- lib/ssz_ex/merkleization.ex | 4 +- lib/ssz_ex/ssz_ex.ex | 11 +++- lib/ssz_ex/utils.ex | 6 --- test/unit/ssz_ex_test.exs | 103 ++++++++++++++++++++++++++++++++++-- 7 files changed, 125 insertions(+), 20 deletions(-) diff --git a/lib/ssz_ex/decode.ex b/lib/ssz_ex/decode.ex index 8efc49c50..2708db86d 100644 --- a/lib/ssz_ex/decode.ex +++ b/lib/ssz_ex/decode.ex @@ -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) |> Utils.add_trace("#{module}"), - else: decode_fixed_container(binary, module) |> Utils.add_trace("#{module}") + do: decode_variable_container(binary, module), + else: decode_fixed_container(binary, module) ) do if exported?(module, :decode_ex, 1) do {:ok, module.decode_ex(result)} @@ -339,7 +339,7 @@ defmodule SszEx.Decode do <> = rest_bytes {:cont, - {rest, [{key, decode(chunk, schema) |> Utils.add_trace(key)} | acc_variable_parts]}} + {rest, [{key, decode(chunk, schema) |> Error.add_trace(key)} | acc_variable_parts]}} error -> {:halt, {<<>>, [{key, error} | acc_variable_parts]}} @@ -347,7 +347,7 @@ defmodule SszEx.Decode do [{_offset, {key, schema}}], {rest_bytes, acc_variable_parts} -> {:cont, - {<<>>, [{key, decode(rest_bytes, schema) |> Utils.add_trace(key)} | acc_variable_parts]}} + {<<>>, [{key, decode(rest_bytes, schema) |> Error.add_trace(key)} | acc_variable_parts]}} end) |> then(fn {<<>>, variable_parts} -> flatten_container_results(variable_parts) @@ -367,7 +367,7 @@ defmodule SszEx.Decode do ssz_fixed_len = Utils.get_fixed_size(schema) <> = binary - {rest, [{key, decode(chunk, schema) |> Utils.add_trace(key)} | fixed_parts], offsets, + {rest, [{key, decode(chunk, schema) |> Error.add_trace(key)} | fixed_parts], offsets, items_index + ssz_fixed_len} end end) diff --git a/lib/ssz_ex/encode.ex b/lib/ssz_ex/encode.ex index e32caec3c..e91813a6f 100644 --- a/lib/ssz_ex/encode.ex +++ b/lib/ssz_ex/encode.ex @@ -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()) |> Utils.add_trace("#{module}") + encode_container(container, module.schema()) end defp encode_int(value, size) when is_integer(value), do: {:ok, <>} @@ -173,7 +173,7 @@ defmodule SszEx.Encode do defp encode_schemas(tuple_values) do Enum.map(tuple_values, fn {value, key, schema} -> - encode(value, schema) |> Utils.add_trace(key) + encode(value, schema) |> Error.add_trace(key) end) |> Utils.flatten_results() end diff --git a/lib/ssz_ex/error.ex b/lib/ssz_ex/error.ex index a09b048d8..73185c379 100644 --- a/lib/ssz_ex/error.ex +++ b/lib/ssz_ex/error.ex @@ -10,7 +10,7 @@ defmodule SszEx.Error do def format(%Error{message: message, stacktrace: stacktrace}) do "#{message}" - formatted_stacktrace = stacktrace |> Enum.reverse() |> Enum.join("\n") + formatted_stacktrace = stacktrace |> Enum.join(".") "#{message}Stacktrace: #{formatted_stacktrace}" end @@ -22,6 +22,11 @@ defmodule SszEx.Error do %Error{message: message, stacktrace: [new_trace | stacktrace]} end + def add_trace({:error, %Error{} = error}, module), + do: {:error, Error.add_trace(error, module)} + + def add_trace(value, _module), do: value + defimpl String.Chars, for: __MODULE__ do def to_string(error), do: Error.format(error) end diff --git a/lib/ssz_ex/merkleization.ex b/lib/ssz_ex/merkleization.ex index 8e77b1f2a..7429cd10d 100644 --- a/lib/ssz_ex/merkleization.ex +++ b/lib/ssz_ex/merkleization.ex @@ -138,8 +138,8 @@ defmodule SszEx.Merkleization do root = chunks |> merkleize_chunks_with_virtual_padding(leaf_count) {:ok, root} - {:error, %Error{} = error} -> - {:error, Error.add_trace(error, "#{module}")} + {:error, %Error{}} -> + value end end diff --git a/lib/ssz_ex/ssz_ex.ex b/lib/ssz_ex/ssz_ex.ex index 05be7f40d..317c81124 100644 --- a/lib/ssz_ex/ssz_ex.ex +++ b/lib/ssz_ex/ssz_ex.ex @@ -62,12 +62,17 @@ defmodule SszEx do @spec encode(struct()) :: {:ok, binary()} | {:error, Error.t()} - def encode(%name{} = value), do: encode(value, name) + def encode(%name{} = value), do: encode(value, name) |> Error.add_trace("#{name}") @spec encode(any(), schema()) :: {:ok, binary()} | {:error, Error.t()} def encode(value, schema), do: Encode.encode(value, schema) + @spec decode(binary(), schema()) :: + {:ok, any()} | {:error, Error.t()} + def decode(value, module) when is_atom(module), + do: Decode.decode(value, module) |> Error.add_trace("#{module}") + @spec decode(binary(), schema()) :: {:ok, any()} | {:error, Error.t()} def decode(value, schema), do: Decode.decode(value, schema) @@ -78,6 +83,10 @@ defmodule SszEx do @spec hash_tree_root!(any, any) :: Types.root() def hash_tree_root!(value, schema), do: Merkleization.hash_tree_root!(value, schema) + @spec hash_tree_root(struct()) :: {:ok, Types.root()} | {:error, Error.t()} + def hash_tree_root(%name{} = value), + do: hash_tree_root(value, name) |> Error.add_trace("#{name}") + @spec hash_tree_root(any, any) :: {:ok, Types.root()} | {:error, Error.t()} def hash_tree_root(value, schema), do: Merkleization.hash_tree_root(value, schema) diff --git a/lib/ssz_ex/utils.ex b/lib/ssz_ex/utils.ex index edb52f845..099bb7ad0 100644 --- a/lib/ssz_ex/utils.ex +++ b/lib/ssz_ex/utils.ex @@ -5,7 +5,6 @@ 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 @@ -115,9 +114,4 @@ 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 diff --git a/test/unit/ssz_ex_test.exs b/test/unit/ssz_ex_test.exs index c009ea604..19ef94283 100644 --- a/test/unit/ssz_ex_test.exs +++ b/test/unit/ssz_ex_test.exs @@ -18,6 +18,59 @@ defmodule Unit.SSZExTest do assert {:ok, deserialized} === SszEx.decode(serialized, schema) end + def build_broken_attester_slashing() do + checkpoint_source = %Types.Checkpoint{ + epoch: 3_776_037_760_046_644_755, + root: + <<29, 22, 191, 147, 188, 238, 162, 89, 147, 162, 202, 111, 169, 162, 84, 95, 194, 85, 54, + 172, 44, 74, 37, 128, 248, 21, 86, 246, 151, 54, 24, 54>> + } + + checkpoint_target = %Types.Checkpoint{ + epoch: 2_840_053_453_521_072_037, + root: + <<15, 174, 23, 120, 4, 9, 2, 116, 67, 73, 254, 53, 197, 3, 191, 166, 104, 34, 121, 2, 57, + 69, 75, 69, 254, 237, 132, 68, 254, 49, 127, 175>> + } + + attestation_data = %Types.AttestationData{ + slot: 5_057_010_135_270_197_978, + index: 6_920_931_864_607_509_210, + beacon_block_root: + <<31, 38, 101, 174, 248, 168, 116, 226, 15, 39, 218, 148, 42, 8, 80, 80, 241, 149, 162, + 32, 176, 208, 120, 120, 89, 123, 136, 115, 154, 28, 21, 174>>, + source: checkpoint_source, + target: checkpoint_target + } + + indexed_attestation_1 = %Types.IndexedAttestation{ + attesting_indices: [15_833_676_831_095_072_535, 7_978_643_446_947_046_229], + data: attestation_data, + signature: + <<46, 244, 83, 164, 182, 222, 218, 247, 8, 186, 138, 100, 5, 96, 34, 117, 134, 123, 219, + 188, 181, 11, 209, 57, 207, 24, 249, 42, 74, 27, 228, 97, 73, 46, 219, 202, 122, 149, + 135, 30, 91, 126, 180, 69, 129, 170, 147, 142, 242, 27, 233, 63, 242, 7, 144, 8, 192, + 165, 194, 220, 77, 247, 128, 107, 41, 199, 166, 59, 34, 160, 222, 114, 250, 250, 3, 130, + 145, 8, 45, 65, 13, 82, 44, 80, 30, 181, 239, 54, 152, 237, 244, 72, 231, 179, 239, 22>> + } + + broken_attestation = %Types.IndexedAttestation{ + attesting_indices: List.duplicate(0, 3000), + data: attestation_data, + signature: + <<46, 244, 83, 164, 182, 222, 218, 247, 8, 186, 138, 100, 5, 96, 34, 117, 134, 123, 219, + 188, 181, 11, 209, 57, 207, 24, 249, 42, 74, 27, 228, 97, 73, 46, 219, 202, 122, 149, + 135, 30, 91, 126, 180, 69, 129, 170, 147, 142, 242, 27, 233, 63, 242, 7, 144, 8, 192, + 165, 194, 220, 77, 247, 128, 107, 41, 199, 166, 59, 34, 160, 222, 114, 250, 250, 3, 130, + 145, 8, 45, 65, 13, 82, 44, 80, 30, 181, 239, 54, 152, 237, 244, 72, 231, 179, 239, 22>> + } + + %Types.AttesterSlashing{ + attestation_1: indexed_attestation_1, + attestation_2: broken_attestation + } + end + test "packing a list of uints" do list_1 = [1, 2, 3, 4, 5] @@ -764,7 +817,7 @@ defmodule Unit.SSZExTest do assert error == "#{result}" end - test "stacktrace in hash_tree_root with invalid logs_bloom" do + test "hash_tree_root with invalid logs_bloom" do execution_payload = %ExecutionPayload{ parent_hash: @default_hash, fee_recipient: <<0::size(20 * 8)>>, @@ -788,7 +841,34 @@ defmodule Unit.SSZExTest do {:error, error} = SszEx.hash_tree_root(execution_payload, ExecutionPayload) assert "#{error}" == - "Invalid binary length while merkleizing byte_vector.\nExpected size: 256.\nFound: 3\nStacktrace: logs_bloom\nElixir.Types.ExecutionPayload" + "Invalid binary length while merkleizing byte_vector.\nExpected size: 256.\nFound: 3\nStacktrace: logs_bloom" + end + + test "stacktrace in hash_tree_root with invalid logs_bloom" do + execution_payload = %ExecutionPayload{ + parent_hash: @default_hash, + fee_recipient: <<0::size(20 * 8)>>, + state_root: @default_root, + receipts_root: @default_root, + logs_bloom: <<0, 0, 0>>, + prev_randao: <<0::size(32 * 8)>>, + block_number: 0, + gas_limit: 0, + gas_used: 0, + timestamp: 0, + extra_data: <<>>, + base_fee_per_gas: 0, + block_hash: @default_hash, + transactions: [], + withdrawals: [], + blob_gas_used: 0, + excess_blob_gas: 0 + } + + {:error, error} = SszEx.hash_tree_root(execution_payload) + + assert "#{error}" == + "Invalid binary length while merkleizing byte_vector.\nExpected size: 256.\nFound: 3\nStacktrace: Elixir.Types.ExecutionPayload.logs_bloom" end test "stacktrace in encode with invalid sync_committee_bits" do @@ -800,6 +880,23 @@ defmodule Unit.SSZExTest do {:error, error} = SszEx.encode(sync_aggregate) assert "#{error}" == - "Invalid binary length while encoding BitVector. \nExpected: 512.\nFound: 2.\nStacktrace: sync_committee_bits\nElixir.Types.SyncAggregate" + "Invalid binary length while encoding BitVector. \nExpected: 512.\nFound: 2.\nStacktrace: Elixir.Types.SyncAggregate.sync_committee_bits" + end + + test "stacktrace encode nested container" do + attester_slashing = build_broken_attester_slashing() + + {:error, error} = SszEx.encode(attester_slashing) + + assert "#{error}" == + "Invalid binary length while encoding list of {:int, 64}.\nExpected max_size: 2048.\nFound: 3000\nStacktrace: Elixir.Types.AttesterSlashing.attestation_2.attesting_indices" + end + + test "stacktrace hash_tree_root nested container" do + attester_slashing = build_broken_attester_slashing() + {:error, error} = SszEx.hash_tree_root(attester_slashing) + + assert "Invalid binary length while merkleizing list of {:int, 64}.\nExpected max_size: 2048.\nFound: 3000\nStacktrace: Elixir.Types.AttesterSlashing.attestation_2.attesting_indices" = + "#{error}" end end From 3b166883fd50661d6d05ee8e9b08a01c7d7e4b4c Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Tue, 23 Apr 2024 11:44:53 -0300 Subject: [PATCH 05/10] Restore unnecessary change. --- lib/ssz_ex/encode.ex | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/ssz_ex/encode.ex b/lib/ssz_ex/encode.ex index e91813a6f..7e15efda1 100644 --- a/lib/ssz_ex/encode.ex +++ b/lib/ssz_ex/encode.ex @@ -41,9 +41,8 @@ defmodule SszEx.Encode do def encode(value, {:bitvector, size}) when is_bitvector(value), do: encode_bitvector(value, size) - def encode(container, module) when is_map(container) do - encode_container(container, module.schema()) - end + def encode(container, module) when is_map(container), + do: encode_container(container, module.schema()) defp encode_int(value, size) when is_integer(value), do: {:ok, <>} defp encode_bool(true), do: {:ok, "\x01"} From 5135f0668fb9b8ed898432b7043f8a041f72205a Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Tue, 23 Apr 2024 16:01:35 -0300 Subject: [PATCH 06/10] Remove type's prefixes --- lib/ssz_ex/error.ex | 11 +++++++++-- lib/ssz_ex/ssz_ex.ex | 6 +++--- test/unit/ssz_ex_test.exs | 8 ++++---- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/lib/ssz_ex/error.ex b/lib/ssz_ex/error.ex index 73185c379..c2c4d73aa 100644 --- a/lib/ssz_ex/error.ex +++ b/lib/ssz_ex/error.ex @@ -18,12 +18,19 @@ defmodule SszEx.Error do %Error{message: message, stacktrace: [new_trace]} end + def add_trace(%Error{message: message, stacktrace: stacktrace}, value) when is_struct(value) do + new_trace = + value.__struct__ |> Module.split() |> List.last() + + %Error{message: message, stacktrace: [new_trace | stacktrace]} + end + def add_trace(%Error{message: message, stacktrace: stacktrace}, new_trace) do %Error{message: message, stacktrace: [new_trace | stacktrace]} end - def add_trace({:error, %Error{} = error}, module), - do: {:error, Error.add_trace(error, module)} + def add_trace({:error, %Error{} = error}, new_trace), + do: {:error, Error.add_trace(error, new_trace)} def add_trace(value, _module), do: value diff --git a/lib/ssz_ex/ssz_ex.ex b/lib/ssz_ex/ssz_ex.ex index 317c81124..2e3810c5f 100644 --- a/lib/ssz_ex/ssz_ex.ex +++ b/lib/ssz_ex/ssz_ex.ex @@ -62,7 +62,7 @@ defmodule SszEx do @spec encode(struct()) :: {:ok, binary()} | {:error, Error.t()} - def encode(%name{} = value), do: encode(value, name) |> Error.add_trace("#{name}") + def encode(%name{} = value), do: encode(value, name) |> Error.add_trace(value) @spec encode(any(), schema()) :: {:ok, binary()} | {:error, Error.t()} @@ -71,7 +71,7 @@ defmodule SszEx do @spec decode(binary(), schema()) :: {:ok, any()} | {:error, Error.t()} def decode(value, module) when is_atom(module), - do: Decode.decode(value, module) |> Error.add_trace("#{module}") + do: Decode.decode(value, module) |> Error.add_trace(module) @spec decode(binary(), schema()) :: {:ok, any()} | {:error, Error.t()} @@ -85,7 +85,7 @@ defmodule SszEx do @spec hash_tree_root(struct()) :: {:ok, Types.root()} | {:error, Error.t()} def hash_tree_root(%name{} = value), - do: hash_tree_root(value, name) |> Error.add_trace("#{name}") + do: hash_tree_root(value, name) |> Error.add_trace(value) @spec hash_tree_root(any, any) :: {:ok, Types.root()} | {:error, Error.t()} def hash_tree_root(value, schema), do: Merkleization.hash_tree_root(value, schema) diff --git a/test/unit/ssz_ex_test.exs b/test/unit/ssz_ex_test.exs index 19ef94283..d1f7c6b19 100644 --- a/test/unit/ssz_ex_test.exs +++ b/test/unit/ssz_ex_test.exs @@ -868,7 +868,7 @@ defmodule Unit.SSZExTest do {:error, error} = SszEx.hash_tree_root(execution_payload) assert "#{error}" == - "Invalid binary length while merkleizing byte_vector.\nExpected size: 256.\nFound: 3\nStacktrace: Elixir.Types.ExecutionPayload.logs_bloom" + "Invalid binary length while merkleizing byte_vector.\nExpected size: 256.\nFound: 3\nStacktrace: ExecutionPayload.logs_bloom" end test "stacktrace in encode with invalid sync_committee_bits" do @@ -880,7 +880,7 @@ defmodule Unit.SSZExTest do {:error, error} = SszEx.encode(sync_aggregate) assert "#{error}" == - "Invalid binary length while encoding BitVector. \nExpected: 512.\nFound: 2.\nStacktrace: Elixir.Types.SyncAggregate.sync_committee_bits" + "Invalid binary length while encoding BitVector. \nExpected: 512.\nFound: 2.\nStacktrace: SyncAggregate.sync_committee_bits" end test "stacktrace encode nested container" do @@ -889,14 +889,14 @@ defmodule Unit.SSZExTest do {:error, error} = SszEx.encode(attester_slashing) assert "#{error}" == - "Invalid binary length while encoding list of {:int, 64}.\nExpected max_size: 2048.\nFound: 3000\nStacktrace: Elixir.Types.AttesterSlashing.attestation_2.attesting_indices" + "Invalid binary length while encoding list of {:int, 64}.\nExpected max_size: 2048.\nFound: 3000\nStacktrace: AttesterSlashing.attestation_2.attesting_indices" end test "stacktrace hash_tree_root nested container" do attester_slashing = build_broken_attester_slashing() {:error, error} = SszEx.hash_tree_root(attester_slashing) - assert "Invalid binary length while merkleizing list of {:int, 64}.\nExpected max_size: 2048.\nFound: 3000\nStacktrace: Elixir.Types.AttesterSlashing.attestation_2.attesting_indices" = + assert "Invalid binary length while merkleizing list of {:int, 64}.\nExpected max_size: 2048.\nFound: 3000\nStacktrace: AttesterSlashing.attestation_2.attesting_indices" = "#{error}" end end From 6cedfdf10b47301e01d3d19783af3dc20eee5682 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 24 Apr 2024 11:44:57 -0300 Subject: [PATCH 07/10] refactor: remove module prefixes in decode --- lib/ssz_ex/error.ex | 21 +++++++++++++++------ lib/ssz_ex/ssz_ex.ex | 6 +++--- test/unit/ssz_ex_test.exs | 4 ++-- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/lib/ssz_ex/error.ex b/lib/ssz_ex/error.ex index c2c4d73aa..34acf16b4 100644 --- a/lib/ssz_ex/error.ex +++ b/lib/ssz_ex/error.ex @@ -3,10 +3,10 @@ defmodule SszEx.Error do Error messages for SszEx domain. """ alias SszEx.Error - defstruct [:message, :stacktrace] + defstruct [:message, stacktrace: []] @type t :: %__MODULE__{message: String.t(), stacktrace: list()} - def format(%Error{message: message, stacktrace: nil}), do: "#{message}" + def format(%Error{message: message, stacktrace: []}), do: "#{message}" def format(%Error{message: message, stacktrace: stacktrace}) do "#{message}" @@ -14,17 +14,26 @@ defmodule SszEx.Error do "#{message}Stacktrace: #{formatted_stacktrace}" end - def add_trace(%Error{message: message, stacktrace: nil}, new_trace) do - %Error{message: message, stacktrace: [new_trace]} + def add_container(%Error{message: message, stacktrace: stacktrace}, value) + when is_struct(value) do + new_trace = + value.__struct__ |> Module.split() |> List.last() + + %Error{message: message, stacktrace: [new_trace | stacktrace]} end - def add_trace(%Error{message: message, stacktrace: stacktrace}, value) when is_struct(value) do + def add_container(%Error{message: message, stacktrace: stacktrace}, value) do new_trace = - value.__struct__ |> Module.split() |> List.last() + value |> Module.split() |> List.last() %Error{message: message, stacktrace: [new_trace | stacktrace]} end + def add_container({:error, %Error{} = error}, new_trace), + do: {:error, Error.add_container(error, new_trace)} + + def add_container(value, _module), do: value + def add_trace(%Error{message: message, stacktrace: stacktrace}, new_trace) do %Error{message: message, stacktrace: [new_trace | stacktrace]} end diff --git a/lib/ssz_ex/ssz_ex.ex b/lib/ssz_ex/ssz_ex.ex index 2e3810c5f..c2bdb7df6 100644 --- a/lib/ssz_ex/ssz_ex.ex +++ b/lib/ssz_ex/ssz_ex.ex @@ -62,7 +62,7 @@ defmodule SszEx do @spec encode(struct()) :: {:ok, binary()} | {:error, Error.t()} - def encode(%name{} = value), do: encode(value, name) |> Error.add_trace(value) + def encode(%name{} = value), do: encode(value, name) |> Error.add_container(value) @spec encode(any(), schema()) :: {:ok, binary()} | {:error, Error.t()} @@ -71,7 +71,7 @@ defmodule SszEx do @spec decode(binary(), schema()) :: {:ok, any()} | {:error, Error.t()} def decode(value, module) when is_atom(module), - do: Decode.decode(value, module) |> Error.add_trace(module) + do: Decode.decode(value, module) |> Error.add_container(module) @spec decode(binary(), schema()) :: {:ok, any()} | {:error, Error.t()} @@ -85,7 +85,7 @@ defmodule SszEx do @spec hash_tree_root(struct()) :: {:ok, Types.root()} | {:error, Error.t()} def hash_tree_root(%name{} = value), - do: hash_tree_root(value, name) |> Error.add_trace(value) + do: hash_tree_root(value, name) |> Error.add_container(value) @spec hash_tree_root(any, any) :: {:ok, Types.root()} | {:error, Error.t()} def hash_tree_root(value, schema), do: Merkleization.hash_tree_root(value, schema) diff --git a/test/unit/ssz_ex_test.exs b/test/unit/ssz_ex_test.exs index d1f7c6b19..30fafa071 100644 --- a/test/unit/ssz_ex_test.exs +++ b/test/unit/ssz_ex_test.exs @@ -794,7 +794,7 @@ defmodule Unit.SSZExTest do {: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" + "Invalid binary length while decoding Elixir.Types.Checkpoint. \nExpected 40. \nFound 3.\nStacktrace: Checkpoint" end test "decode longer checkpoint" do @@ -804,7 +804,7 @@ defmodule Unit.SSZExTest do {: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" + "Invalid binary length while decoding Elixir.Types.Checkpoint. \nExpected 40. \nFound 41.\nStacktrace: Checkpoint" end test "hash tree root of list exceeding max size" do From ac80861eb65cd922172311225b18be86e794d549 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 24 Apr 2024 12:44:08 -0300 Subject: [PATCH 08/10] fix: handle decode errors with schemas --- lib/ssz_ex/error.ex | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/ssz_ex/error.ex b/lib/ssz_ex/error.ex index 34acf16b4..1db14ebda 100644 --- a/lib/ssz_ex/error.ex +++ b/lib/ssz_ex/error.ex @@ -22,13 +22,18 @@ defmodule SszEx.Error do %Error{message: message, stacktrace: [new_trace | stacktrace]} end - def add_container(%Error{message: message, stacktrace: stacktrace}, value) do + def add_container(%Error{message: message, stacktrace: stacktrace}, value) + when is_atom(value) do new_trace = value |> Module.split() |> List.last() %Error{message: message, stacktrace: [new_trace | stacktrace]} end + def add_container(%Error{message: message, stacktrace: stacktrace}, new_trace) do + %Error{message: message, stacktrace: [new_trace | stacktrace]} + end + def add_container({:error, %Error{} = error}, new_trace), do: {:error, Error.add_container(error, new_trace)} From f6e199231650e0a534ae986aad3bce2bb2f53443 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 24 Apr 2024 14:44:00 -0300 Subject: [PATCH 09/10] fix: decode spec-tests --- lib/ssz_ex/error.ex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/ssz_ex/error.ex b/lib/ssz_ex/error.ex index 1db14ebda..6e43c67b6 100644 --- a/lib/ssz_ex/error.ex +++ b/lib/ssz_ex/error.ex @@ -9,7 +9,6 @@ defmodule SszEx.Error do def format(%Error{message: message, stacktrace: []}), do: "#{message}" def format(%Error{message: message, stacktrace: stacktrace}) do - "#{message}" formatted_stacktrace = stacktrace |> Enum.join(".") "#{message}Stacktrace: #{formatted_stacktrace}" end @@ -22,6 +21,8 @@ defmodule SszEx.Error do %Error{message: message, stacktrace: [new_trace | stacktrace]} end + def add_container(%Error{} = error, :bool), do: error + def add_container(%Error{message: message, stacktrace: stacktrace}, value) when is_atom(value) do new_trace = From 626cb97c9cd505696394460755bb3ce67a37fd45 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 24 Apr 2024 14:49:43 -0300 Subject: [PATCH 10/10] refactor: remove \n from each message --- lib/ssz_ex/decode.ex | 22 +++++++++++----------- lib/ssz_ex/encode.ex | 8 ++++---- lib/ssz_ex/error.ex | 4 ++-- lib/ssz_ex/merkleization.ex | 6 +++--- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/ssz_ex/decode.ex b/lib/ssz_ex/decode.ex index 2708db86d..0a4084fba 100644 --- a/lib/ssz_ex/decode.ex +++ b/lib/ssz_ex/decode.ex @@ -55,7 +55,7 @@ defmodule SszEx.Decode do {:error, %Error{ message: - "Invalid binary length while decoding uint.\nExpected size: #{size}.\nFound:#{bit_size(binary)}\n" + "Invalid binary length while decoding uint.\nExpected size: #{size}.\nFound:#{bit_size(binary)}" }} defp decode_uint(binary, size) do @@ -68,7 +68,7 @@ defmodule SszEx.Decode do {:error, %Error{ message: - "Invalid binary length while decoding bool.\nExpected size: 1.\nFound:#{byte_size(binary)}\n" + "Invalid binary length while decoding bool.\nExpected size: 1.\nFound:#{byte_size(binary)}" }} defp decode_bool("\x01"), do: {:ok, true} @@ -86,7 +86,7 @@ defmodule SszEx.Decode do do: {:error, %Error{ - message: "Invalid binary value while decoding BitList.\nEmpty binary found.\n" + message: "Invalid binary value while decoding BitList.\nEmpty binary found." }} defp decode_bitlist(bit_list, max_size) do @@ -98,14 +98,14 @@ defmodule SszEx.Decode do match?(<<_::binary-size(num_bytes - 1), 0>>, bit_list) -> {:error, %Error{ - message: "Invalid binary value while decoding BitList.\nMissing sentinel bit.\n" + message: "Invalid binary value while decoding BitList.\nMissing sentinel bit." }} len > max_size -> {:error, %Error{ message: - "Invalid binary length while decoding BitList. \nExpected max_size: #{max_size}. Found: #{len}.\n" + "Invalid binary length while decoding BitList. \nExpected max_size: #{max_size}. Found: #{len}." }} true -> @@ -125,7 +125,7 @@ defmodule SszEx.Decode do _ -> {:error, %Error{ - message: "Invalid binary length while decoding BitVector. \nExpected size: #{size}.\n" + message: "Invalid binary length while decoding BitVector. \nExpected size: #{size}." }} end end @@ -162,7 +162,7 @@ defmodule SszEx.Decode do {:error, %Error{ message: - "Invalid binary length while decoding list of #{inspect(inner_type)}.\nExpected max_size: #{max_size}.\nFound: #{byte_length}\n" + "Invalid binary length while decoding list of #{inspect(inner_type)}.\nExpected max_size: #{max_size}.\nFound: #{byte_length}" }} defp check_valid_fixed_list_size(_byte_length, _inner_type, _inner_type_size, _max_size), @@ -174,7 +174,7 @@ defmodule SszEx.Decode do {:error, %Error{ message: - "Invalid binary length while decoding vector of #{inspect(inner_type)}.\nExpected size #{inner_type_size * size} bytes.\nFound: #{byte_length}.\n" + "Invalid binary length while decoding vector of #{inspect(inner_type)}.\nExpected size #{inner_type_size * size} bytes.\nFound: #{byte_length}." }} defp check_valid_vector_size(_byte_length, _inner_type, _inner_type_size, _size), @@ -310,7 +310,7 @@ defmodule SszEx.Decode do {:error, %Error{ message: - "Invalid binary length while decoding #{module}. \nExpected #{expected_length}. \nFound #{size}.\n" + "Invalid binary length while decoding #{module}. \nExpected #{expected_length}. \nFound #{size}." }} defp check_fixed_container_size(_module, _expected_length, _size), @@ -322,7 +322,7 @@ defmodule SszEx.Decode do {:error, %Error{ message: - "First offset does not point to the first variable byte.\nExpected index: #{items_index}.\nOffset: #{offset}. " + "First offset does not point to the first variable byte.\nExpected index: #{items_index}.\nOffset: #{offset}." }} defp check_first_offset(_offsets, _items_index, _binary_size), @@ -446,7 +446,7 @@ defmodule SszEx.Decode do {:error, %Error{ message: - "Invalid binary length while decoding collection. \nInner type size: #{chunk_size} bytes. Binary length: #{byte_size(binary)} bytes.\n" + "Invalid binary length while decoding collection. \nInner type size: #{chunk_size} bytes. Binary length: #{byte_size(binary)} bytes." }} | results ] diff --git a/lib/ssz_ex/encode.ex b/lib/ssz_ex/encode.ex index 7e15efda1..9c63aea03 100644 --- a/lib/ssz_ex/encode.ex +++ b/lib/ssz_ex/encode.ex @@ -55,7 +55,7 @@ defmodule SszEx.Encode do {:error, %Error{ message: - "Invalid binary length while encoding list of #{inspect(inner_type)}.\nExpected max_size: #{max_size}.\nFound: #{size}\n" + "Invalid binary length while encoding list of #{inspect(inner_type)}.\nExpected max_size: #{max_size}.\nFound: #{size}" }} else list @@ -71,7 +71,7 @@ defmodule SszEx.Encode do {:error, %Error{ message: - "Invalid binary length while encoding BitList.\nExpected max_size: #{max_size}. Found: #{len}.\n" + "Invalid binary length while encoding BitList.\nExpected max_size: #{max_size}. Found: #{len}." }} else {:ok, BitList.to_bytes(bit_list)} @@ -83,7 +83,7 @@ defmodule SszEx.Encode do {:error, %Error{ message: - "Invalid binary length while encoding BitVector. \nExpected: #{size}.\nFound: #{bit_vector_size(bit_vector)}.\n" + "Invalid binary length while encoding BitVector. \nExpected: #{size}.\nFound: #{bit_vector_size(bit_vector)}." }} defp encode_bitvector(bit_vector, _size), @@ -96,7 +96,7 @@ defmodule SszEx.Encode do {:error, %Error{ message: - "Invalid binary length while encoding list of #{inspect(inner_type)}.\nExpected max_size: #{max_size}.\nFound: #{size}\n" + "Invalid binary length while encoding list of #{inspect(inner_type)}.\nExpected max_size: #{max_size}.\nFound: #{size}" }} else fixed_lengths = @bytes_per_length_offset * length(list) diff --git a/lib/ssz_ex/error.ex b/lib/ssz_ex/error.ex index 6e43c67b6..dbbc14780 100644 --- a/lib/ssz_ex/error.ex +++ b/lib/ssz_ex/error.ex @@ -6,11 +6,11 @@ defmodule SszEx.Error do defstruct [:message, stacktrace: []] @type t :: %__MODULE__{message: String.t(), stacktrace: list()} - def format(%Error{message: message, stacktrace: []}), do: "#{message}" + def format(%Error{message: message, stacktrace: []}), do: "#{message}\n" def format(%Error{message: message, stacktrace: stacktrace}) do formatted_stacktrace = stacktrace |> Enum.join(".") - "#{message}Stacktrace: #{formatted_stacktrace}" + "#{message}\nStacktrace: #{formatted_stacktrace}" end def add_container(%Error{message: message, stacktrace: stacktrace}, value) diff --git a/lib/ssz_ex/merkleization.ex b/lib/ssz_ex/merkleization.ex index 7429cd10d..c4d3f512d 100644 --- a/lib/ssz_ex/merkleization.ex +++ b/lib/ssz_ex/merkleization.ex @@ -44,7 +44,7 @@ defmodule SszEx.Merkleization do {:error, %Error{ message: - "Invalid binary length while merkleizing byte_vector.\nExpected size: #{size}.\nFound: #{byte_size(value)}\n" + "Invalid binary length while merkleizing byte_vector.\nExpected size: #{size}.\nFound: #{byte_size(value)}" }} def hash_tree_root(value, {:byte_vector, _size}) do @@ -81,7 +81,7 @@ defmodule SszEx.Merkleization do {:error, %Error{ message: - "Invalid binary length while merkleizing list of #{inspect(type)}.\nExpected max_size: #{max_size}.\nFound: #{len}\n" + "Invalid binary length while merkleizing list of #{inspect(type)}.\nExpected max_size: #{max_size}.\nFound: #{len}" }} Utils.basic_type?(type) -> @@ -99,7 +99,7 @@ defmodule SszEx.Merkleization do {:error, %Error{ message: - "Invalid binary length while merkleizing vector of #{inspect(inner_type)}.\nExpected size: #{size}.\nFound: #{length(vector)}\n" + "Invalid binary length while merkleizing vector of #{inspect(inner_type)}.\nExpected size: #{size}.\nFound: #{length(vector)}" }} def hash_tree_root(vector, {:vector, type, _size} = schema) do