11use std:: collections:: HashMap ;
2+ use std:: time:: Instant ;
23
34use ethlambda_types:: {
45 attestation:: { AttestationData , XmssSignature } ,
56 primitives:: { H256 , HashTreeRoot as _} ,
67 signature:: { ValidatorSecretKey , ValidatorSignature } ,
78} ;
8- use tracing:: info;
9+ use tracing:: { info, warn } ;
910
1011use crate :: metrics;
1112
@@ -48,6 +49,14 @@ impl KeyManager {
4849 self . keys . keys ( ) . copied ( ) . collect ( )
4950 }
5051
52+ /// Advances every validator's XMSS preparation windows to cover slot
53+ pub fn advance_keys_to ( & mut self , slot : u32 ) {
54+ for ( validator_id, key_pair) in self . keys . iter_mut ( ) {
55+ advance_key ( * validator_id, & mut key_pair. attestation_key , slot) ;
56+ advance_key ( * validator_id, & mut key_pair. proposal_key , slot) ;
57+ }
58+ }
59+
5160 /// Signs an attestation using the validator's attestation key.
5261 pub fn sign_attestation (
5362 & mut self ,
@@ -85,6 +94,7 @@ impl KeyManager {
8594 // Multiple advances may be needed if the node was offline for an extended period.
8695 if !key_pair. attestation_key . is_prepared_for ( slot) {
8796 info ! ( validator_id, slot, "Advancing XMSS key preparation window" ) ;
97+ let start = Instant :: now ( ) ;
8898 while !key_pair. attestation_key . is_prepared_for ( slot) {
8999 let before = key_pair. attestation_key . get_prepared_interval ( ) ;
90100 key_pair. attestation_key . advance_preparation ( ) ;
@@ -95,6 +105,12 @@ impl KeyManager {
95105 ) ) ) ;
96106 }
97107 }
108+ info ! (
109+ validator_id,
110+ slot,
111+ elapsed_ms = start. elapsed( ) . as_millis( ) as u64 ,
112+ "Advanced XMSS key preparation window"
113+ ) ;
98114 }
99115
100116 let signature: ValidatorSignature = {
@@ -130,6 +146,7 @@ impl KeyManager {
130146 validator_id,
131147 slot, "Advancing XMSS proposal key preparation window"
132148 ) ;
149+ let start = Instant :: now ( ) ;
133150 while !key_pair. proposal_key . is_prepared_for ( slot) {
134151 let before = key_pair. proposal_key . get_prepared_interval ( ) ;
135152 key_pair. proposal_key . advance_preparation ( ) ;
@@ -140,6 +157,12 @@ impl KeyManager {
140157 ) ) ) ;
141158 }
142159 }
160+ info ! (
161+ validator_id,
162+ slot,
163+ elapsed_ms = start. elapsed( ) . as_millis( ) as u64 ,
164+ "Advanced XMSS proposal key preparation window"
165+ ) ;
143166 }
144167
145168 let signature: ValidatorSignature = key_pair
@@ -153,6 +176,28 @@ impl KeyManager {
153176 }
154177}
155178
179+ fn advance_key ( validator_id : u64 , key : & mut ValidatorSecretKey , slot : u32 ) {
180+ if key. is_prepared_for ( slot) {
181+ return ;
182+ }
183+ info ! ( validator_id, slot, "Advancing XMSS key preparation window" ) ;
184+ let start = Instant :: now ( ) ;
185+ while !key. is_prepared_for ( slot) {
186+ let before = key. get_prepared_interval ( ) ;
187+ key. advance_preparation ( ) ;
188+ if key. get_prepared_interval ( ) == before {
189+ warn ! ( validator_id, slot, "XMSS key activation interval exhausted" ) ;
190+ break ;
191+ }
192+ }
193+ info ! (
194+ validator_id,
195+ slot,
196+ elapsed_ms = start. elapsed( ) . as_millis( ) as u64 ,
197+ "Advanced XMSS key preparation window"
198+ ) ;
199+ }
200+
156201#[ cfg( test) ]
157202mod tests {
158203 use super :: * ;
0 commit comments