Skip to content

Commit cb0b580

Browse files
committed
Calculate proposers for the whole epoch
1 parent 6046c52 commit cb0b580

File tree

3 files changed

+44
-22
lines changed

3 files changed

+44
-22
lines changed

lib/lambda_ethereum_consensus/validator/duties.ex

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,18 @@ defmodule LambdaEthereumConsensus.Validator.Duties do
4040
}
4141
end
4242

43-
@spec compute_proposers_for_epoch(beacon_state :: BeaconState.t(), epoch :: Types.epoch()) ::
43+
@spec compute_proposers_for_epoch(beacon_state :: BeaconState.t(), epoch :: Types.epoch(), %{}) ::
4444
%{Types.slot() => non_neg_integer()}
45-
def compute_proposers_for_epoch(beacon_state, epoch) do
45+
def compute_proposers_for_epoch(beacon_state, epoch, validators) do
4646
start_slot = Misc.compute_start_slot_at_epoch(epoch)
4747

4848
start_slot..(start_slot + ChainSpec.get("SLOTS_PER_EPOCH") - 1)
49-
|> Enum.map(fn slot ->
50-
{slot, Accessors.get_beacon_proposer_index(beacon_state, slot)}
49+
|> Enum.flat_map(fn slot ->
50+
validator_index = Accessors.get_beacon_proposer_index(beacon_state, slot)
51+
52+
if Map.has_key?(validators, validator_index),
53+
do: [{slot, Accessors.get_beacon_proposer_index(beacon_state, slot)}],
54+
else: []
5155
end)
5256
|> Map.new()
5357
end

lib/lambda_ethereum_consensus/validator/validator.ex

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ defmodule LambdaEthereumConsensus.Validator do
4848
payload_builder: {Types.slot(), Types.root(), BlockBuilder.payload_id()} | nil
4949
}
5050

51-
@spec new({Types.slot(), Types.root(), {Bls.pubkey(), Bls.privkey()}}) :: state
52-
def new({head_slot, head_root, {pubkey, privkey}}) do
51+
@spec new({Bls.pubkey(), Bls.privkey()}, Types.epoch(), Types.slot(), Types.root(), Types.BeaconState.t()) :: state
52+
def new({pubkey, privkey}, epoch, head_slot, head_root, beacon) do
5353
state = %__MODULE__{
5454
slot: head_slot,
55-
epoch: Misc.compute_epoch_at_slot(head_slot),
55+
epoch: epoch,
5656
root: head_root,
5757
duties: Duties.empty_duties(),
5858
validator: %{
@@ -63,7 +63,7 @@ defmodule LambdaEthereumConsensus.Validator do
6363
payload_builder: nil
6464
}
6565

66-
case try_setup_validator(state, head_slot, head_root) do
66+
case try_setup_validator(state, epoch, head_slot, head_root, beacon) do
6767
nil ->
6868
# TODO: Previously this was handled by the validator continously trying to setup itself,
6969
# but now that they are processed syncronously, we should handle this case different.
@@ -76,11 +76,8 @@ defmodule LambdaEthereumConsensus.Validator do
7676
end
7777
end
7878

79-
@spec try_setup_validator(state, Types.slot(), Types.root()) :: state | nil
80-
defp try_setup_validator(state, slot, root) do
81-
epoch = Misc.compute_epoch_at_slot(slot)
82-
beacon = fetch_target_state(epoch, root)
83-
79+
@spec try_setup_validator(state, Types.epoch(), Types.slot(), Types.root(), Types.BeaconState.t()) :: state | nil
80+
defp try_setup_validator(state, epoch, slot, root, beacon) do
8481
case fetch_validator_index(beacon, state.validator) do
8582
nil ->
8683
nil

lib/lambda_ethereum_consensus/validator/validator_pool.ex

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
1010
require Logger
1111

1212
alias LambdaEthereumConsensus.StateTransition.Misc
13+
alias LambdaEthereumConsensus.Store.CheckpointStates
1314
alias LambdaEthereumConsensus.Validator
15+
alias LambdaEthereumConsensus.Validator.Duties
1416

15-
@type validators :: %{atom() => list(Validator.state())}
17+
@type validators :: %{atom() => %{} | []}
1618
@type t :: %__MODULE__{
17-
epoch: Types.epoch(),
18-
slot: Types.slot(),
19-
head_root: Types.root(),
19+
epoch: Types.epoch() | nil,
20+
slot: Types.slot() | nil,
21+
head_root: Types.root() | nil,
2022
validators: validators()
2123
}
2224

@@ -44,18 +46,33 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
4446
defp setup_validators(slot, head_root, keystore_dir, keystore_pass_dir) do
4547
validator_keys = decode_validator_keys(keystore_dir, keystore_pass_dir)
4648

47-
validators = Enum.map(validator_keys, &Validator.new({slot, head_root, &1}))
49+
epoch = Misc.compute_epoch_at_slot(slot)
50+
beacon = fetch_target_state!(epoch, head_root)
51+
52+
validators = Map.new(validator_keys, fn validator_key ->
53+
validator = Validator.new(validator_key, epoch, slot, head_root, beacon)
54+
{validator.validator.index, validator}
55+
end)
4856

4957
Logger.info("[Validator] Initialized #{Enum.count(validators)} validators")
5058

59+
proposers = Duties.compute_proposers_for_epoch(beacon, epoch, validators)
60+
5161
%__MODULE__{
52-
epoch: Misc.compute_epoch_at_slot(slot),
62+
epoch: epoch,
5363
slot: slot,
5464
head_root: head_root,
55-
validators: %{uninitialized: validators}
65+
validators: %{
66+
proposers: proposers,
67+
uninitialized: validators}
5668
}
5769
end
5870

71+
defp fetch_target_state!(epoch, head_root) do
72+
{:ok, state} = CheckpointStates.compute_target_checkpoint_state(epoch, head_root)
73+
state
74+
end
75+
5976
@doc """
6077
Notify all validators of a new head.
6178
"""
@@ -64,7 +81,9 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
6481
uninitialized_validators =
6582
maybe_debug_notify(
6683
fn ->
67-
Enum.map(validators, &Validator.handle_new_head(slot, head_root, &1))
84+
Map.new(validators, fn {k, v} ->
85+
{k, Validator.handle_new_head(slot, head_root, v)}
86+
end)
6887
end,
6988
{:new_head, slot, head_root}
7089
)
@@ -80,7 +99,9 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
8099
uninitialized_validators =
81100
maybe_debug_notify(
82101
fn ->
83-
Enum.map(validators, &Validator.handle_tick(slot_data, &1))
102+
Map.new(validators, fn {k, v} ->
103+
{k, Validator.handle_tick(slot_data, v)}
104+
end)
84105
end,
85106
{:on_tick, slot_data}
86107
)

0 commit comments

Comments
 (0)