Skip to content

Commit

Permalink
Merge branch 'main' into sync-committee-message-production
Browse files Browse the repository at this point in the history
  • Loading branch information
rodrigo-o committed Aug 23, 2024
2 parents 3215928 + 9835380 commit 97e6b3a
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 36 deletions.
9 changes: 8 additions & 1 deletion lib/lambda_ethereum_consensus/validator/duties.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ defmodule LambdaEthereumConsensus.Validator.Duties do

@type attester_duty :: %{
attested?: boolean(),
# should_aggregate? is used to check if aggregation is needed for this attestation.
# and also to avoid double aggregation.
should_aggregate?: boolean(),
selection_proof: Bls.signature(),
signing_domain: Types.domain(),
Expand Down Expand Up @@ -58,7 +60,11 @@ defmodule LambdaEthereumConsensus.Validator.Duties do

for {epoch, slot} <- epochs_and_start_slots, reduce: duties_map do
duties_map ->
beacon = Validator.fetch_target_state_and_go_to_slot(slot, head_root)
beacon = Validator.fetch_target_state_and_go_to_slot(epoch, slot, head_root)
# If committees are not already calculated for the epoch, this is way faster than
# calculating them on the fly.
Accessors.maybe_prefetch_committees(beacon, epoch)

last_epoch = Map.keys(duties_map) |> Enum.max(fn -> 0 end)

{time_p, new_proposers} =
Expand Down Expand Up @@ -262,6 +268,7 @@ defmodule LambdaEthereumConsensus.Validator.Duties do
def attested(duty), do: Map.put(duty, :attested?, true)

@spec aggregated(attester_duty()) :: attester_duty()
# should_aggregate? is set to false to avoid double aggregation.
def aggregated(duty), do: Map.put(duty, :should_aggregate?, false)

@spec sync_committee_broadcasted(sync_committee_duty(), Types.slot()) :: sync_committee_duty()
Expand Down
28 changes: 5 additions & 23 deletions lib/lambda_ethereum_consensus/validator/validator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,10 @@ defmodule LambdaEthereumConsensus.Validator do

@spec new(Keystore.t(), Types.slot(), Types.root()) :: t()
def new(keystore, head_slot, head_root) do
beacon = fetch_target_state_and_go_to_slot(head_slot, head_root)
epoch = Misc.compute_epoch_at_slot(head_slot)
beacon = fetch_target_state_and_go_to_slot(epoch, head_slot, head_root)

state = %__MODULE__{
index: nil,
keystore: keystore,
payload_builder: nil
}

case fetch_validator_index(beacon, state.keystore.pubkey) do
nil ->
Logger.warning(
"[Validator] Public key #{state.keystore.pubkey} not found in the validator set"
)

state

validator_index ->
log_debug(validator_index, "Setup completed")
%{state | index: validator_index}
end
new(keystore, beacon)
end

@spec new(Keystore.t(), Types.BeaconState.t()) :: t()
Expand Down Expand Up @@ -85,11 +69,9 @@ defmodule LambdaEthereumConsensus.Validator do
##########################
# Target State

@spec fetch_target_state_and_go_to_slot(Types.slot(), Types.root()) ::
@spec fetch_target_state_and_go_to_slot(Types.epoch(), Types.slot(), Types.root()) ::
Types.BeaconState.t()
def fetch_target_state_and_go_to_slot(slot, root) do
epoch = Misc.compute_epoch_at_slot(slot)

def fetch_target_state_and_go_to_slot(epoch, slot, root) do
epoch |> fetch_target_state(root) |> go_to_slot(slot)
end

Expand Down
31 changes: 19 additions & 12 deletions lib/lambda_ethereum_consensus/validator/validator_set.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
simplify the delegation of work.
"""

defstruct head_root: nil, duties: %{}, validators: []
defstruct head_root: nil, duties: %{}, validators: %{}

require Logger

Expand Down Expand Up @@ -54,10 +54,11 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
defp setup_validators(slot, head_root, keystore_dir, keystore_pass_dir) do
validator_keystores = decode_validator_keystores(keystore_dir, keystore_pass_dir)
epoch = Misc.compute_epoch_at_slot(slot)
beacon = Validator.fetch_target_state_and_go_to_slot(epoch, slot, head_root)

validators =
Map.new(validator_keystores, fn keystore ->
validator = Validator.new(keystore, slot, head_root)
validator = Validator.new(keystore, beacon)
{validator.index, validator}
end)

Expand All @@ -71,22 +72,28 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
Notify all validators of a new head.
"""
@spec notify_head(t(), Types.slot(), Types.root()) :: t()
def notify_head(%{validators: validators} = state, _slot, _head_root) when validators == %{},
do: state

def notify_head(set, slot, head_root) do
Logger.debug("[ValidatorSet] New Head", root: head_root, slot: slot)
epoch = Misc.compute_epoch_at_slot(slot)

# TODO: this doesn't take into account reorgs
set
|> update_state(epoch, slot, head_root)
|> attests(epoch, slot, head_root)
|> build_payload(slot + 1, head_root)
|> maybe_attests(epoch, slot, head_root)
|> maybe_build_payload(slot + 1, head_root)
|> sync_committee_broadcasts(epoch, slot, head_root)
end

@doc """
Notify all validators of a new tick.
"""
@spec notify_tick(t(), tuple()) :: t()
def notify_tick(%{validators: validators} = state, _slot_data) when validators == %{},
do: state

def notify_tick(%{head_root: head_root} = set, {slot, third} = slot_data) do
Logger.debug("[ValidatorSet] Tick #{inspect(third)}", root: head_root, slot: slot)
epoch = Misc.compute_epoch_at_slot(slot)
Expand All @@ -97,18 +104,18 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
end

defp process_tick(%{head_root: head_root} = set, epoch, {slot, :first_third}) do
propose(set, epoch, slot, head_root)
maybe_propose(set, epoch, slot, head_root)
end

defp process_tick(%{head_root: head_root} = set, epoch, {slot, :second_third}) do
set
|> attests(epoch, slot, head_root)
|> build_payload(slot + 1, head_root)
|> maybe_attests(epoch, slot, head_root)
|> maybe_build_payload(slot + 1, head_root)
|> sync_committee_broadcasts(epoch, slot, head_root)
end

defp process_tick(set, epoch, {slot, :last_third}) do
publish_aggregates(set, epoch, slot)
maybe_publish_aggregates(set, epoch, slot)
end

##############################
Expand Down Expand Up @@ -148,7 +155,7 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
##############################
# Block proposal

defp build_payload(%{validators: validators} = set, slot, head_root) do
defp maybe_build_payload(%{validators: validators} = set, slot, head_root) do
# We calculate payloads from a previous slot, we need to recompute the epoch
epoch = Misc.compute_epoch_at_slot(slot)

Expand All @@ -163,7 +170,7 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
end
end

defp propose(%{validators: validators} = set, epoch, slot, head_root) do
defp maybe_propose(%{validators: validators} = set, epoch, slot, head_root) do
case Duties.current_proposer(set.duties, epoch, slot) do
nil ->
set
Expand Down Expand Up @@ -203,7 +210,7 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
##############################
# Attestation

defp attests(set, epoch, slot, head_root) do
defp maybe_attests(set, epoch, slot, head_root) do
case Duties.current_attesters(set.duties, epoch, slot) do
[] ->
set
Expand All @@ -215,7 +222,7 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
end
end

defp publish_aggregates(set, epoch, slot) do
defp maybe_publish_aggregates(set, epoch, slot) do
case Duties.current_aggregators(set.duties, epoch, slot) do
[] ->
set
Expand Down

0 comments on commit 97e6b3a

Please sign in to comment.