diff --git a/.spectest_version b/.spectest_version index 18fa8e74f..0a7905b0e 100644 --- a/.spectest_version +++ b/.spectest_version @@ -1 +1 @@ -v1.3.0 +v1.4.0-alpha.0 diff --git a/lib/lambda_ethereum_consensus/state_transition/operations.ex b/lib/lambda_ethereum_consensus/state_transition/operations.ex index acf8e5a72..f45788fcb 100644 --- a/lib/lambda_ethereum_consensus/state_transition/operations.ex +++ b/lib/lambda_ethereum_consensus/state_transition/operations.ex @@ -3,7 +3,6 @@ defmodule LambdaEthereumConsensus.StateTransition.Operations do This module contains functions for handling state transition """ - alias LambdaEthereumConsensus.Engine alias LambdaEthereumConsensus.StateTransition.{Accessors, Misc, Mutators, Predicates} alias LambdaEthereumConsensus.Utils.BitVector alias SszTypes.BeaconBlockBody @@ -242,14 +241,13 @@ defmodule LambdaEthereumConsensus.StateTransition.Operations do @doc """ State transition function managing the processing & validation of the `ExecutionPayload` """ - @spec process_execution_payload(BeaconState.t(), ExecutionPayload.t(), boolean()) :: + @spec process_execution_payload(BeaconState.t(), BeaconBlockBody.t(), fun()) :: {:ok, BeaconState.t()} | {:error, String.t()} - - def process_execution_payload(_state, _payload, false) do - {:error, "Invalid execution payload"} - end - - def process_execution_payload(state, payload, _execution_valid) do + def process_execution_payload( + state, + %BeaconBlockBody{execution_payload: payload}, + verify_and_notify_new_payload + ) do cond do # Verify consistency of the parent hash with respect to the previous execution payload header SszTypes.BeaconState.is_merge_transition_complete(state) and @@ -265,7 +263,7 @@ defmodule LambdaEthereumConsensus.StateTransition.Operations do {:error, "Timestamp verification failed"} # Verify the execution payload is valid if not mocked - Engine.Execution.verify_and_notify_new_payload(payload) != {:ok, true} -> + verify_and_notify_new_payload.(payload) != {:ok, true} -> {:error, "Invalid execution payload"} # Cache execution payload header diff --git a/lib/lambda_ethereum_consensus/state_transition/state_transition.ex b/lib/lambda_ethereum_consensus/state_transition/state_transition.ex index 2b1044304..81fb02f04 100644 --- a/lib/lambda_ethereum_consensus/state_transition/state_transition.ex +++ b/lib/lambda_ethereum_consensus/state_transition/state_transition.ex @@ -3,6 +3,7 @@ defmodule LambdaEthereumConsensus.StateTransition do State transition logic. """ + alias LambdaEthereumConsensus.Engine.Execution alias LambdaEthereumConsensus.StateTransition alias LambdaEthereumConsensus.StateTransition.{EpochProcessing, Operations} alias SszTypes.{BeaconBlockHeader, BeaconState, SignedBeaconBlock} @@ -117,10 +118,12 @@ defmodule LambdaEthereumConsensus.StateTransition do # TODO: uncomment when implemented def process_block(state, block) do + verify_and_notify_new_payload = &Execution.verify_and_notify_new_payload/1 + {:ok, state} |> map(&Operations.process_block_header(&1, block)) |> map(&Operations.process_withdrawals(&1, block.body.execution_payload)) - # |> map(&Operations.process_execution_payload(&1, block.body, EXECUTION_ENGINE)) + |> map(&Operations.process_execution_payload(&1, block.body, verify_and_notify_new_payload)) |> map(&Operations.process_randao(&1, block.body)) |> map(&Operations.process_eth1_data(&1, block.body)) # |> map(&Operations.process_operations(&1, block.body)) diff --git a/lib/spec/runners/operations.ex b/lib/spec/runners/operations.ex index c962e5f12..cfcf29ab7 100644 --- a/lib/spec/runners/operations.ex +++ b/lib/spec/runners/operations.ex @@ -2,9 +2,12 @@ defmodule OperationsTestRunner do @moduledoc """ Runner for Operations test cases. See: https://github.com/ethereum/consensus-specs/tree/dev/tests/formats/operations """ + alias LambdaEthereumConsensus.StateTransition.Operations alias LambdaEthereumConsensus.Utils.Diff + alias SszTypes.BeaconBlockBody + use ExUnit.CaseTemplate use TestRunner @@ -17,7 +20,7 @@ defmodule OperationsTestRunner do "proposer_slashing" => "ProposerSlashing", "voluntary_exit" => "SignedVoluntaryExit", "sync_aggregate" => "SyncAggregate", - "execution_payload" => "ExecutionPayload", + "execution_payload" => "BeaconBlockBody", "withdrawals" => "ExecutionPayload", "bls_to_execution_change" => "SignedBLSToExecutionChange" # "deposit_receipt" => "DepositReceipt" Not yet implemented @@ -32,7 +35,7 @@ defmodule OperationsTestRunner do "proposer_slashing" => "proposer_slashing", "voluntary_exit" => "voluntary_exit", "sync_aggregate" => "sync_aggregate", - "execution_payload" => "execution_payload", + "execution_payload" => "body", "withdrawals" => "execution_payload", "bls_to_execution_change" => "address_change" # "deposit_receipt" => "deposit_receipt" Not yet implemented @@ -53,13 +56,9 @@ defmodule OperationsTestRunner do # "bls_to_execution_change" ] - @disabled_cases [ - "bad_parent_hash_first_payload" - ] - @impl TestRunner - def skip?(%SpecTestCase{fork: "capella", handler: handler, case: testcase}) do - Enum.member?(@disabled_handlers, handler) or Enum.member?(@disabled_cases, testcase) + def skip?(%SpecTestCase{fork: "capella", handler: handler}) do + Enum.member?(@disabled_handlers, handler) end @impl TestRunner @@ -93,19 +92,21 @@ defmodule OperationsTestRunner do handle_case(testcase.handler, pre, operation, post, case_dir) end - defp handle_case("execution_payload", pre, operation, post, case_dir) do + defp handle_case("execution_payload", pre, %BeaconBlockBody{} = body, post, case_dir) do %{execution_valid: execution_valid} = YamlElixir.read_from_file!(case_dir <> "/execution.yaml") |> SpecTestUtils.sanitize_yaml() - result = Operations.process_execution_payload(pre, operation, execution_valid) + result = + Operations.process_execution_payload(pre, body, fn _payload -> {:ok, execution_valid} end) - case result do - {:ok, state} -> - assert Diff.diff(state, post) == :unchanged + case post do + nil -> + assert {:error, _error_msg} = result - {:error, error} -> - assert post == nil, "Execution payload failed, error: #{error}" + post -> + assert {:ok, state} = result + assert Diff.diff(state, post) == :unchanged end end