Skip to content

Commit dfa8193

Browse files
committed
test(cache): add unit tests for effective_balance_increments and pubkey_cache
Add unit tests for two state transition caches that had explicit TODO comments requesting tests: - effective_balance_increments: test allocation, capacity rounding, zero init - pubkey_cache: test syncPubkeys populate, incremental sync, no-op, and inconsistent cache detection 🤖 Generated with AI assistance
1 parent a351e0e commit dfa8193

2 files changed

Lines changed: 151 additions & 0 deletions

File tree

src/state_transition/cache/effective_balance_increments.zig

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,44 @@ pub fn effectiveBalanceIncrementsInit(allocator: Allocator, validator_count: usi
2020
}
2121

2222
// TODO: unit tests
23+
24+
test "effectiveBalanceIncrementsInit basic allocation" {
25+
const allocator = std.testing.allocator;
26+
var increments = try effectiveBalanceIncrementsInit(allocator, 100);
27+
defer increments.deinit();
28+
29+
try std.testing.expectEqual(@as(usize, 100), increments.items.len);
30+
// Capacity should be rounded up to next 1024 boundary
31+
try std.testing.expectEqual(@as(usize, 1024), increments.capacity);
32+
// All values should be zero
33+
for (increments.items) |val| {
34+
try std.testing.expectEqual(@as(u16, 0), val);
35+
}
36+
}
37+
38+
test "effectiveBalanceIncrementsInit capacity rounding" {
39+
const allocator = std.testing.allocator;
40+
41+
// Exactly 1024 validators
42+
{
43+
var increments = try effectiveBalanceIncrementsInit(allocator, 1024);
44+
defer increments.deinit();
45+
try std.testing.expectEqual(@as(usize, 1024), increments.items.len);
46+
try std.testing.expectEqual(@as(usize, 2048), increments.capacity);
47+
}
48+
49+
// Just over 1024 boundary
50+
{
51+
var increments = try effectiveBalanceIncrementsInit(allocator, 1025);
52+
defer increments.deinit();
53+
try std.testing.expectEqual(@as(usize, 1025), increments.items.len);
54+
try std.testing.expectEqual(@as(usize, 2048), increments.capacity);
55+
}
56+
57+
// Zero validators
58+
{
59+
var increments = try effectiveBalanceIncrementsInit(allocator, 0);
60+
defer increments.deinit();
61+
try std.testing.expectEqual(@as(usize, 0), increments.items.len);
62+
}
63+
}

src/state_transition/cache/pubkey_cache.zig

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)