Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 50 additions & 104 deletions bench/state_transition/process_block.zig
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,22 @@ const Index2PubkeyCache = state_transition.Index2PubkeyCache;
const slotFromStateBytes = @import("utils.zig").slotFromStateBytes;
const loadState = @import("utils.zig").loadState;
const loadBlock = @import("utils.zig").loadBlock;
const BenchState = @import("utils.zig").BenchState;

const BenchOpts = struct {
verify_signature: bool,
};

fn ProcessBlockHeaderBench(comptime fork: ForkSeq) type {
return struct {
cached_state: *CachedBeaconState,
block: *const BeaconBlock(.full, fork),

pub fn run(self: *@This(), allocator: std.mem.Allocator) void {
const cloned = self.cached_state.clone(allocator, .{}) catch unreachable;
defer {
cloned.deinit();
allocator.destroy(cloned);
}

state_transition.processBlockHeader(
fork,
allocator,
cloned.epoch_cache,
cloned.state.castToFork(fork),
BenchState.cloned_cached_state.epoch_cache,
BenchState.cloned_cached_state.state.castToFork(fork),
.full,
self.block,
) catch unreachable;
Expand All @@ -58,16 +52,9 @@ fn ProcessBlockHeaderBench(comptime fork: ForkSeq) type {

fn ProcessWithdrawalsBench(comptime fork: ForkSeq) type {
return struct {
cached_state: *CachedBeaconState,
body: *const BeaconBlockBody(.full, fork),

pub fn run(self: *@This(), allocator: std.mem.Allocator) void {
const cloned = self.cached_state.clone(allocator, .{}) catch unreachable;
defer {
cloned.deinit();
allocator.destroy(cloned);
}

var withdrawals_result = WithdrawalsResult{
.withdrawals = Withdrawals.initCapacity(allocator, preset.MAX_WITHDRAWALS_PER_PAYLOAD) catch unreachable,
};
Expand All @@ -76,11 +63,11 @@ fn ProcessWithdrawalsBench(comptime fork: ForkSeq) type {
var withdrawal_balances = std.AutoHashMap(ValidatorIndex, usize).init(allocator);
defer withdrawal_balances.deinit();

const state = cloned.state.castToFork(fork);
const state = BenchState.cloned_cached_state.state.castToFork(fork);
state_transition.getExpectedWithdrawals(
fork,
allocator,
cloned.epoch_cache,
BenchState.cloned_cached_state.epoch_cache,
state,
&withdrawals_result,
&withdrawal_balances,
Expand All @@ -103,23 +90,16 @@ fn ProcessWithdrawalsBench(comptime fork: ForkSeq) type {

fn ProcessExecutionPayloadBench(comptime fork: ForkSeq) type {
return struct {
cached_state: *CachedBeaconState,
body: *const BeaconBlockBody(.full, fork),

pub fn run(self: *@This(), allocator: std.mem.Allocator) void {
const cloned = self.cached_state.clone(allocator, .{}) catch unreachable;
defer {
cloned.deinit();
allocator.destroy(cloned);
}

const external_data = BlockExternalData{ .execution_payload_status = .valid, .data_availability_status = .available };
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This line exceeds the 100-column limit defined in the style guide (Line 400). Hard limiting line lengths ensures better readability and avoids horizontal scrolling.

            const external_data = BlockExternalData{
                .execution_payload_status = .valid,
                .data_availability_status = .available,
            };
References
  1. Hard limit all line lengths, without exception, to at most 100 columns. (link)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also seems unrelated as the repo isn't enforcing any styling requirements atm, and this line is unaffected by the present changes.

state_transition.processExecutionPayload(
fork,
allocator,
cloned.config,
cloned.state.castToFork(fork),
cloned.epoch_cache.epoch,
BenchState.cloned_cached_state.config,
BenchState.cloned_cached_state.state.castToFork(fork),
BenchState.cloned_cached_state.epoch_cache.epoch,
.full,
self.body,
external_data,
Expand All @@ -130,22 +110,17 @@ fn ProcessExecutionPayloadBench(comptime fork: ForkSeq) type {

fn ProcessRandaoBench(comptime fork: ForkSeq, comptime opts: BenchOpts) type {
return struct {
cached_state: *CachedBeaconState,
block: *const BeaconBlock(.full, fork),
body: *const BeaconBlockBody(.full, fork),

pub fn run(self: *@This(), allocator: std.mem.Allocator) void {
const cloned = self.cached_state.clone(allocator, .{}) catch unreachable;
defer {
cloned.deinit();
allocator.destroy(cloned);
}
_ = allocator;

state_transition.processRandao(
fork,
cloned.config,
cloned.epoch_cache,
cloned.state.castToFork(fork),
BenchState.cloned_cached_state.config,
BenchState.cloned_cached_state.epoch_cache,
BenchState.cloned_cached_state.state.castToFork(fork),
.full,
self.body,
self.block.proposerIndex(),
Expand All @@ -157,19 +132,14 @@ fn ProcessRandaoBench(comptime fork: ForkSeq, comptime opts: BenchOpts) type {

fn ProcessEth1DataBench(comptime fork: ForkSeq) type {
return struct {
cached_state: *CachedBeaconState,
body: *const BeaconBlockBody(.full, fork),

pub fn run(self: *@This(), allocator: std.mem.Allocator) void {
const cloned = self.cached_state.clone(allocator, .{}) catch unreachable;
defer {
cloned.deinit();
allocator.destroy(cloned);
}
_ = allocator;

state_transition.processEth1Data(
fork,
cloned.state.castToFork(fork),
BenchState.cloned_cached_state.state.castToFork(fork),
self.body.eth1Data(),
) catch unreachable;
}
Expand All @@ -178,23 +148,16 @@ fn ProcessEth1DataBench(comptime fork: ForkSeq) type {

fn ProcessOperationsBench(comptime fork: ForkSeq, comptime opts: BenchOpts) type {
return struct {
cached_state: *CachedBeaconState,
body: *const BeaconBlockBody(.full, fork),

pub fn run(self: *@This(), allocator: std.mem.Allocator) void {
const cloned = self.cached_state.clone(allocator, .{}) catch unreachable;
defer {
cloned.deinit();
allocator.destroy(cloned);
}

state_transition.processOperations(
fork,
allocator,
cloned.config,
cloned.epoch_cache,
cloned.state.castToFork(fork),
&cloned.slashings_cache,
BenchState.cloned_cached_state.config,
BenchState.cloned_cached_state.epoch_cache,
BenchState.cloned_cached_state.state.castToFork(fork),
&BenchState.cloned_cached_state.slashings_cache,
.full,
self.body,
.{ .verify_signature = opts.verify_signature },
Expand All @@ -205,22 +168,15 @@ fn ProcessOperationsBench(comptime fork: ForkSeq, comptime opts: BenchOpts) type

fn ProcessSyncAggregateBench(comptime fork: ForkSeq, comptime opts: BenchOpts) type {
return struct {
cached_state: *CachedBeaconState,
body: *const BeaconBlockBody(.full, fork),

pub fn run(self: *@This(), allocator: std.mem.Allocator) void {
const cloned = self.cached_state.clone(allocator, .{}) catch unreachable;
defer {
cloned.deinit();
allocator.destroy(cloned);
}

state_transition.processSyncAggregate(
fork,
allocator,
cloned.config,
cloned.epoch_cache,
cloned.state.castToFork(fork),
BenchState.cloned_cached_state.config,
BenchState.cloned_cached_state.epoch_cache,
BenchState.cloned_cached_state.state.castToFork(fork),
self.body.syncAggregate(),
opts.verify_signature,
) catch unreachable;
Expand All @@ -230,24 +186,17 @@ fn ProcessSyncAggregateBench(comptime fork: ForkSeq, comptime opts: BenchOpts) t

fn ProcessBlockBench(comptime fork: ForkSeq, comptime opts: BenchOpts) type {
return struct {
cached_state: *CachedBeaconState,
block: *const BeaconBlock(.full, fork),

pub fn run(self: *@This(), allocator: std.mem.Allocator) void {
const cloned = self.cached_state.clone(allocator, .{}) catch unreachable;
defer {
cloned.deinit();
allocator.destroy(cloned);
}

const external_data = BlockExternalData{ .execution_payload_status = .valid, .data_availability_status = .available };
state_transition.processBlock(
fork,
allocator,
cloned.config,
cloned.epoch_cache,
cloned.state.castToFork(fork),
&cloned.slashings_cache,
BenchState.cloned_cached_state.config,
BenchState.cloned_cached_state.epoch_cache,
BenchState.cloned_cached_state.state.castToFork(fork),
&BenchState.cloned_cached_state.slashings_cache,
.full,
self.block,
external_data,
Expand Down Expand Up @@ -308,22 +257,14 @@ fn printSegmentStats(stdout: *std.Io.Writer) !void {

fn ProcessBlockSegmentedBench(comptime fork: ForkSeq) type {
return struct {
cached_state: *CachedBeaconState,
block: *const BeaconBlock(.full, fork),
body: *const BeaconBlockBody(.full, fork),
io: std.Io,

pub fn run(self: *@This(), allocator: std.mem.Allocator) void {
const io = self.io;
const cloned = self.cached_state.clone(allocator, .{}) catch unreachable;
defer {
cloned.deinit();
allocator.destroy(cloned);
}

const state = cloned.state.castToFork(fork);
const epoch_cache = cloned.epoch_cache;

const state = BenchState.cloned_cached_state.state.castToFork(fork);
const epoch_cache = BenchState.cloned_cached_state.epoch_cache;
const block_start = time.timestampNow(io);

const header_start = time.timestampNow(io);
Expand Down Expand Up @@ -372,7 +313,7 @@ fn ProcessBlockSegmentedBench(comptime fork: ForkSeq) type {
state_transition.processExecutionPayload(
fork,
allocator,
cloned.config,
BenchState.cloned_cached_state.config,
state,
epoch_cache.epoch,
.full,
Expand All @@ -385,7 +326,7 @@ fn ProcessBlockSegmentedBench(comptime fork: ForkSeq) type {
const randao_start = time.timestampNow(io);
state_transition.processRandao(
fork,
cloned.config,
BenchState.cloned_cached_state.config,
epoch_cache,
state,
.full,
Expand All @@ -407,10 +348,10 @@ fn ProcessBlockSegmentedBench(comptime fork: ForkSeq) type {
state_transition.processOperations(
fork,
allocator,
cloned.config,
BenchState.cloned_cached_state.config,
epoch_cache,
state,
&cloned.slashings_cache,
&BenchState.cloned_cached_state.slashings_cache,
.full,
self.body,
.{ .verify_signature = true },
Expand All @@ -422,7 +363,7 @@ fn ProcessBlockSegmentedBench(comptime fork: ForkSeq) type {
state_transition.processSyncAggregate(
fork,
allocator,
cloned.config,
BenchState.cloned_cached_state.config,
epoch_cache,
state,
self.body.syncAggregate(),
Expand All @@ -445,6 +386,7 @@ pub fn main(init: std.process.Init) !void {
var stdout_buf: [4096]u8 = undefined;
var stdout_file_writer = std.Io.File.stdout().writer(io, &stdout_buf);
var stdout = &stdout_file_writer.interface;

var pool = try Node.Pool.init(allocator, 10_000_000);
defer pool.deinit();

Expand Down Expand Up @@ -536,6 +478,7 @@ fn runBenchmark(
.index_to_pubkey = index_pubkey_cache,
.pubkey_to_index = &pubkey_index_map,
}, .{ .skip_sync_committee_cache = !comptime fork.gte(.altair), .skip_sync_pubkeys = false });
BenchState.init(allocator, cached_state);
beacon_state = null;
defer {
cached_state.deinit();
Expand All @@ -553,37 +496,40 @@ fn runBenchmark(
try state_transition.buildSlashingsCacheFromStateIfNeeded(allocator, cached_state.state, &cached_state.slashings_cache);
try stdout.print("State: slot={}, validators={}\n", .{ try cached_state.state.slot(), try cached_state.state.validatorsCount() });

const hooks: zbench.Hooks = .{ .before_each = BenchState.beforeEach, .after_each = BenchState.afterEach };

var bench = zbench.Benchmark.init(allocator, .{
.iterations = 50,
});
defer bench.deinit();

try bench.addParam("block_header", &ProcessBlockHeaderBench(fork){ .cached_state = cached_state, .block = block }, .{});
try bench.addParam("block_header", &ProcessBlockHeaderBench(fork){ .block = block }, .{ .hooks = hooks });

if (comptime fork.gte(.capella)) {
try bench.addParam("withdrawals", &ProcessWithdrawalsBench(fork){ .cached_state = cached_state, .body = body }, .{});
try bench.addParam("withdrawals", &ProcessWithdrawalsBench(fork){ .body = body }, .{ .hooks = hooks });
}
if (comptime fork.gte(.bellatrix)) {
try bench.addParam("execution_payload", &ProcessExecutionPayloadBench(fork){ .cached_state = cached_state, .body = body }, .{});
try bench.addParam("execution_payload", &ProcessExecutionPayloadBench(fork){ .body = body }, .{ .hooks = hooks });
}

try bench.addParam("randao", &ProcessRandaoBench(fork, .{ .verify_signature = true }){ .cached_state = cached_state, .block = block, .body = body }, .{});
try bench.addParam("randao_no_sig", &ProcessRandaoBench(fork, .{ .verify_signature = false }){ .cached_state = cached_state, .block = block, .body = body }, .{});
try bench.addParam("eth1_data", &ProcessEth1DataBench(fork){ .cached_state = cached_state, .body = body }, .{});
try bench.addParam("operations", &ProcessOperationsBench(fork, .{ .verify_signature = true }){ .cached_state = cached_state, .body = body }, .{});
try bench.addParam("operations_no_sig", &ProcessOperationsBench(fork, .{ .verify_signature = false }){ .cached_state = cached_state, .body = body }, .{});
try bench.addParam("randao", &ProcessRandaoBench(fork, .{ .verify_signature = true }){ .block = block, .body = body }, .{ .hooks = hooks });
try bench.addParam("randao_no_sig", &ProcessRandaoBench(fork, .{ .verify_signature = false }){ .block = block, .body = body }, .{ .hooks = hooks });
try bench.addParam("eth1_data", &ProcessEth1DataBench(fork){ .body = body }, .{ .hooks = hooks });
try bench.addParam("operations", &ProcessOperationsBench(fork, .{ .verify_signature = true }){ .body = body }, .{ .hooks = hooks });
try bench.addParam("operations_no_sig", &ProcessOperationsBench(fork, .{ .verify_signature = false }){ .body = body }, .{ .hooks = hooks });

if (comptime fork.gte(.altair)) {
try bench.addParam("sync_aggregate", &ProcessSyncAggregateBench(fork, .{ .verify_signature = true }){ .cached_state = cached_state, .body = body }, .{});
try bench.addParam("sync_aggregate_no_sig", &ProcessSyncAggregateBench(fork, .{ .verify_signature = false }){ .cached_state = cached_state, .body = body }, .{});
try bench.addParam("sync_aggregate", &ProcessSyncAggregateBench(fork, .{ .verify_signature = true }){ .body = body }, .{ .hooks = hooks });
try bench.addParam("sync_aggregate_no_sig", &ProcessSyncAggregateBench(fork, .{ .verify_signature = false }){ .body = body }, .{ .hooks = hooks });
}

try bench.addParam("process_block", &ProcessBlockBench(fork, .{ .verify_signature = true }){ .cached_state = cached_state, .block = block }, .{});
try bench.addParam("process_block_no_sig", &ProcessBlockBench(fork, .{ .verify_signature = false }){ .cached_state = cached_state, .block = block }, .{});
try bench.addParam("process_block", &ProcessBlockBench(fork, .{ .verify_signature = true }){ .block = block }, .{ .hooks = hooks });
try bench.addParam("process_block_no_sig", &ProcessBlockBench(fork, .{ .verify_signature = false }){ .block = block }, .{ .hooks = hooks });

// // Segmented benchmark (step-by-step timing)
resetSegmentStats();
try bench.addParam("block(segments)", &ProcessBlockSegmentedBench(fork){ .cached_state = cached_state, .block = block, .body = body, .io = io }, .{});

try bench.addParam("block(segments)", &ProcessBlockSegmentedBench(fork){ .block = block, .body = body, .io = io }, .{ .hooks = hooks });

try bench.run(io, std.Io.File.stdout());
try printSegmentStats(stdout);
Expand Down
Loading
Loading