Skip to content

Commit 82f8d15

Browse files
committed
chore: fix more tests
1 parent 81e836d commit 82f8d15

4 files changed

Lines changed: 55 additions & 47 deletions

File tree

bindings/napi/BeaconStateView.zig

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -224,24 +224,12 @@ pub fn BeaconStateView_latestExecutionPayloadHeader(env: napi.Env, cb: napi.Call
224224
pub fn BeaconStateView_historicalSummaries(env: napi.Env, cb: napi.CallbackInfo(0)) !napi.Value {
225225
const cached_state = try env.unwrap(CachedBeaconState, cb.this());
226226

227-
var historical_summaries = cached_state.state.historicalSummaries() catch {
228-
try env.throwError("STATE_ERROR", "Failed to get historicalSummaries");
229-
return env.getNull();
230-
};
227+
var historical_summaries_view = try cached_state.state.historicalSummaries();
228+
var historical_summaries = ct.capella.HistoricalSummaries.default_value;
229+
try historical_summaries_view.toValue(allocator, &historical_summaries);
230+
defer historical_summaries.deinit(allocator);
231231

232-
const size = historical_summaries.serializedSize() catch {
233-
try env.throwError("STATE_ERROR", "Failed to get historicalSummaries size");
234-
return env.getNull();
235-
};
236-
237-
var bytes: [*]u8 = undefined;
238-
const buf = try env.createArrayBuffer(size, &bytes);
239-
_ = historical_summaries.serializeIntoBytes(bytes[0..size]) catch {
240-
try env.throwError("STATE_ERROR", "Failed to serialize historicalSummaries");
241-
return env.getNull();
242-
};
243-
244-
return try env.createTypedarray(.uint8, size, buf, 0);
232+
return try sszValueToNapiValue(env, ct.capella.HistoricalSummaries, &historical_summaries);
245233
}
246234

247235
/// Get the pending deposits from the state (Electra+).
@@ -460,7 +448,12 @@ pub fn BeaconStateView_currentSyncCommitteeIndexed(env: napi.Env, cb: napi.Callb
460448
const obj = try env.createObject();
461449
try obj.setNamedProperty(
462450
"validatorIndices",
463-
try numberSliceToNapiValue(env, u32, @as([]const u32, @ptrCast(validator_indices)), .{ .typed_array = .uint32 }),
451+
try numberSliceToNapiValue(
452+
env,
453+
u32,
454+
@as([]const u32, @ptrCast(validator_indices)),
455+
.{ .typed_array = null },
456+
),
464457
);
465458

466459
const global = try env.getGlobal();
@@ -965,7 +958,7 @@ pub fn BeaconStateView_hashTreeRoot(env: napi.Env, cb: napi.CallbackInfo(0)) !na
965958
/// Arguments:
966959
/// - arg 0: target slot (number)
967960
/// - arg 1: options object (optional) with `transferCache` boolean
968-
pub fn BeaconStateView_processSlots(env: napi.Env, cb: napi.CallbackInfo(1)) !napi.Value {
961+
pub fn BeaconStateView_processSlots(env: napi.Env, cb: napi.CallbackInfo(2)) !napi.Value {
969962
const cached_state = try env.unwrap(CachedBeaconState, cb.this());
970963
const slot: u64 = @intCast(try cb.arg(0).getValueInt64());
971964

@@ -974,6 +967,7 @@ pub fn BeaconStateView_processSlots(env: napi.Env, cb: napi.CallbackInfo(1)) !na
974967
if (try options_arg.typeof() == .object) {
975968
if (try options_arg.hasNamedProperty("transferCache")) {
976969
transfer_cache = try (try options_arg.getNamedProperty("transferCache")).getValueBool();
970+
std.debug.print("has transferCache: {}\n", .{transfer_cache});
977971
}
978972
}
979973
}
@@ -1087,7 +1081,7 @@ pub fn register(env: napi.Env, exports: napi.Value) !void {
10871081
method(0, BeaconStateView_hashTreeRoot),
10881082

10891083
// method(2, BeaconStateView_stateTransition),
1090-
method(1, BeaconStateView_processSlots),
1084+
method(2, BeaconStateView_processSlots),
10911085
},
10921086
);
10931087
// Static method on constructor

bindings/test/beaconStateView.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ describe("BeaconStateView", () => {
341341
it("serialize should produce bytes matching original", () => {
342342
const serialized = state.serialize();
343343
expect(serialized.length).toBe(stateBytes.length);
344-
expect(serialized).toEqual(stateBytes);
344+
expect(Buffer.compare(serialized, stateBytes)).toBe(0);
345345
});
346346

347347
it("serializedSize should match actual serialized length", () => {
@@ -356,7 +356,7 @@ describe("BeaconStateView", () => {
356356
const bytesWritten = state.serializeToBytes(output, 0);
357357

358358
expect(bytesWritten).toBe(size);
359-
expect(output).toEqual(stateBytes);
359+
expect(Buffer.compare(output, stateBytes)).toBe(0);
360360
});
361361

362362
it("serializeValidators should produce valid validator bytes", () => {
@@ -378,9 +378,9 @@ describe("BeaconStateView", () => {
378378
expect(bytesWritten).toBe(size);
379379

380380
const expected = state.serializeValidators();
381-
expect(output).toEqual(expected);
381+
expect(Buffer.compare(output, expected)).toBe(0);
382382
});
383-
});
383+
}, 10_000); // slow
384384

385385
describe("hashTreeRoot", () => {
386386
it("hashTreeRoot should match lodestar", () => {

src/state_transition/cache/effective_balance_increments.zig

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ const ReferenceCount = @import("../utils/reference_count.zig").ReferenceCount;
77
pub const EffectiveBalanceIncrements = std.ArrayList(u16);
88
pub const EffectiveBalanceIncrementsRc = ReferenceCount(EffectiveBalanceIncrements);
99

10-
pub fn getEffectiveBalanceIncrementsZeroed(allocator: Allocator, len: usize) !EffectiveBalanceIncrements {
11-
var increments = try EffectiveBalanceIncrements.initCapacity(allocator, len);
10+
pub fn getEffectiveBalanceIncrementsZeroed(allocator: Allocator, len: usize, capacity: usize) !EffectiveBalanceIncrements {
11+
var increments = try EffectiveBalanceIncrements.initCapacity(allocator, capacity);
1212
try increments.resize(len);
1313
for (0..len) |i| {
1414
increments.items[i] = 0;
@@ -17,10 +17,11 @@ pub fn getEffectiveBalanceIncrementsZeroed(allocator: Allocator, len: usize) !Ef
1717
}
1818

1919
pub fn getEffectiveBalanceIncrementsWithLen(allocator: Allocator, validator_count: usize) !EffectiveBalanceIncrements {
20-
const len = 1024 * @divFloor(validator_count + 1024, 1024);
21-
return getEffectiveBalanceIncrementsZeroed(allocator, len);
20+
const capacity = 1024 * @divFloor(validator_count + 1024, 1024);
21+
return getEffectiveBalanceIncrementsZeroed(allocator, validator_count, capacity);
2222
}
2323

24+
/// unused, but may be useful for testing or other purposes
2425
pub fn getEffectiveBalanceIncrements(allocator: Allocator, state: AnyBeaconState) !EffectiveBalanceIncrements {
2526
const validators = try state.validatorsSlice(allocator);
2627
defer allocator.free(validators);

src/state_transition/cache/epoch_cache.zig

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ pub const EpochCache = struct {
110110
// next_active_indices
111111

112112
// EpochCache does not take ownership of EffectiveBalanceIncrements, it is shared across EpochCache instances
113-
effective_balance_increment: *EffectiveBalanceIncrementsRc,
113+
effective_balance_increments: *EffectiveBalanceIncrementsRc,
114114

115115
total_slashings_by_increment: u64,
116116

@@ -169,7 +169,7 @@ pub const EpochCache = struct {
169169
try syncPubkeys(validators, pubkey_to_index, index_to_pubkey);
170170
}
171171

172-
const effective_balance_increment = try getEffectiveBalanceIncrementsWithLen(allocator, validator_count);
172+
const effective_balance_increments = try getEffectiveBalanceIncrementsWithLen(allocator, validator_count);
173173
const state_fork_seq = state.forkSeq();
174174
const total_slashings_by_increment = switch (state_fork_seq) {
175175
inline else => |f| try getTotalSlashingsByIncrement(f, state.castToFork(f)),
@@ -188,15 +188,15 @@ pub const EpochCache = struct {
188188
const validator = validators[i];
189189

190190
// Note: Not usable for fork-choice balances since in-active validators are not zero'ed
191-
effective_balance_increment.items[i] = @intCast(@divFloor(validator.effective_balance, preset.EFFECTIVE_BALANCE_INCREMENT));
191+
effective_balance_increments.items[i] = @intCast(@divFloor(validator.effective_balance, preset.EFFECTIVE_BALANCE_INCREMENT));
192192

193193
if (isActiveValidator(&validator, previous_epoch)) {
194194
try previous_active_indices_array_list.append(i);
195195
}
196196

197197
if (isActiveValidator(&validator, current_epoch)) {
198198
try current_active_indices_array_list.append(i);
199-
total_active_balance_increments += effective_balance_increment.items[i];
199+
total_active_balance_increments += effective_balance_increments.items[i];
200200
}
201201

202202
if (isActiveValidator(&validator, next_epoch)) {
@@ -242,6 +242,7 @@ pub const EpochCache = struct {
242242
inline else => |f| try getSeed(f, state.castToFork(f), current_epoch, c.DOMAIN_BEACON_PROPOSER, &current_proposer_seed),
243243
}
244244
var proposers = [_]ValidatorIndex{0} ** preset.SLOTS_PER_EPOCH;
245+
var next_proposers: ?[preset.SLOTS_PER_EPOCH]ValidatorIndex = null;
245246
if (current_shuffling.active_indices.len > 0) {
246247
switch (fork_seq) {
247248
inline else => |f| try computeProposers(
@@ -250,10 +251,22 @@ pub const EpochCache = struct {
250251
current_proposer_seed,
251252
current_epoch,
252253
current_shuffling.active_indices,
253-
effective_balance_increment,
254+
effective_balance_increments,
254255
&proposers,
255256
),
256257
}
258+
if (fork_seq.gte(.fulu)) {
259+
// Post-Fulu, EIP-7917 introduced the `proposer_lookahead`
260+
switch (fork_seq) {
261+
inline else => |f| {
262+
next_proposers = undefined;
263+
var proposer_lookahead = try state.castToFork(f).proposerLookahead();
264+
for (0..preset.SLOTS_PER_EPOCH) |i| {
265+
next_proposers.?[i] = @intCast(try proposer_lookahead.get(preset.SLOTS_PER_EPOCH + i));
266+
}
267+
},
268+
}
269+
}
257270
}
258271

259272
// Only after altair, compute the indices of the current sync committee
@@ -341,14 +354,14 @@ pub const EpochCache = struct {
341354
.proposers = proposers,
342355
// On first epoch, set to null to prevent unnecessary work since this is only used for metrics
343356
.proposers_prev_epoch = null,
344-
.proposers_next_epoch = null,
357+
.proposers_next_epoch = next_proposers,
345358
.previous_decision_root = previous_decision_root,
346359
.current_decision_root = current_decision_root,
347360
.next_decision_root = next_decision_root,
348361
.previous_shuffling = try EpochShufflingRc.init(allocator, previous_shuffling),
349362
.current_shuffling = try EpochShufflingRc.init(allocator, current_shuffling),
350363
.next_shuffling = try EpochShufflingRc.init(allocator, next_shuffling),
351-
.effective_balance_increment = try EffectiveBalanceIncrementsRc.init(allocator, effective_balance_increment),
364+
.effective_balance_increments = try EffectiveBalanceIncrementsRc.init(allocator, effective_balance_increments),
352365
.total_slashings_by_increment = total_slashings_by_increment,
353366
.sync_participant_reward = sync_participant_reward,
354367
.sync_proposer_reward = sync_proposer_reward,
@@ -378,7 +391,7 @@ pub const EpochCache = struct {
378391
self.next_shuffling.release();
379392

380393
// unref the effective balance increments
381-
self.effective_balance_increment.release();
394+
self.effective_balance_increments.release();
382395

383396
// unref the sync committee caches
384397
self.current_sync_committee_indexed.release();
@@ -402,7 +415,7 @@ pub const EpochCache = struct {
402415
.current_shuffling = self.current_shuffling.acquire(),
403416
.next_shuffling = self.next_shuffling.acquire(),
404417
// reuse the same instances, increase reference count, cloned only when necessary before an epoch transition
405-
.effective_balance_increment = self.effective_balance_increment.acquire(),
418+
.effective_balance_increments = self.effective_balance_increments.acquire(),
406419
.total_slashings_by_increment = self.total_slashings_by_increment,
407420
// Basic types (numbers) cloned implicitly
408421
.sync_participant_reward = self.sync_participant_reward,
@@ -449,7 +462,7 @@ pub const EpochCache = struct {
449462

450463
/// Utility method to return SyncCommitteeCache so that consumers don't have to deal with ".get()" call
451464
pub fn getEffectiveBalanceIncrements(self: *const EpochCache) EffectiveBalanceIncrements {
452-
return self.effective_balance_increment.get();
465+
return self.effective_balance_increments.get();
453466
}
454467

455468
pub fn afterProcessEpoch(self: *EpochCache, state: *AnyBeaconState, epoch_transition_cache: *const EpochTransitionCache) !void {
@@ -526,7 +539,7 @@ pub const EpochCache = struct {
526539
upcoming_proposer_seed,
527540
self.epoch,
528541
self.current_shuffling.get().active_indices,
529-
self.effective_balance_increment.get(),
542+
self.effective_balance_increments.get(),
530543
&self.proposers,
531544
);
532545
}
@@ -536,11 +549,11 @@ pub const EpochCache = struct {
536549

537550
pub fn beforeEpochTransition(self: *EpochCache) !void {
538551
// Clone (copy) before being mutated in processEffectiveBalanceUpdates
539-
var effective_balance_increment = try EffectiveBalanceIncrements.initCapacity(self.allocator, self.effective_balance_increment.get().items.len);
540-
try effective_balance_increment.appendSlice(self.effective_balance_increment.get().items);
552+
var effective_balance_increment = try EffectiveBalanceIncrements.initCapacity(self.allocator, self.effective_balance_increments.get().items.len);
553+
try effective_balance_increment.appendSlice(self.effective_balance_increments.get().items);
541554
// unref the previous effective balance increment
542-
self.effective_balance_increment.release();
543-
self.effective_balance_increment = try EffectiveBalanceIncrementsRc.init(self.allocator, effective_balance_increment);
555+
self.effective_balance_increments.release();
556+
self.effective_balance_increments = try EffectiveBalanceIncrementsRc.init(self.allocator, effective_balance_increment);
544557
}
545558

546559
/// Consumer borrows the returned slice
@@ -770,14 +783,14 @@ pub const EpochCache = struct {
770783

771784
/// This is different from typescript version: only allocate new EffectiveBalanceIncrements if needed
772785
pub fn effectiveBalanceIncrementsSet(self: *EpochCache, allocator: Allocator, index: usize, effective_balance: u64) !void {
773-
var effective_balance_increments = self.effective_balance_increment.get();
786+
var effective_balance_increments = self.effective_balance_increments.get();
774787
if (index >= effective_balance_increments.items.len) {
775788
// Clone and extend effectiveBalanceIncrements
776789
effective_balance_increments = try getEffectiveBalanceIncrementsWithLen(self.allocator, index + 1);
777-
self.effective_balance_increment.release();
778-
self.effective_balance_increment = try EffectiveBalanceIncrementsRc.init(allocator, effective_balance_increments);
790+
self.effective_balance_increments.release();
791+
self.effective_balance_increments = try EffectiveBalanceIncrementsRc.init(allocator, effective_balance_increments);
779792
}
780-
self.effective_balance_increment.get().items[index] = @intCast(@divFloor(effective_balance, preset.EFFECTIVE_BALANCE_INCREMENT));
793+
self.effective_balance_increments.get().items[index] = @intCast(@divFloor(effective_balance, preset.EFFECTIVE_BALANCE_INCREMENT));
781794
}
782795

783796
pub fn isPostElectra(self: *const EpochCache) bool {

0 commit comments

Comments
 (0)