@@ -26,6 +26,10 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
26
26
validators: validators ( )
27
27
}
28
28
29
+ @ doc "Check if the duties for the given epoch are already computed."
30
+ defguard is_duties_computed ( set , epoch )
31
+ when is_map ( set . duties ) and not is_nil ( :erlang . map_get ( epoch , set . duties ) )
32
+
29
33
@ doc """
30
34
Initiate the set of validators, given the slot and head root.
31
35
"""
@@ -75,7 +79,7 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
75
79
set
76
80
|> update_state ( epoch , slot , head_root )
77
81
|> attests ( epoch , slot , head_root )
78
- |> build_next_payload ( epoch , slot , head_root )
82
+ |> build_payload ( slot + 1 , head_root )
79
83
end
80
84
81
85
@ doc """
@@ -99,7 +103,7 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
99
103
defp process_tick ( % { head_root: head_root } = set , epoch , { slot , :second_third } ) do
100
104
set
101
105
|> attests ( epoch , slot , head_root )
102
- |> build_next_payload ( epoch , slot , head_root )
106
+ |> build_payload ( slot + 1 , head_root )
103
107
end
104
108
105
109
defp process_tick ( set , epoch , { slot , :last_third } ) do
@@ -119,19 +123,23 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
119
123
defp update_head ( set , head_root ) , do: % { set | head_root: head_root }
120
124
121
125
defp compute_duties ( set , epoch , _slot , _head_root )
122
- when not is_nil ( :erlang . map_get ( epoch , set . duties ) ) ,
126
+ when is_duties_computed ( set , epoch ) and is_duties_computed ( set , epoch + 1 ) ,
123
127
do: set
124
128
125
129
defp compute_duties ( set , epoch , slot , head_root ) do
126
- epoch
127
- |> Validator . fetch_target_state_and_go_to_slot ( slot , head_root )
128
- |> compute_duties_for_epoch! ( epoch , set . validators )
130
+ epochs_to_calculate =
131
+ [ { epoch , slot } , { epoch + 1 , Misc . compute_start_slot_at_epoch ( epoch + 1 ) } ]
132
+ |> Enum . reject ( & Map . has_key? ( set . duties , elem ( & 1 , 0 ) ) )
133
+
134
+ epochs_to_calculate
135
+ |> Map . new ( & compute_duties_for_epoch! ( set , & 1 , head_root ) )
129
136
|> merge_duties_and_prune ( epoch , set )
130
137
end
131
138
132
- defp compute_duties_for_epoch! ( beacon , epoch , validators ) do
133
- proposers = Duties . compute_proposers_for_epoch ( beacon , epoch , validators )
134
- attesters = Duties . compute_attesters_for_epoch ( beacon , epoch , validators )
139
+ defp compute_duties_for_epoch! ( set , { epoch , slot } , head_root ) do
140
+ beacon = Validator . fetch_target_state_and_go_to_slot ( epoch , slot , head_root )
141
+ proposers = Duties . compute_proposers_for_epoch ( beacon , epoch , set . validators )
142
+ attesters = Duties . compute_attesters_for_epoch ( beacon , epoch , set . validators )
135
143
136
144
Logger . info (
137
145
"[Validator] Proposer duties for epoch #{ epoch } are: #{ inspect ( proposers , pretty: true ) } "
@@ -141,29 +149,30 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
141
149
"[Validator] Attester duties for epoch #{ epoch } are: #{ inspect ( attesters , pretty: true ) } "
142
150
)
143
151
144
- % { epoch => % { proposers: proposers , attesters: attesters } }
152
+ { epoch , % { proposers: proposers , attesters: attesters } }
145
153
end
146
154
147
- defp merge_duties_and_prune ( new_duties , epoch , set ) do
155
+ defp merge_duties_and_prune ( new_duties , current_epoch , set ) do
148
156
set . duties
149
157
# Remove duties from epoch - 2 or older
150
- |> Map . reject ( fn { old_epoch , _ } -> old_epoch < epoch - 2 end )
158
+ |> Map . reject ( fn { old_epoch , _ } -> old_epoch < current_epoch - 1 end )
151
159
|> Map . merge ( new_duties )
152
160
|> then ( fn current_duties -> % { set | duties: current_duties } end )
153
161
end
154
162
155
163
##############################
156
164
# Block proposal
157
165
158
- defp build_next_payload ( % { validators: validators } = set , epoch , slot , head_root ) do
159
- # FIXME: At a boundary slot epoch here is incorrect, we need to alway have the next epoch calculated
160
- case Duties . current_proposer ( set . duties , epoch , slot + 1 ) do
166
+ defp build_payload ( % { validators: validators } = set , slot , head_root ) do
167
+ epoch = Misc . compute_epoch_at_slot ( slot )
168
+
169
+ case Duties . current_proposer ( set . duties , epoch , slot ) do
161
170
nil ->
162
171
set
163
172
164
173
validator_index ->
165
174
validators
166
- |> Map . update! ( validator_index , & Validator . start_payload_builder ( & 1 , slot + 1 , head_root ) )
175
+ |> Map . update! ( validator_index , & Validator . start_payload_builder ( & 1 , slot , head_root ) )
167
176
|> update_validators ( set )
168
177
end
169
178
end
0 commit comments