Skip to content

Commit 97e6b3a

Browse files
committed
Merge branch 'main' into sync-committee-message-production
2 parents 3215928 + 9835380 commit 97e6b3a

File tree

3 files changed

+32
-36
lines changed

3 files changed

+32
-36
lines changed

lib/lambda_ethereum_consensus/validator/duties.ex

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ defmodule LambdaEthereumConsensus.Validator.Duties do
1313

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

5961
for {epoch, slot} <- epochs_and_start_slots, reduce: duties_map do
6062
duties_map ->
61-
beacon = Validator.fetch_target_state_and_go_to_slot(slot, head_root)
63+
beacon = Validator.fetch_target_state_and_go_to_slot(epoch, slot, head_root)
64+
# If committees are not already calculated for the epoch, this is way faster than
65+
# calculating them on the fly.
66+
Accessors.maybe_prefetch_committees(beacon, epoch)
67+
6268
last_epoch = Map.keys(duties_map) |> Enum.max(fn -> 0 end)
6369

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

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

267274
@spec sync_committee_broadcasted(sync_committee_duty(), Types.slot()) :: sync_committee_duty()

lib/lambda_ethereum_consensus/validator/validator.ex

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -38,26 +38,10 @@ defmodule LambdaEthereumConsensus.Validator do
3838

3939
@spec new(Keystore.t(), Types.slot(), Types.root()) :: t()
4040
def new(keystore, head_slot, head_root) do
41-
beacon = fetch_target_state_and_go_to_slot(head_slot, head_root)
41+
epoch = Misc.compute_epoch_at_slot(head_slot)
42+
beacon = fetch_target_state_and_go_to_slot(epoch, head_slot, head_root)
4243

43-
state = %__MODULE__{
44-
index: nil,
45-
keystore: keystore,
46-
payload_builder: nil
47-
}
48-
49-
case fetch_validator_index(beacon, state.keystore.pubkey) do
50-
nil ->
51-
Logger.warning(
52-
"[Validator] Public key #{state.keystore.pubkey} not found in the validator set"
53-
)
54-
55-
state
56-
57-
validator_index ->
58-
log_debug(validator_index, "Setup completed")
59-
%{state | index: validator_index}
60-
end
44+
new(keystore, beacon)
6145
end
6246

6347
@spec new(Keystore.t(), Types.BeaconState.t()) :: t()
@@ -85,11 +69,9 @@ defmodule LambdaEthereumConsensus.Validator do
8569
##########################
8670
# Target State
8771

88-
@spec fetch_target_state_and_go_to_slot(Types.slot(), Types.root()) ::
72+
@spec fetch_target_state_and_go_to_slot(Types.epoch(), Types.slot(), Types.root()) ::
8973
Types.BeaconState.t()
90-
def fetch_target_state_and_go_to_slot(slot, root) do
91-
epoch = Misc.compute_epoch_at_slot(slot)
92-
74+
def fetch_target_state_and_go_to_slot(epoch, slot, root) do
9375
epoch |> fetch_target_state(root) |> go_to_slot(slot)
9476
end
9577

lib/lambda_ethereum_consensus/validator/validator_set.ex

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
55
simplify the delegation of work.
66
"""
77

8-
defstruct head_root: nil, duties: %{}, validators: []
8+
defstruct head_root: nil, duties: %{}, validators: %{}
99

1010
require Logger
1111

@@ -54,10 +54,11 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
5454
defp setup_validators(slot, head_root, keystore_dir, keystore_pass_dir) do
5555
validator_keystores = decode_validator_keystores(keystore_dir, keystore_pass_dir)
5656
epoch = Misc.compute_epoch_at_slot(slot)
57+
beacon = Validator.fetch_target_state_and_go_to_slot(epoch, slot, head_root)
5758

5859
validators =
5960
Map.new(validator_keystores, fn keystore ->
60-
validator = Validator.new(keystore, slot, head_root)
61+
validator = Validator.new(keystore, beacon)
6162
{validator.index, validator}
6263
end)
6364

@@ -71,22 +72,28 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
7172
Notify all validators of a new head.
7273
"""
7374
@spec notify_head(t(), Types.slot(), Types.root()) :: t()
75+
def notify_head(%{validators: validators} = state, _slot, _head_root) when validators == %{},
76+
do: state
77+
7478
def notify_head(set, slot, head_root) do
7579
Logger.debug("[ValidatorSet] New Head", root: head_root, slot: slot)
7680
epoch = Misc.compute_epoch_at_slot(slot)
7781

7882
# TODO: this doesn't take into account reorgs
7983
set
8084
|> update_state(epoch, slot, head_root)
81-
|> attests(epoch, slot, head_root)
82-
|> build_payload(slot + 1, head_root)
85+
|> maybe_attests(epoch, slot, head_root)
86+
|> maybe_build_payload(slot + 1, head_root)
8387
|> sync_committee_broadcasts(epoch, slot, head_root)
8488
end
8589

8690
@doc """
8791
Notify all validators of a new tick.
8892
"""
8993
@spec notify_tick(t(), tuple()) :: t()
94+
def notify_tick(%{validators: validators} = state, _slot_data) when validators == %{},
95+
do: state
96+
9097
def notify_tick(%{head_root: head_root} = set, {slot, third} = slot_data) do
9198
Logger.debug("[ValidatorSet] Tick #{inspect(third)}", root: head_root, slot: slot)
9299
epoch = Misc.compute_epoch_at_slot(slot)
@@ -97,18 +104,18 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
97104
end
98105

99106
defp process_tick(%{head_root: head_root} = set, epoch, {slot, :first_third}) do
100-
propose(set, epoch, slot, head_root)
107+
maybe_propose(set, epoch, slot, head_root)
101108
end
102109

103110
defp process_tick(%{head_root: head_root} = set, epoch, {slot, :second_third}) do
104111
set
105-
|> attests(epoch, slot, head_root)
106-
|> build_payload(slot + 1, head_root)
112+
|> maybe_attests(epoch, slot, head_root)
113+
|> maybe_build_payload(slot + 1, head_root)
107114
|> sync_committee_broadcasts(epoch, slot, head_root)
108115
end
109116

110117
defp process_tick(set, epoch, {slot, :last_third}) do
111-
publish_aggregates(set, epoch, slot)
118+
maybe_publish_aggregates(set, epoch, slot)
112119
end
113120

114121
##############################
@@ -148,7 +155,7 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
148155
##############################
149156
# Block proposal
150157

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

@@ -163,7 +170,7 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
163170
end
164171
end
165172

166-
defp propose(%{validators: validators} = set, epoch, slot, head_root) do
173+
defp maybe_propose(%{validators: validators} = set, epoch, slot, head_root) do
167174
case Duties.current_proposer(set.duties, epoch, slot) do
168175
nil ->
169176
set
@@ -203,7 +210,7 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
203210
##############################
204211
# Attestation
205212

206-
defp attests(set, epoch, slot, head_root) do
213+
defp maybe_attests(set, epoch, slot, head_root) do
207214
case Duties.current_attesters(set.duties, epoch, slot) do
208215
[] ->
209216
set
@@ -215,7 +222,7 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
215222
end
216223
end
217224

218-
defp publish_aggregates(set, epoch, slot) do
225+
defp maybe_publish_aggregates(set, epoch, slot) do
219226
case Duties.current_aggregators(set.duties, epoch, slot) do
220227
[] ->
221228
set

0 commit comments

Comments
 (0)