Skip to content

Commit 22a782e

Browse files
authored
feat: enable ssz static deposit data container using new ssz_ex library (#740)
1 parent 83e1772 commit 22a782e

File tree

3 files changed

+80
-67
lines changed

3 files changed

+80
-67
lines changed

test/spec/runners/ssz_generic.ex

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ defmodule SszGenericTestRunner do
33
Runner for SSZ general test cases. `run_test_case/1` is the main entrypoint.
44
"""
55
alias LambdaEthereumConsensus.SszEx
6-
alias LambdaEthereumConsensus.Utils.BitList
7-
alias LambdaEthereumConsensus.Utils.BitVector
86
use ExUnit.CaseTemplate
97
use TestRunner
108

@@ -54,7 +52,7 @@ defmodule SszGenericTestRunner do
5452
real_deserialized =
5553
YamlElixir.read_from_file!(case_dir <> "/value.yaml")
5654
|> SpecTestUtils.sanitize_yaml()
57-
|> sanitize(schema)
55+
|> SpecTestUtils.sanitize_ssz(schema)
5856

5957
%{root: expected_root} =
6058
YamlElixir.read_from_file!(case_dir <> "/meta.yaml")
@@ -118,35 +116,4 @@ defmodule SszGenericTestRunner do
118116
[size | _] = String.split(rest, "_")
119117
{:bitvector, String.to_integer(size)}
120118
end
121-
122-
def sanitize(container, module) when is_map(container) do
123-
schema = module.schema() |> Map.new()
124-
125-
container
126-
|> Enum.map(fn {k, v} -> {k, sanitize(v, Map.fetch!(schema, k))} end)
127-
|> then(&struct!(module, &1))
128-
end
129-
130-
def sanitize(vector_elements, {:vector, :bool, _size} = _schema), do: vector_elements
131-
132-
def sanitize(vector_elements, {:vector, module, _size} = _schema) when is_atom(module),
133-
do:
134-
vector_elements
135-
|> Enum.map(&struct!(module, &1))
136-
137-
def sanitize(bitlist, {:bitlist, _size} = _schema), do: elem(BitList.new(bitlist), 0)
138-
def sanitize(bitvector, {:bitvector, size} = _schema), do: BitVector.new(bitvector, size)
139-
140-
def sanitize(bytelist, {:list, {:int, 8}, _size} = _schema)
141-
when is_integer(bytelist) and bytelist > 0,
142-
do: :binary.encode_unsigned(bytelist) |> :binary.bin_to_list()
143-
144-
def sanitize(bytelist, {:list, {:int, 8}, _size} = _schema)
145-
when is_integer(bytelist) and bytelist == 0,
146-
do: []
147-
148-
def sanitize(bytelist, {:list, {:int, 8}, _size} = _schema),
149-
do: :binary.bin_to_list(bytelist)
150-
151-
def sanitize(other, _schema), do: other
152119
end

test/spec/runners/ssz_static.ex

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,60 @@ defmodule SszStaticTestRunner do
22
@moduledoc """
33
Runner for SSZ test cases. `run_test_case/1` is the main entrypoint.
44
"""
5+
alias LambdaEthereumConsensus.SszEx
56
alias LambdaEthereumConsensus.Utils.Diff
67

78
use ExUnit.CaseTemplate
89
use TestRunner
9-
import Aja
1010

1111
@disabled [
12-
"ContributionAndProof",
13-
"Eth1Block",
12+
# "DepositData",
13+
# "DepositMessage",
14+
# "Eth1Data",
15+
# "ProposerSlashing",
16+
# "SignedBeaconBlockHeader",
17+
# "SignedVoluntaryExit",
18+
# "Validator",
19+
# "VoluntaryExit",
20+
# "Attestation",
21+
# "AttestationData",
22+
# "BLSToExecutionChange",
23+
# "BeaconBlockHeader",
24+
# "Checkpoint",
25+
# "Deposit",
26+
# "SignedBLSToExecutionChange",
27+
# "SigningData",
28+
# "SyncCommittee",
29+
# "Withdrawal",
30+
# "AttesterSlashing",
31+
# "HistoricalSummary",
32+
# "PendingAttestation",
33+
# "Fork",
34+
# "ForkData",
35+
# "HistoricalBatch",
36+
# "IndexedAttestation",
37+
"ExecutionPayload",
38+
"ExecutionPayloadHeader",
39+
"SignedBeaconBlock",
40+
"SyncAggregate",
41+
"AggregateAndProof",
42+
"BeaconBlock",
43+
"BeaconBlockBody",
44+
"BeaconState",
45+
"SignedAggregateAndProof",
46+
# -- not defined yet
1447
"LightClientBootstrap",
15-
"LightClientFinalityUpdate",
16-
"LightClientHeader",
1748
"LightClientOptimisticUpdate",
1849
"LightClientUpdate",
50+
"Eth1Block",
1951
"PowBlock",
2052
"SignedContributionAndProof",
53+
"SignedData",
2154
"SyncAggregatorSelectionData",
2255
"SyncCommitteeContribution",
56+
"ContributionAndProof",
57+
"LightClientFinalityUpdate",
58+
"LightClientHeader",
2359
"SyncCommitteeMessage"
2460
]
2561

@@ -40,46 +76,25 @@ defmodule SszStaticTestRunner do
4076
expected =
4177
YamlElixir.read_from_file!(case_dir <> "/value.yaml")
4278
|> SpecTestUtils.sanitize_yaml()
79+
|> SpecTestUtils.sanitize_ssz(schema)
4380

4481
%{"root" => expected_root} = YamlElixir.read_from_file!(case_dir <> "/roots.yaml")
4582
expected_root = expected_root |> SpecTestUtils.sanitize_yaml()
4683

4784
assert_ssz(schema, decompressed, expected, expected_root)
4885
end
4986

50-
defp assert_ssz(schema, real_serialized, real_deserialized, expected_root) do
51-
{:ok, deserialized} = Ssz.from_ssz(real_serialized, schema)
52-
real_deserialized = to_struct_checked(deserialized, real_deserialized)
53-
87+
defp assert_ssz(schema, real_serialized, real_deserialized, _expected_root) do
88+
{:ok, deserialized} = SszEx.decode(real_serialized, schema)
5489
assert Diff.diff(deserialized, real_deserialized) == :unchanged
55-
56-
{:ok, serialized} = Ssz.to_ssz(real_deserialized)
90+
{:ok, serialized} = SszEx.encode(real_deserialized, schema)
5791
assert serialized == real_serialized
5892

59-
root = Ssz.hash_tree_root!(real_deserialized)
60-
assert root == expected_root
61-
end
62-
63-
defp to_struct_checked(actual, expected) when is_list(actual) and is_list(expected) do
64-
Stream.zip(actual, expected) |> Enum.map(fn {a, e} -> to_struct_checked(a, e) end)
65-
end
66-
67-
defp to_struct_checked(vec(_) = actual, vec(_) = expected) do
68-
actual
69-
|> Aja.Enum.to_list()
70-
|> to_struct_checked(Aja.Enum.to_list(expected))
71-
|> Aja.Vector.new()
72-
end
73-
74-
defp to_struct_checked(%name{} = actual, %{} = expected) do
75-
expected
76-
|> Stream.map(fn {k, v} -> {k, to_struct_checked(Map.get(actual, k), v)} end)
77-
|> Map.new()
78-
|> then(&struct!(name, &1))
93+
## TODO Enable when merklelization is enable
94+
# root = SszEx.hash_tree_root!(real_deserialized)
95+
# assert root == expected_root
7996
end
8097

81-
defp to_struct_checked(_actual, expected), do: expected
82-
8398
defp parse_type(%SpecTestCase{handler: handler}) do
8499
Module.concat(Types, handler)
85100
end

test/spec/utils.ex

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ defmodule SpecTestUtils do
33
Utilities for spec tests.
44
"""
55
alias LambdaEthereumConsensus.SszEx
6+
alias LambdaEthereumConsensus.Utils.BitList
7+
alias LambdaEthereumConsensus.Utils.BitVector
68

79
@vectors_dir Path.join(["test", "spec", "vectors", "tests"])
810
@vector_keys [
@@ -116,4 +118,33 @@ defmodule SpecTestUtils do
116118
name -> name
117119
end
118120
end
121+
122+
def sanitize_ssz(container, module) when is_map(container) do
123+
schema = module.schema() |> Map.new()
124+
125+
container
126+
|> Enum.map(fn {k, v} -> {k, sanitize_ssz(v, Map.fetch!(schema, k))} end)
127+
|> then(&struct!(module, &1))
128+
end
129+
130+
def sanitize_ssz(vector_elements, {:vector, :bool, _size} = _schema), do: vector_elements
131+
132+
def sanitize_ssz(vector_elements, {:vector, module, _size} = _schema) when is_atom(module),
133+
do: Enum.map(vector_elements, &struct!(module, &1))
134+
135+
def sanitize_ssz(bitlist, {:bitlist, _size} = _schema), do: elem(BitList.new(bitlist), 0)
136+
def sanitize_ssz(bitvector, {:bitvector, size} = _schema), do: BitVector.new(bitvector, size)
137+
138+
def sanitize_ssz(0, {:list, {:int, 8}, _size} = _schema), do: []
139+
140+
def sanitize_ssz(bytelist, {:list, {:int, 8}, _size} = _schema) when is_integer(bytelist),
141+
do: :binary.encode_unsigned(bytelist) |> :binary.bin_to_list()
142+
143+
@doc """
144+
this clause is called when an element of a container is a bytelist that is parsed as a binary and not as a list of bytes
145+
"""
146+
def sanitize_ssz(bytelist, {:list, {:int, 8}, _size} = _schema),
147+
do: :binary.bin_to_list(bytelist)
148+
149+
def sanitize_ssz(other, _schema), do: other
119150
end

0 commit comments

Comments
 (0)