Skip to content

Commit c99729f

Browse files
committed
handle_tick completely moved to ValidatorSet
1 parent 3abb064 commit c99729f

File tree

2 files changed

+111
-62
lines changed

2 files changed

+111
-62
lines changed

lib/lambda_ethereum_consensus/validator/validator.ex

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -111,26 +111,6 @@ defmodule LambdaEthereumConsensus.Validator do
111111
end
112112
end
113113

114-
@spec handle_new_head(Types.slot(), Types.root(), t()) :: t()
115-
def handle_new_head(slot, head_root, %{index: nil} = state) do
116-
log_error("-1", "setup validator", "index not present handle block",
117-
slot: slot,
118-
root: head_root
119-
)
120-
121-
state
122-
end
123-
124-
def handle_new_head(slot, head_root, state) do
125-
log_debug(state.index, "recieved new head", slot: slot, root: head_root)
126-
127-
# TODO: this doesn't take into account reorgs
128-
state
129-
|> update_state(slot, head_root)
130-
|> maybe_attest(slot, head_root)
131-
|> maybe_build_payload(slot + 1, head_root)
132-
end
133-
134114
@spec handle_tick({Types.slot(), atom()}, t(), Types.root()) :: t()
135115
def handle_tick(_logical_time, %{index: nil} = state, _root) do
136116
log_error("-1", "setup validator", "index not present for handle tick")
@@ -298,7 +278,7 @@ defmodule LambdaEthereumConsensus.Validator do
298278
end
299279
end
300280

301-
defp publish_aggregate(duty, validator_index, keystore) do
281+
def publish_aggregate(duty, validator_index, keystore) do
302282
case Gossip.Attestation.stop_collecting(duty.subnet_id) do
303283
{:ok, attestations} ->
304284
log_md = [slot: duty.slot, attestations: attestations]
@@ -445,15 +425,15 @@ defmodule LambdaEthereumConsensus.Validator do
445425
end
446426
end
447427

448-
defp propose(
449-
%{
450-
index: validator_index,
451-
payload_builder: {proposed_slot, head_root, payload_id},
452-
keystore: keystore
453-
} = state,
454-
proposed_slot,
455-
head_root
456-
) do
428+
def propose(
429+
%{
430+
index: validator_index,
431+
payload_builder: {proposed_slot, head_root, payload_id},
432+
keystore: keystore
433+
} = state,
434+
proposed_slot,
435+
head_root
436+
) do
457437
log_debug(validator_index, "building block", slot: proposed_slot)
458438

459439
build_result =
@@ -481,12 +461,12 @@ defmodule LambdaEthereumConsensus.Validator do
481461
end
482462

483463
# TODO: at least in kurtosis there are blocks that are proposed without a payload apparently, must investigate.
484-
defp propose(%{payload_builder: nil} = state, _proposed_slot, _head_root) do
464+
def propose(%{payload_builder: nil} = state, _proposed_slot, _head_root) do
485465
log_error(state.index, "propose block", "lack of execution payload")
486466
state
487467
end
488468

489-
defp propose(state, proposed_slot, _head_root) do
469+
def propose(state, proposed_slot, _head_root) do
490470
Logger.error(
491471
"[Validator] Skipping block proposal for slot #{proposed_slot} due to missing validator data"
492472
)

lib/lambda_ethereum_consensus/validator/validator_set.ex

Lines changed: 99 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -57,20 +57,54 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
5757
Notify all validators of a new tick.
5858
"""
5959
@spec notify_tick(t(), tuple()) :: t()
60-
def notify_tick(%{validators: validators, head_root: head_root} = set, slot_data) do
61-
validators =
62-
maybe_debug_notify(
63-
fn ->
64-
Map.new(validators, fn {k, v} ->
65-
{k, Validator.handle_tick(slot_data, v, head_root)}
66-
end)
67-
end,
68-
{:on_tick, slot_data}
69-
)
60+
def notify_tick(%{head_root: head_root} = set, {slot, third} = slot_data) do
61+
# TODO: Just for testing purposes, remove it later
62+
Logger.info("[Validator] Notifying all Validators with notify_tick: #{inspect(third)}",
63+
root: head_root,
64+
slot: slot
65+
)
66+
67+
epoch = Misc.compute_epoch_at_slot(slot)
68+
69+
process_tick(set, epoch, slot_data)
70+
end
71+
72+
@spec process_tick(t(), Types.epoch(), tuple()) :: t()
73+
def process_tick(%{head_root: head_root} = set, epoch, {slot, :first_third}) do
74+
set
75+
|> update_state(epoch, head_root)
76+
|> propose(epoch, slot, head_root)
77+
end
7078

71-
%{set | validators: validators}
79+
@spec process_tick(t(), Types.epoch(), tuple()) :: t()
80+
def process_tick(%{head_root: head_root} = set, epoch, {slot, :second_third}) do
81+
set
82+
|> update_state(epoch, head_root)
83+
|> attest(epoch, slot, head_root)
84+
|> build_next_payload(epoch, slot, head_root)
85+
end
86+
87+
@spec process_tick(t(), Types.epoch(), tuple()) :: t()
88+
def process_tick(%{head_root: head_root} = set, epoch, {slot, :last_third}) do
89+
set
90+
|> update_state(epoch, head_root)
91+
|> publish_aggregate(epoch, slot, head_root)
7292
end
7393

94+
# def process_tick(%{validators: validators, head_root: head_root} = set, _epoch, slot_data) do
95+
# validators =
96+
# maybe_debug_notify(
97+
# fn ->
98+
# Map.new(validators, fn {k, v} ->
99+
# {k, Validator.handle_tick(slot_data, v, head_root)}
100+
# end)
101+
# end,
102+
# {:on_tick, slot_data}
103+
# )
104+
105+
# %{set | validators: validators}
106+
# end
107+
74108
##############################
75109
# Setup
76110

@@ -170,18 +204,45 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
170204
%{set | duties: put_in(set.duties, [epoch, :attesters, slot], updated_duties)}
171205
end
172206

173-
defp build_next_payload(set, epoch, slot, head_root) do
207+
defp publish_aggregate(set, epoch, slot, head_root) do
208+
updated_duties =
209+
set
210+
|> current_aggregators(epoch, slot)
211+
|> Enum.map(fn {validator, duty} ->
212+
Validator.publish_aggregate(duty, validator.index, validator.keystore)
213+
214+
# Duty.aggregated(duty)
215+
%{duty | should_aggregate?: false}
216+
end)
217+
218+
%{set | duties: put_in(set.duties, [epoch, :attesters, slot], updated_duties)}
219+
end
220+
221+
defp build_next_payload(%{validators: validators} = set, epoch, slot, head_root) do
174222
set
175223
|> proposer(epoch, slot + 1)
176224
|> case do
177225
nil ->
178226
set
179227

180228
validator_index ->
181-
validator = Map.get(set.validators, validator_index)
182-
updated_validator = Validator.start_payload_builder(validator, slot + 1, head_root)
229+
validators
230+
|> Map.update!(validator_index, &Validator.start_payload_builder(&1, slot + 1, head_root))
231+
|> then(&%{set | validators: &1})
232+
end
233+
end
234+
235+
defp propose(%{validators: validators} = set, epoch, slot, head_root) do
236+
set
237+
|> proposer(epoch, slot)
238+
|> case do
239+
nil ->
240+
set
183241

184-
%{set | validators: Map.put(set.validators, updated_validator.index, updated_validator)}
242+
validator_index ->
243+
validators
244+
|> Map.update!(validator_index, &Validator.propose(&1, slot, head_root))
245+
|> then(&%{set | validators: &1})
185246
end
186247
end
187248

@@ -196,27 +257,35 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
196257
end)
197258
end
198259

260+
defp current_aggregators(set, epoch, slot) do
261+
attesters(set, epoch, slot)
262+
|> Enum.flat_map(fn
263+
%{should_aggregate?: true} = duty -> [{Map.get(set.validators, duty.validator_index), duty}]
264+
_ -> []
265+
end)
266+
end
267+
199268
defp proposer(set, epoch, slot), do: get_in(set.duties, [epoch, :proposers, slot])
200269
defp attesters(set, epoch, slot), do: get_in(set.duties, [epoch, :attesters, slot]) || []
201270

202-
defp maybe_debug_notify(fun, data) do
203-
# :debug do
204-
if Application.get_env(:logger, :level) == :info do
205-
Logger.info("[Validator] Notifying all Validators with message: #{inspect(data)}")
271+
# defp maybe_debug_notify(fun, data) do
272+
# # :debug do
273+
# if Application.get_env(:logger, :level) == :info do
274+
# Logger.info("[Validator] Notifying all Validators with message: #{inspect(data)}")
206275

207-
start_time = System.monotonic_time(:millisecond)
208-
result = fun.()
209-
end_time = System.monotonic_time(:millisecond)
276+
# start_time = System.monotonic_time(:millisecond)
277+
# result = fun.()
278+
# end_time = System.monotonic_time(:millisecond)
210279

211-
Logger.info(
212-
"[Validator] #{inspect(data)} notified to all Validators after #{end_time - start_time} ms"
213-
)
280+
# Logger.info(
281+
# "[Validator] #{inspect(data)} notified to all Validators after #{end_time - start_time} ms"
282+
# )
214283

215-
result
216-
else
217-
fun.()
218-
end
219-
end
284+
# result
285+
# else
286+
# fun.()
287+
# end
288+
# end
220289

221290
@doc """
222291
Get validator keystores from the keystore directory.

0 commit comments

Comments
 (0)