@@ -38,18 +38,43 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
38
38
setup_validators ( slot , head_root , keystore_dir , keystore_pass_dir )
39
39
end
40
40
41
+ defp setup_validators ( _s , _r , keystore_dir , keystore_pass_dir )
42
+ when is_nil ( keystore_dir ) or is_nil ( keystore_pass_dir ) do
43
+ Logger . warning (
44
+ "[Validator] No keystore_dir or keystore_pass_dir provided. Validators won't start."
45
+ )
46
+
47
+ % __MODULE__ { }
48
+ end
49
+
50
+ defp setup_validators ( slot , head_root , keystore_dir , keystore_pass_dir ) do
51
+ validator_keystores = decode_validator_keystores ( keystore_dir , keystore_pass_dir )
52
+ epoch = Misc . compute_epoch_at_slot ( slot )
53
+
54
+ validators =
55
+ Map . new ( validator_keystores , fn keystore ->
56
+ validator = Validator . new ( keystore , slot , head_root )
57
+ { validator . index , validator }
58
+ end )
59
+
60
+ Logger . info ( "[Validator] Initialized #{ Enum . count ( validators ) } validators" )
61
+
62
+ % __MODULE__ { validators: validators }
63
+ |> update_state ( epoch , slot , head_root )
64
+ end
65
+
41
66
@ doc """
42
67
Notify all validators of a new head.
43
68
"""
44
69
@ spec notify_head ( t ( ) , Types . slot ( ) , Types . root ( ) ) :: t ( )
45
70
def notify_head ( set , slot , head_root ) do
46
71
# TODO: Just for testing purposes, remove it later
47
- Logger . info ( "[Validator] Notifying all Validators with new_head " , root: head_root , slot: slot )
72
+ Logger . info ( "[ValidatorSet] New Head " , root: head_root , slot: slot )
48
73
epoch = Misc . compute_epoch_at_slot ( slot )
49
74
50
75
set
51
76
|> update_state ( epoch , slot , head_root )
52
- |> attest ( epoch , slot , head_root )
77
+ |> attests ( epoch , slot , head_root )
53
78
|> build_next_payload ( epoch , slot , head_root )
54
79
end
55
80
@@ -59,59 +84,26 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
59
84
@ spec notify_tick ( t ( ) , tuple ( ) ) :: t ( )
60
85
def notify_tick ( % { head_root: head_root } = set , { slot , third } = slot_data ) do
61
86
# 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
-
87
+ Logger . info ( "[ValidatorSet] Tick #{ inspect ( third ) } " , root: head_root , slot: slot )
67
88
epoch = Misc . compute_epoch_at_slot ( slot )
68
89
69
90
set
70
91
|> update_state ( epoch , slot , head_root )
71
92
|> process_tick ( epoch , slot_data )
72
93
end
73
94
74
- defp process_tick ( % { head_root: head_root } = set , epoch , { slot , :first_third } ) ,
75
- do: propose ( set , epoch , slot , head_root )
95
+ defp process_tick ( % { head_root: head_root } = set , epoch , { slot , :first_third } ) do
96
+ propose ( set , epoch , slot , head_root )
97
+ end
76
98
77
99
defp process_tick ( % { head_root: head_root } = set , epoch , { slot , :second_third } ) do
78
100
set
79
- |> attest ( epoch , slot , head_root )
101
+ |> attests ( epoch , slot , head_root )
80
102
|> build_next_payload ( epoch , slot , head_root )
81
103
end
82
104
83
- defp process_tick ( set , epoch , { slot , :last_third } ) ,
84
- do: publish_aggregate ( set , epoch , slot )
85
-
86
- ##############################
87
- # Setup
88
-
89
- defp setup_validators ( _s , _r , keystore_dir , keystore_pass_dir )
90
- when is_nil ( keystore_dir ) or is_nil ( keystore_pass_dir ) do
91
- Logger . warning (
92
- "[Validator] No keystore_dir or keystore_pass_dir provided. Validators won't start."
93
- )
94
-
95
- % __MODULE__ { }
96
- end
97
-
98
- defp setup_validators ( slot , head_root , keystore_dir , keystore_pass_dir ) do
99
- validator_keystores = decode_validator_keystores ( keystore_dir , keystore_pass_dir )
100
- epoch = Misc . compute_epoch_at_slot ( slot )
101
-
102
- # This will be removed later when refactoring Validator new
103
- beacon = Validator . fetch_target_state_and_go_to_slot ( epoch , slot , head_root )
104
-
105
- validators =
106
- Map . new ( validator_keystores , fn keystore ->
107
- validator = Validator . new ( keystore , beacon )
108
- { validator . index , validator }
109
- end )
110
-
111
- Logger . info ( "[Validator] Initialized #{ Enum . count ( validators ) } validators" )
112
-
113
- % __MODULE__ { validators: validators }
114
- |> update_state ( epoch , slot , head_root )
105
+ defp process_tick ( set , epoch , { slot , :last_third } ) do
106
+ publish_aggregates ( set , epoch , slot )
115
107
end
116
108
117
109
##############################
@@ -161,91 +153,86 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
161
153
end
162
154
163
155
##############################
164
- # Attestation and proposal
165
-
166
- defp attest ( set , epoch , slot , head_root ) do
167
- case current_attesters ( set , epoch , slot ) do
168
- [ ] ->
169
- set
170
-
171
- attesters ->
172
- Enum . map ( attesters , fn { validator , duty } ->
173
- Validator . attest ( validator , duty , slot , head_root )
174
-
175
- # Duty.attested(duty)
176
- % { duty | attested?: true }
177
- end )
178
- |> then ( & % { set | duties: put_in ( set . duties , [ epoch , :attesters , slot ] , & 1 ) } )
179
- end
180
- end
181
-
182
- defp publish_aggregate ( set , epoch , slot ) do
183
- case current_aggregators ( set , epoch , slot ) do
184
- [ ] ->
185
- set
186
-
187
- aggregators ->
188
- Enum . map ( aggregators , fn { validator , duty } ->
189
- Validator . publish_aggregate ( duty , slot , validator . index , validator . keystore )
190
-
191
- # Duty.aggregated(duty)
192
- % { duty | should_aggregate?: false }
193
- end )
194
- |> then ( & % { set | duties: put_in ( set . duties , [ epoch , :attesters , slot ] , & 1 ) } )
195
- end
196
- end
156
+ # Block proposal
197
157
198
158
defp build_next_payload ( % { validators: validators } = set , epoch , slot , head_root ) do
199
- set
200
- |> proposer ( epoch , slot + 1 )
201
- |> case 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
202
161
nil ->
203
162
set
204
163
205
164
validator_index ->
206
165
validators
207
166
|> Map . update! ( validator_index , & Validator . start_payload_builder ( & 1 , slot + 1 , head_root ) )
208
- |> then ( & % { set | validators: & 1 } )
167
+ |> update_validators ( set )
209
168
end
210
169
end
211
170
212
171
defp propose ( % { validators: validators } = set , epoch , slot , head_root ) do
213
- set
214
- |> proposer ( epoch , slot )
215
- |> case do
172
+ case Duties . current_proposer ( set . duties , epoch , slot ) do
216
173
nil ->
217
174
set
218
175
219
176
validator_index ->
220
177
validators
221
178
|> Map . update! ( validator_index , & Validator . propose ( & 1 , slot , head_root ) )
222
- |> then ( & % { set | validators: & 1 } )
179
+ |> update_validators ( set )
223
180
end
224
181
end
225
182
183
+ defp update_validators ( new_validators , set ) , do: % { set | validators: new_validators }
184
+
226
185
##############################
227
- # Helpers
186
+ # Attestation
228
187
229
- defp current_attesters ( set , epoch , slot ) do
230
- set
231
- |> attesters ( epoch , slot )
232
- |> Enum . flat_map ( fn
233
- % { attested?: false } = duty -> [ { Map . get ( set . validators , duty . validator_index ) , duty } ]
234
- _ -> [ ]
235
- end )
188
+ defp attests ( set , epoch , slot , head_root ) do
189
+ case Duties . current_attesters ( set . duties , epoch , slot ) do
190
+ [ ] ->
191
+ set
192
+
193
+ attester_duties ->
194
+ attester_duties
195
+ |> Enum . map ( & attest ( & 1 , slot , head_root , set . validators ) )
196
+ |> update_duties ( set , epoch , :attesters , slot )
197
+ end
236
198
end
237
199
238
- defp current_aggregators ( set , epoch , slot ) do
239
- set
240
- |> attesters ( epoch , slot )
241
- |> Enum . flat_map ( fn
242
- % { should_aggregate?: true } = duty -> [ { Map . get ( set . validators , duty . validator_index ) , duty } ]
243
- _ -> [ ]
244
- end )
200
+ defp publish_aggregates ( set , epoch , slot ) do
201
+ case Duties . current_aggregators ( set . duties , epoch , slot ) do
202
+ [ ] ->
203
+ set
204
+
205
+ aggregator_duties ->
206
+ aggregator_duties
207
+ |> Enum . map ( & publish_aggregate ( & 1 , slot , set . validators ) )
208
+ |> update_duties ( set , epoch , :attesters , slot )
209
+ end
210
+ end
211
+
212
+ defp attest ( duty , slot , head_root , validators ) do
213
+ validators
214
+ |> Map . get ( duty . validator_index )
215
+ |> Validator . attest ( duty , slot , head_root )
216
+
217
+ Duties . attested ( duty )
245
218
end
246
219
247
- defp proposer ( set , epoch , slot ) , do: get_in ( set . duties , [ epoch , :proposers , slot ] )
248
- defp attesters ( set , epoch , slot ) , do: get_in ( set . duties , [ epoch , :attesters , slot ] ) || [ ]
220
+ defp publish_aggregate ( duty , slot , validators ) do
221
+ validators
222
+ |> Map . get ( duty . validator_index )
223
+ |> Validator . publish_aggregate ( duty , slot )
224
+
225
+ Duties . aggregated ( duty )
226
+ end
227
+
228
+ defp update_duties ( new_duties , set , epoch , kind , slot ) do
229
+ set . duties
230
+ |> Duties . update_duties! ( kind , epoch , slot , new_duties )
231
+ |> then ( & % { set | duties: & 1 } )
232
+ end
233
+
234
+ ##############################
235
+ # Key management
249
236
250
237
@ doc """
251
238
Get validator keystores from the keystore directory.
0 commit comments