Skip to content

Commit

Permalink
feat: merkle proof spec test (#496)
Browse files Browse the repository at this point in the history
  • Loading branch information
karasakalmt authored Dec 6, 2023
1 parent db881a5 commit 6e6f106
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 5 deletions.
13 changes: 8 additions & 5 deletions lib/lambda_ethereum_consensus/state_transition/predicates.ex
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,14 @@ defmodule LambdaEthereumConsensus.StateTransition.Predicates do
SszTypes.root()
) :: boolean
def is_valid_merkle_branch?(leaf, branch, depth, index, root) do
root ==
branch
|> Enum.take(depth)
|> Enum.with_index()
|> Enum.reduce(leaf, fn {v, i}, value -> hash_merkle_node(v, value, index, i) end)
root == generate_merkle_proof(leaf, branch, depth, index)
end

def generate_merkle_proof(leaf, branch, depth, index) do
branch
|> Enum.take(depth)
|> Enum.with_index()
|> Enum.reduce(leaf, fn {v, i}, value -> hash_merkle_node(v, value, index, i) end)
end

defp hash_merkle_node(value_1, value_2, index, i) do
Expand Down
52 changes: 52 additions & 0 deletions lib/spec/runners/light_client.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
defmodule LightClientTestRunner do
alias LambdaEthereumConsensus.StateTransition.Predicates
use ExUnit.CaseTemplate
use TestRunner

@moduledoc """
Runner for LightClient test cases. See: https://github.com/ethereum/consensus-specs/tree/dev/tests/formats/light_client
"""

# Remove handler from here once you implement the corresponding functions
@disabled_handlers [
# "single_merkle_proof",
"sync",
"update_ranking"
]

@impl TestRunner
def skip?(%SpecTestCase{} = testcase) do
Enum.member?(@disabled_handlers, testcase.handler)
end

@impl TestRunner
def run_test_case(%SpecTestCase{} = testcase) do
handle(testcase.handler, testcase)
end

defp handle("single_merkle_proof", testcase) do
case_dir = SpecTestCase.dir(testcase)

object_root =
SpecTestUtils.read_ssz_from_file!(
case_dir <> "/object.ssz_snappy",
String.to_existing_atom("Elixir.SszTypes." <> testcase.suite)
)
|> Ssz.hash_tree_root!()

%{leaf: leaf, leaf_index: leaf_index, branch: branch} =
YamlElixir.read_from_file!(case_dir <> "/proof.yaml")
|> SpecTestUtils.sanitize_yaml()

res =
Predicates.is_valid_merkle_branch?(
leaf,
branch,
Constants.deposit_contract_tree_depth() + 1,
leaf_index,
object_root
)

assert true == res
end
end

0 comments on commit 6e6f106

Please sign in to comment.