@@ -5,7 +5,7 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
5
5
simplify the delegation of work.
6
6
"""
7
7
8
- defstruct epoch: nil , slot: nil , head_root: nil , validators : % { uninitialized : [ ] }
8
+ defstruct epoch: nil , slot: nil , head_root: nil , duties : % { } , validators : [ ]
9
9
10
10
require Logger
11
11
@@ -19,11 +19,12 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
19
19
epoch: Types . epoch ( ) | nil ,
20
20
slot: Types . slot ( ) | nil ,
21
21
head_root: Types . root ( ) | nil ,
22
+ duties: % { Types . epoch ( ) => % { proposers: Duties . proposers ( ) , attesters: Duties . attesters ( ) } } ,
22
23
validators: validators ( )
23
24
}
24
25
25
26
@ doc """
26
- Initiate the pool of validators, given the slot and head root.
27
+ Initiate the set of validators, given the slot and head root.
27
28
"""
28
29
@ spec init ( Types . slot ( ) , Types . root ( ) ) :: t ( )
29
30
def init ( slot , head_root ) do
@@ -57,8 +58,8 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
57
58
58
59
Logger . info ( "[Validator] Initialized #{ Enum . count ( validators ) } validators" )
59
60
60
- proposers = Duties . compute_proposers_for_epoch ( beacon , epoch , validators )
61
- attesters = Duties . compute_attesters_for_epoch ( beacon , epoch , validators )
61
+ { :ok , proposers } = Duties . compute_proposers_for_epoch ( beacon , epoch , validators )
62
+ { :ok , attesters } = Duties . compute_attesters_for_epoch ( beacon , epoch , validators )
62
63
63
64
Logger . info ( "[Validator] Proposers: #{ inspect ( proposers , pretty: true ) } " )
64
65
Logger . info ( "[Validator] Attesters: #{ inspect ( attesters , pretty: true ) } " )
@@ -67,11 +68,11 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
67
68
epoch: epoch ,
68
69
slot: slot ,
69
70
head_root: head_root ,
70
- validators: % {
71
+ duties: % { epoch => % {
71
72
proposers: proposers ,
72
- attesters: attesters ,
73
- uninitialized: validators
74
- }
73
+ attesters: attesters
74
+ } } ,
75
+ validators: validators
75
76
}
76
77
end
77
78
@@ -84,26 +85,62 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
84
85
Notify all validators of a new head.
85
86
"""
86
87
@ spec notify_head ( t ( ) , Types . slot ( ) , Types . root ( ) ) :: t ( )
87
- def notify_head ( % { validators: % { uninitialized: validators } } = pool , slot , head_root ) do
88
- uninitialized_validators =
89
- maybe_debug_notify (
90
- fn ->
91
- Map . new ( validators , fn { k , v } ->
92
- { k , Validator . handle_new_head ( slot , head_root , v ) }
93
- end )
94
- end ,
95
- { :new_head , slot , head_root }
96
- )
88
+ def notify_head ( % { validators: validators , epoch: epoch } = set , slot , head_root ) do
89
+ set
90
+ |> attest ( epoch , slot )
91
+ |> build_next_payload ( epoch , slot , head_root )
92
+ |> update_state ( slot , head_root )
93
+ end
97
94
98
- % { pool | validators: % { uninitialized: uninitialized_validators } }
95
+ defp update_state ( set , slot , head_root ) do
96
+ % { set | slot: slot , head_root: head_root }
99
97
end
100
98
99
+ defp attest ( set , epoch , slot ) do
100
+ updated_duties =
101
+ set
102
+ |> current_attesters ( epoch , slot )
103
+ |> Enum . map ( fn { validator , duty } ->
104
+ Validator . attest ( validator , duty )
105
+
106
+ # Duty.attested(duty)
107
+ % { duty | attested?: true }
108
+ end )
109
+
110
+ % { set | duties: put_in ( set . duties , [ set . epoch , :attesters , slot ] , updated_duties ) }
111
+ end
112
+
113
+ defp build_next_payload ( set , epoch , slot , head_root ) do
114
+ set
115
+ |> proposer ( epoch , slot + 1 )
116
+ |> case do
117
+ nil -> set
118
+ validator_index ->
119
+ validator = Map . get ( set . validators , validator_index )
120
+ updated_validator = Validator . start_payload_builder ( validator , slot + 1 , head_root )
121
+
122
+ % { set | validators: Map . put ( set . validators , updated_validator . validator . index , updated_validator ) }
123
+ end
124
+ end
125
+
126
+ defp current_attesters ( set , epoch , slot ) do
127
+ attesters ( set , epoch , slot )
128
+ |> Enum . flat_map ( fn
129
+ % { attested?: false } = duty -> [ { Map . get ( set . validators , duty . validator_index ) , duty } ]
130
+ _ -> [ ]
131
+ end )
132
+ end
133
+
134
+ defp proposer ( set , epoch , slot ) , do: get_in ( set . duties , [ epoch , :proposers , slot ] )
135
+ defp attesters ( set , epoch , slot ) , do: get_in ( set . duties , [ epoch , :attesters , slot ] ) || [ ]
136
+
137
+
101
138
@ doc """
102
139
Notify all validators of a new tick.
103
140
"""
104
141
@ spec notify_tick ( t ( ) , tuple ( ) ) :: t ( )
105
- def notify_tick ( % { validators: % { uninitialized: validators } } = pool , slot_data ) do
106
- uninitialized_validators =
142
+ def notify_tick ( % { validators: validators } = set , slot_data ) do
143
+ validators =
107
144
maybe_debug_notify (
108
145
fn ->
109
146
Map . new ( validators , fn { k , v } ->
@@ -113,7 +150,7 @@ defmodule LambdaEthereumConsensus.ValidatorSet do
113
150
{ :on_tick , slot_data }
114
151
)
115
152
116
- % { pool | validators: % { uninitialized: uninitialized_validators } }
153
+ % { set | validators: validators }
117
154
end
118
155
119
156
defp maybe_debug_notify ( fun , data ) do
0 commit comments