@@ -19,6 +19,7 @@ pub const VALIDATOR_FLAG: &str = "validators";
19
19
pub const EXIT_EPOCH_FLAG : & str = "exit-epoch" ;
20
20
pub const SIGNATURE_FLAG : & str = "signature" ;
21
21
pub const EXIT_STATUS_FLAG : & str = "status" ;
22
+ pub const MERGE_FLAG : & str = "merge" ;
22
23
23
24
pub fn cli_app ( ) -> Command {
24
25
Command :: new ( CMD )
@@ -68,16 +69,37 @@ pub fn cli_app() -> Command {
68
69
Arg :: new ( EXIT_EPOCH_FLAG )
69
70
. long ( EXIT_EPOCH_FLAG )
70
71
. value_name ( "EPOCH" )
71
- . help ( "Provide the minimum epoch for processing voluntary exit." )
72
+ . help (
73
+ "Provide the minimum epoch for processing voluntary exit. \
74
+ This flag is typically used in combination with `--signature` to \
75
+ save the voluntary exit signature to a file for future use.",
76
+ )
72
77
. action ( ArgAction :: Set )
73
78
. display_order ( 0 ) ,
74
79
)
75
80
. arg (
76
81
Arg :: new ( SIGNATURE_FLAG )
77
82
. long ( SIGNATURE_FLAG )
78
- . help ( "Display the signature of the voluntary exit." )
83
+ . help (
84
+ "Generate the voluntary exit signature and save it to a file \
85
+ named {validator_pubkey}.json. Note: Using this without the \
86
+ `--beacon-node` flag will not publish the voluntary exit to the network.",
87
+ )
88
+ . help_heading ( FLAG_HEADER )
89
+ . action ( ArgAction :: SetTrue )
90
+ . display_order ( 0 ) ,
91
+ )
92
+ . arg (
93
+ Arg :: new ( MERGE_FLAG )
94
+ . long ( MERGE_FLAG )
95
+ . help (
96
+ "Merge the generated voluntary exit signatures into a single file named \
97
+ `all_validators.json`. This flag has to be used together with \
98
+ the `--signature` flag.",
99
+ )
79
100
. help_heading ( FLAG_HEADER )
80
101
. action ( ArgAction :: SetTrue )
102
+ . requires ( SIGNATURE_FLAG )
81
103
. display_order ( 0 ) ,
82
104
)
83
105
. arg (
@@ -99,6 +121,7 @@ pub struct ExitConfig {
99
121
pub beacon_url : Option < SensitiveUrl > ,
100
122
pub exit_epoch : Option < Epoch > ,
101
123
pub signature : bool ,
124
+ pub merge : bool ,
102
125
pub exit_status : bool ,
103
126
}
104
127
@@ -123,6 +146,7 @@ impl ExitConfig {
123
146
beacon_url : clap_utils:: parse_optional ( matches, BEACON_URL_FLAG ) ?,
124
147
exit_epoch : clap_utils:: parse_optional ( matches, EXIT_EPOCH_FLAG ) ?,
125
148
signature : matches. get_flag ( SIGNATURE_FLAG ) ,
149
+ merge : matches. get_flag ( MERGE_FLAG ) ,
126
150
exit_status : matches. get_flag ( EXIT_STATUS_FLAG ) ,
127
151
} )
128
152
}
@@ -149,6 +173,7 @@ async fn run<E: EthSpec>(config: ExitConfig) -> Result<(), String> {
149
173
beacon_url,
150
174
exit_epoch,
151
175
signature,
176
+ merge,
152
177
exit_status,
153
178
} = config;
154
179
@@ -158,6 +183,8 @@ async fn run<E: EthSpec>(config: ExitConfig) -> Result<(), String> {
158
183
validators_to_exit = validators. iter ( ) . map ( |v| v. validating_pubkey ) . collect ( ) ;
159
184
}
160
185
186
+ let mut exit_message_all = Vec :: new ( ) ;
187
+
161
188
for validator_to_exit in validators_to_exit {
162
189
// Check that the validators_to_exit is in the validator client
163
190
if !validators
@@ -174,13 +201,18 @@ async fn run<E: EthSpec>(config: ExitConfig) -> Result<(), String> {
174
201
175
202
if signature {
176
203
let exit_message_json = serde_json:: to_string ( & exit_message. data ) ;
204
+
177
205
match exit_message_json {
178
206
Ok ( json) => {
179
- // Save the exit message to a JSON file
180
- let file_path = format ! ( "validator_{}.json" , validator_to_exit) ;
181
- std:: fs:: write ( & file_path, json)
182
- . map_err ( |e| format ! ( "Failed to write exit message to file: {}" , e) ) ?;
183
- println ! ( "Exit message saved to {}" , file_path) ;
207
+ // Save the exit message to JSON file(s)
208
+ if merge {
209
+ exit_message_all. push ( json. clone ( ) ) ;
210
+ } else {
211
+ let file_path = format ! ( "{}.json" , validator_to_exit) ;
212
+ std:: fs:: write ( & file_path, json)
213
+ . map_err ( |e| format ! ( "Failed to write voluntary exit message to file: {}" , e) ) ?;
214
+ println ! ( "Voluntary exit message saved to {}" , file_path) ;
215
+ }
184
216
}
185
217
Err ( e) => eprintln ! ( "Failed to serialize voluntary exit message: {}" , e) ,
186
218
}
@@ -324,6 +356,14 @@ async fn run<E: EthSpec>(config: ExitConfig) -> Result<(), String> {
324
356
}
325
357
}
326
358
}
359
+
360
+ if merge {
361
+ let all_json = serde_json:: to_string ( & exit_message_all)
362
+ . map_err ( |e| format ! ( "Failed to serialize voluntary exit message: {}" , e) ) ?;
363
+ std:: fs:: write ( "all_validators.json" , all_json)
364
+ . map_err ( |e| format ! ( "Failed to write all voluntary exit messages to file: {}" , e) ) ?;
365
+ println ! ( "All voluntary exit messages save to all_validators.json." )
366
+ }
327
367
Ok ( ( ) )
328
368
}
329
369
@@ -484,6 +524,7 @@ mod test {
484
524
beacon_url : Some ( beacon_url) ,
485
525
exit_epoch : None ,
486
526
signature : false ,
527
+ merge : false ,
487
528
exit_status : false ,
488
529
} ) ;
489
530
0 commit comments