Skip to content

Commit cfc5efe

Browse files
committed
Hybrid version working with new_head handled at the ValidatorSet
1 parent a604213 commit cfc5efe

File tree

2 files changed

+54
-34
lines changed

2 files changed

+54
-34
lines changed

lib/lambda_ethereum_consensus/validator/validator.ex

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -121,35 +121,35 @@ defmodule LambdaEthereumConsensus.Validator do
121121
state
122122
|> update_state(slot, head_root)
123123
|> maybe_attest(slot)
124-
|> maybe_build_payload(slot + 1)
124+
|> maybe_build_payload(slot + 1, head_root)
125125
end
126126

127-
@spec handle_tick({Types.slot(), atom()}, state) :: state
128-
def handle_tick(_logical_time, %{validator: %{index: nil}} = state) do
127+
@spec handle_tick({Types.slot(), atom()}, state, Types.root()) :: state
128+
def handle_tick(_logical_time, %{validator: %{index: nil}} = state, _root) do
129129
log_error("-1", "setup validator", "index not present for handle tick")
130130
state
131131
end
132132

133-
def handle_tick({slot, :first_third}, state) do
133+
def handle_tick({slot, :first_third}, state, root) do
134134
log_debug(state.validator.index, "started first third", slot: slot)
135135
# Here we may:
136136
# 1. propose our blocks
137137
# 2. (TODO) start collecting attestations for aggregation
138-
maybe_propose(state, slot)
139-
|> update_state(slot, state.root)
138+
maybe_propose(state, slot, root)
139+
|> update_state(slot, root)
140140
end
141141

142-
def handle_tick({slot, :second_third}, state) do
142+
def handle_tick({slot, :second_third}, state, root) do
143143
log_debug(state.validator.index, "started second third", slot: slot)
144144
# Here we may:
145145
# 1. send our attestation for an empty slot
146146
# 2. start building a payload
147147
state
148148
|> maybe_attest(slot)
149-
|> maybe_build_payload(slot + 1)
149+
|> maybe_build_payload(slot + 1, root)
150150
end
151151

152-
def handle_tick({slot, :last_third}, state) do
152+
def handle_tick({slot, :last_third}, state, _root) do
153153
log_debug(state.validator.index, "started last third", slot: slot)
154154
# Here we may publish our attestation aggregate
155155
maybe_publish_aggregate(state, slot)
@@ -395,8 +395,8 @@ defmodule LambdaEthereumConsensus.Validator do
395395

396396
defp proposer?(%{duties: %{proposer: slots}}, slot), do: Enum.member?(slots, slot)
397397

398-
@spec maybe_build_payload(state, Types.slot()) :: state
399-
defp maybe_build_payload(%{root: head_root} = state, proposed_slot) do
398+
@spec maybe_build_payload(state, Types.slot(), Types.root()) :: state
399+
defp maybe_build_payload(state, proposed_slot, head_root) do
400400
if proposer?(state, proposed_slot) do
401401
start_payload_builder(state, proposed_slot, head_root)
402402
else
@@ -409,7 +409,7 @@ defmodule LambdaEthereumConsensus.Validator do
409409

410410
def start_payload_builder(%{validator: validator} = state, proposed_slot, head_root) do
411411
# TODO: handle reorgs and late blocks
412-
log_debug(validator.index, "starting building payload for slot #{proposed_slot}")
412+
log_debug(validator.index, "starting building payload for slot #{proposed_slot}", root: head_root)
413413

414414
case BlockBuilder.start_building_payload(proposed_slot, head_root) do
415415
{:ok, payload_id} ->
@@ -424,21 +424,21 @@ defmodule LambdaEthereumConsensus.Validator do
424424
end
425425
end
426426

427-
defp maybe_propose(state, slot) do
427+
defp maybe_propose(state, slot, root) do
428428
if proposer?(state, slot) do
429-
propose(state, slot)
429+
propose(state, slot, root)
430430
else
431431
state
432432
end
433433
end
434434

435435
defp propose(
436436
%{
437-
root: head_root,
438437
validator: validator,
439438
payload_builder: {proposed_slot, head_root, payload_id}
440439
} = state,
441-
proposed_slot
440+
proposed_slot,
441+
head_root
442442
) do
443443
log_debug(validator.index, "building block", slot: proposed_slot)
444444

@@ -467,7 +467,7 @@ defmodule LambdaEthereumConsensus.Validator do
467467
end
468468

469469
# TODO: at least in kurtosis there are blocks that are proposed without a payload apparently, must investigate.
470-
defp propose(%{payload_builder: nil} = state, _proposed_slot) do
470+
defp propose(%{payload_builder: nil} = state, _proposed_slot, _head_root) do
471471
log_error(state.validator.index, "propose block", "lack of execution payload")
472472
state
473473
end

lib/lambda_ethereum_consensus/validator/validator_set.ex

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -58,24 +58,27 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
5858

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

61-
{:ok, proposers} = Duties.compute_proposers_for_epoch(beacon, epoch, validators)
62-
{:ok, attesters} = Duties.compute_attesters_for_epoch(beacon, epoch, validators)
63-
64-
Logger.info("[Validator] Proposers: #{inspect(proposers, pretty: true)}")
65-
Logger.info("[Validator] Attesters: #{inspect(attesters, pretty: true)}")
61+
duties = compute_duties_for_epoch!(beacon, epoch, validators)
6662

6763
%__MODULE__{
6864
epoch: epoch,
6965
slot: slot,
7066
head_root: head_root,
71-
duties: %{epoch => %{
72-
proposers: proposers,
73-
attesters: attesters
74-
}},
67+
duties: %{epoch => duties},
7568
validators: validators
7669
}
7770
end
7871

72+
defp compute_duties_for_epoch!(beacon, epoch, validators) do
73+
{:ok, proposers} = Duties.compute_proposers_for_epoch(beacon, epoch, validators)
74+
{:ok, attesters} = Duties.compute_attesters_for_epoch(beacon, epoch, validators)
75+
76+
Logger.info("[Validator] Proposer duties for epoch #{epoch} are: #{inspect(proposers, pretty: true)}")
77+
Logger.info("[Validator] Attester duties for epoch #{epoch} are: #{inspect(attesters, pretty: true)}")
78+
79+
%{proposers: proposers, attesters: attesters}
80+
end
81+
7982
defp fetch_target_state!(epoch, head_root) do
8083
{:ok, state} = CheckpointStates.compute_target_checkpoint_state(epoch, head_root)
8184
state
@@ -86,14 +89,31 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
8689
"""
8790
@spec notify_head(t(), Types.slot(), Types.root()) :: t()
8891
def notify_head(%{validators: validators, epoch: epoch} = set, slot, head_root) do
92+
# TODO: Just for testing purposes, remove it later
93+
Logger.info("[Validator] Notifying all Validators with new_head", root: head_root, slot: slot)
94+
8995
set
96+
|> update_state(slot, head_root)
9097
|> attest(epoch, slot)
9198
|> build_next_payload(epoch, slot, head_root)
92-
|> update_state(slot, head_root)
9399
end
94100

95101
defp update_state(set, slot, head_root) do
96-
%{set | slot: slot, head_root: head_root}
102+
if new_epoch?(set, slot + 1) do
103+
epoch = Misc.compute_epoch_at_slot(slot + 1)
104+
beacon = fetch_target_state!(epoch, head_root)
105+
106+
duties = compute_duties_for_epoch!(beacon, epoch, set.validators)
107+
108+
%{set | epoch: epoch, slot: slot, head_root: head_root, duties: Map.put(set.duties, epoch, duties)}
109+
else
110+
%{set | slot: slot, head_root: head_root}
111+
end
112+
end
113+
114+
defp new_epoch?(set, slot) do
115+
epoch = Misc.compute_epoch_at_slot(slot)
116+
epoch > set.epoch
97117
end
98118

99119
defp attest(set, epoch, slot) do
@@ -119,7 +139,7 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
119139
validator = Map.get(set.validators, validator_index)
120140
updated_validator = Validator.start_payload_builder(validator, slot + 1, head_root)
121141

122-
%{set | validators: Map.put(set.validators, updated_validator.validator.index, updated_validator)}
142+
%{set | validators: Map.put(set.validators, updated_validator.validator.index, %{updated_validator | root: head_root})}
123143
end
124144
end
125145

@@ -139,12 +159,12 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
139159
Notify all validators of a new tick.
140160
"""
141161
@spec notify_tick(t(), tuple()) :: t()
142-
def notify_tick(%{validators: validators} = set, slot_data) do
162+
def notify_tick(%{validators: validators, head_root: head_root} = set, slot_data) do
143163
validators =
144164
maybe_debug_notify(
145165
fn ->
146166
Map.new(validators, fn {k, v} ->
147-
{k, Validator.handle_tick(slot_data, v)}
167+
{k, Validator.handle_tick(slot_data, v, head_root)}
148168
end)
149169
end,
150170
{:on_tick, slot_data}
@@ -154,14 +174,14 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
154174
end
155175

156176
defp maybe_debug_notify(fun, data) do
157-
if Application.get_env(:logger, :level) == :debug do
158-
Logger.debug("[Validator] Notifying all Validators with message: #{inspect(data)}")
177+
if Application.get_env(:logger, :level) == :info do # :debug do
178+
Logger.info("[Validator] Notifying all Validators with message: #{inspect(data)}")
159179

160180
start_time = System.monotonic_time(:millisecond)
161181
result = fun.()
162182
end_time = System.monotonic_time(:millisecond)
163183

164-
Logger.debug(
184+
Logger.info(
165185
"[Validator] #{inspect(data)} notified to all Validators after #{end_time - start_time} ms"
166186
)
167187

0 commit comments

Comments
 (0)