@@ -116,3 +116,113 @@ pub fn syncPubkeysParallel(
116116}
117117
118118// TODO: unit tests
119+
120+ const testing = std .testing ;
121+ const interop = @import ("../test_utils/interop_pubkeys.zig" );
122+
123+ test "syncPubkeys populates both caches" {
124+ const allocator = testing .allocator ;
125+ const count = 4 ;
126+
127+ var pubkeys : [count ]types.primitive.BLSPubkey.Type = undefined ;
128+ try interop .interopPubkeysCached (count , & pubkeys );
129+
130+ var validators : [count ]Validator = undefined ;
131+ for (0.. count ) | i | {
132+ validators [i ] = std .mem .zeroes (Validator );
133+ validators [i ].pubkey = pubkeys [i ];
134+ }
135+
136+ var pubkey_to_index = PubkeyIndexMap .init (allocator );
137+ defer pubkey_to_index .deinit ();
138+ var index_to_pubkey = Index2PubkeyCache .init (allocator );
139+ defer index_to_pubkey .deinit ();
140+
141+ try syncPubkeys (& validators , & pubkey_to_index , & index_to_pubkey );
142+
143+ try testing .expectEqual (@as (usize , count ), index_to_pubkey .items .len );
144+ try testing .expectEqual (@as (u32 , count ), pubkey_to_index .count ());
145+
146+ // Verify each pubkey maps to the correct index
147+ for (0.. count ) | i | {
148+ const idx = pubkey_to_index .get (pubkeys [i ]).? ;
149+ try testing .expectEqual (@as (u64 , i ), idx );
150+ }
151+ }
152+
153+ test "syncPubkeys incremental sync adds only new validators" {
154+ const allocator = testing .allocator ;
155+ const initial_count = 2 ;
156+ const total_count = 4 ;
157+
158+ var pubkeys : [total_count ]types.primitive.BLSPubkey.Type = undefined ;
159+ try interop .interopPubkeysCached (total_count , & pubkeys );
160+
161+ var validators : [total_count ]Validator = undefined ;
162+ for (0.. total_count ) | i | {
163+ validators [i ] = std .mem .zeroes (Validator );
164+ validators [i ].pubkey = pubkeys [i ];
165+ }
166+
167+ var pubkey_to_index = PubkeyIndexMap .init (allocator );
168+ defer pubkey_to_index .deinit ();
169+ var index_to_pubkey = Index2PubkeyCache .init (allocator );
170+ defer index_to_pubkey .deinit ();
171+
172+ // Initial sync with first 2 validators
173+ try syncPubkeys (validators [0.. initial_count ], & pubkey_to_index , & index_to_pubkey );
174+ try testing .expectEqual (@as (usize , initial_count ), index_to_pubkey .items .len );
175+
176+ // Incremental sync with all 4 validators
177+ try syncPubkeys (& validators , & pubkey_to_index , & index_to_pubkey );
178+ try testing .expectEqual (@as (usize , total_count ), index_to_pubkey .items .len );
179+ try testing .expectEqual (@as (u32 , total_count ), pubkey_to_index .count ());
180+
181+ // Verify all pubkeys are correctly mapped
182+ for (0.. total_count ) | i | {
183+ const idx = pubkey_to_index .get (pubkeys [i ]).? ;
184+ try testing .expectEqual (@as (u64 , i ), idx );
185+ }
186+ }
187+
188+ test "syncPubkeys no-op when already synced" {
189+ const allocator = testing .allocator ;
190+ const count = 2 ;
191+
192+ var pubkeys : [count ]types.primitive.BLSPubkey.Type = undefined ;
193+ try interop .interopPubkeysCached (count , & pubkeys );
194+
195+ var validators : [count ]Validator = undefined ;
196+ for (0.. count ) | i | {
197+ validators [i ] = std .mem .zeroes (Validator );
198+ validators [i ].pubkey = pubkeys [i ];
199+ }
200+
201+ var pubkey_to_index = PubkeyIndexMap .init (allocator );
202+ defer pubkey_to_index .deinit ();
203+ var index_to_pubkey = Index2PubkeyCache .init (allocator );
204+ defer index_to_pubkey .deinit ();
205+
206+ try syncPubkeys (& validators , & pubkey_to_index , & index_to_pubkey );
207+ // Second call should be no-op
208+ try syncPubkeys (& validators , & pubkey_to_index , & index_to_pubkey );
209+ try testing .expectEqual (@as (usize , count ), index_to_pubkey .items .len );
210+ }
211+
212+ test "syncPubkeys detects inconsistent cache" {
213+ const allocator = testing .allocator ;
214+
215+ var pubkey_to_index = PubkeyIndexMap .init (allocator );
216+ defer pubkey_to_index .deinit ();
217+ var index_to_pubkey = Index2PubkeyCache .init (allocator );
218+ defer index_to_pubkey .deinit ();
219+
220+ // Manually desync: add to pubkey_to_index but not index_to_pubkey
221+ const dummy_key = [_ ]u8 {0 } ** 48 ;
222+ try pubkey_to_index .put (dummy_key , 0 );
223+
224+ var validators : [1 ]Validator = undefined ;
225+ validators [0 ] = std .mem .zeroes (Validator );
226+
227+ try testing .expectError (error .InconsistentCache , syncPubkeys (& validators , & pubkey_to_index , & index_to_pubkey ));
228+ }
0 commit comments