@@ -23,30 +23,69 @@ defmodule LambdaEthereumConsensus.Validator do
23
23
24
24
@ impl true
25
25
def init ( { slot , head_root } ) do
26
+ config = Application . get_env ( :lambda_ethereum_consensus , __MODULE__ , [ ] )
27
+
28
+ validator =
29
+ case { Keyword . get ( config , :pubkey ) , Keyword . get ( config , :privkey ) } do
30
+ { nil , nil } -> nil
31
+ { pubkey , privkey } -> % { index: nil , privkey: privkey , pubkey: pubkey }
32
+ end
33
+
26
34
state = % {
27
35
slot: slot ,
28
36
root: head_root ,
29
37
duties: % {
30
38
attester: { :not_computed , :not_computed }
31
39
} ,
32
- # TODO: get validator from config
33
- validator: % { index: 55 , privkey: << 652_916_760 :: 256 >> }
40
+ validator: validator
34
41
}
35
42
36
43
{ :ok , state , { :continue , nil } }
37
44
end
38
45
39
46
@ impl true
47
+ def handle_continue ( nil , % { validator: nil } = state ) , do: { :noreply , state }
48
+
40
49
def handle_continue ( nil , % { slot: slot , root: root } = state ) do
50
+ case try_setup_validator ( state , slot , root ) do
51
+ nil ->
52
+ Logger . error ( "[Validator] Public key not found in the validator set" )
53
+ { :noreply , state }
54
+
55
+ new_state ->
56
+ { :noreply , new_state }
57
+ end
58
+ end
59
+
60
+ defp try_setup_validator ( state , slot , root ) do
41
61
epoch = Misc . compute_epoch_at_slot ( slot )
42
62
beacon = fetch_target_state ( epoch , root )
43
- duties = maybe_update_duties ( state . duties , beacon , epoch , state . validator )
44
- join_subnets_for_duties ( duties )
45
- log_duties ( duties , state . validator . index )
46
- { :noreply , % { state | duties: duties } }
63
+
64
+ case fetch_validator_index ( beacon , state . validator ) do
65
+ nil ->
66
+ nil
67
+
68
+ validator_index ->
69
+ Logger . info ( "[Validator] Setup for validator number #{ validator_index } complete" )
70
+ validator = % { state . validator | index: validator_index }
71
+ duties = maybe_update_duties ( state . duties , beacon , epoch , validator )
72
+ join_subnets_for_duties ( duties )
73
+ log_duties ( duties , validator_index )
74
+ % { state | duties: duties , validator: validator }
75
+ end
47
76
end
48
77
49
78
@ impl true
79
+ def handle_cast ( _ , % { validator: nil } = state ) , do: { :noreply , state }
80
+
81
+ # If we couldn't find the validator before, we just try again
82
+ def handle_cast ( { :new_block , slot , head_root } = msg , % { validator: % { index: nil } } = state ) do
83
+ case try_setup_validator ( state , slot , head_root ) do
84
+ nil -> { :noreply , state }
85
+ new_state -> handle_cast ( msg , new_state )
86
+ end
87
+ end
88
+
50
89
def handle_cast ( { :new_block , slot , head_root } , state ) do
51
90
# TODO: this doesn't take into account reorgs or empty slots
52
91
new_state = update_state ( state , slot , head_root )
@@ -277,6 +316,8 @@ defmodule LambdaEthereumConsensus.Validator do
277
316
st
278
317
end
279
318
319
+ defp update_with_aggregation_duty ( nil , _beacon_state , _privkey ) , do: nil
320
+
280
321
defp update_with_aggregation_duty ( duty , beacon_state , privkey ) do
281
322
proof = Utils . get_slot_signature ( beacon_state , duty . slot , privkey )
282
323
@@ -300,4 +341,8 @@ defmodule LambdaEthereumConsensus.Validator do
300
341
301
342
Map . put ( duty , :subnet_id , subnet_id )
302
343
end
344
+
345
+ defp fetch_validator_index ( beacon , % { index: nil , pubkey: pk } ) do
346
+ beacon . validators |> Enum . find_index ( & ( & 1 . pubkey == pk ) )
347
+ end
303
348
end
0 commit comments