Skip to content

Commit f7e1f21

Browse files
authored
bench: Add benchmark for block and Epoch Processing (#121)
tracks #102 - Adds benchmark for block and epoch transition - fix a bug in [`getAttestationDataSigningRoot` ](https://github.com/ChainSafe/lodestar/blob/688d5584ead0c6245007ece33175f6658169b662/packages/state-transition/src/signatureSets/indexedAttestation.ts#L15) - Unlock spec tests to test for proposer and signatures in state transition which was probably failing because of the above issue
1 parent 3c402de commit f7e1f21

File tree

9 files changed

+1163
-6
lines changed

9 files changed

+1163
-6
lines changed

bench/state_transition/process_block.zig

Lines changed: 399 additions & 0 deletions
Large diffs are not rendered by default.

bench/state_transition/process_epoch.zig

Lines changed: 614 additions & 0 deletions
Large diffs are not rendered by default.

bench/state_transition/utils.zig

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//! Shared utilities for state transition benchmarks
2+
3+
const std = @import("std");
4+
const types = @import("consensus_types");
5+
const config = @import("config");
6+
const state_transition = @import("state_transition");
7+
8+
const ForkSeq = config.ForkSeq;
9+
const BeaconStateAllForks = state_transition.BeaconStateAllForks;
10+
const Slot = types.primitive.Slot.Type;
11+
12+
/// Read slot from raw BeaconState SSZ bytes (offset 40)
13+
pub fn slotFromStateBytes(state_bytes: []const u8) Slot {
14+
std.debug.assert(state_bytes.len >= 48);
15+
return std.mem.readInt(u64, state_bytes[40..48], .little);
16+
}
17+
18+
/// Read slot from raw SignedBeaconBlock SSZ bytes (offset 100)
19+
pub fn slotFromBlockBytes(block_bytes: []const u8) Slot {
20+
std.debug.assert(block_bytes.len >= 108);
21+
return std.mem.readInt(u64, block_bytes[100..108], .little);
22+
}
23+
24+
/// Load and deserialize BeaconState from SSZ bytes for a specific fork
25+
pub fn loadState(comptime fork: ForkSeq, allocator: std.mem.Allocator, state_bytes: []const u8) !*BeaconStateAllForks {
26+
const BeaconState = @field(types, @tagName(fork)).BeaconState;
27+
const state_data = try allocator.create(BeaconState.Type);
28+
errdefer allocator.destroy(state_data);
29+
state_data.* = BeaconState.default_value;
30+
try BeaconState.deserializeFromBytes(allocator, state_bytes, state_data);
31+
32+
const beacon_state = try allocator.create(BeaconStateAllForks);
33+
beacon_state.* = @unionInit(BeaconStateAllForks, @tagName(fork), state_data);
34+
return beacon_state;
35+
}
36+
37+
/// Load and deserialize SignedBeaconBlock from SSZ bytes for a specific fork
38+
pub fn loadBlock(comptime fork: ForkSeq, allocator: std.mem.Allocator, block_bytes: []const u8) !state_transition.SignedBeaconBlock {
39+
const SignedBeaconBlock = @field(types, @tagName(fork)).SignedBeaconBlock;
40+
const block_data = try allocator.create(SignedBeaconBlock.Type);
41+
errdefer allocator.destroy(block_data);
42+
block_data.* = SignedBeaconBlock.default_value;
43+
try SignedBeaconBlock.deserializeFromBytes(allocator, block_bytes, block_data);
44+
return @unionInit(state_transition.SignedBeaconBlock, @tagName(fork), block_data);
45+
}

build.zig

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,52 @@ pub fn build(b: *std.Build) void {
379379
const tls_run_exe_bench_hashing = b.step("run:bench_hashing", "Run the bench_hashing executable");
380380
tls_run_exe_bench_hashing.dependOn(&run_exe_bench_hashing.step);
381381

382+
const module_bench_process_block = b.createModule(.{
383+
.root_source_file = b.path("bench/state_transition/process_block.zig"),
384+
.target = target,
385+
.optimize = optimize,
386+
});
387+
b.modules.put(b.dupe("bench_process_block"), module_bench_process_block) catch @panic("OOM");
388+
389+
const exe_bench_process_block = b.addExecutable(.{
390+
.name = "bench_process_block",
391+
.root_module = module_bench_process_block,
392+
});
393+
394+
const install_exe_bench_process_block = b.addInstallArtifact(exe_bench_process_block, .{});
395+
396+
const tls_install_exe_bench_process_block = b.step("build-exe:bench_process_block", "Install the bench_process_block executable");
397+
tls_install_exe_bench_process_block.dependOn(&install_exe_bench_process_block.step);
398+
b.getInstallStep().dependOn(&install_exe_bench_process_block.step);
399+
400+
const run_exe_bench_process_block = b.addRunArtifact(exe_bench_process_block);
401+
if (b.args) |args| run_exe_bench_process_block.addArgs(args);
402+
const tls_run_exe_bench_process_block = b.step("run:bench_process_block", "Run the bench_process_block executable");
403+
tls_run_exe_bench_process_block.dependOn(&run_exe_bench_process_block.step);
404+
405+
const module_bench_process_epoch = b.createModule(.{
406+
.root_source_file = b.path("bench/state_transition/process_epoch.zig"),
407+
.target = target,
408+
.optimize = optimize,
409+
});
410+
b.modules.put(b.dupe("bench_process_epoch"), module_bench_process_epoch) catch @panic("OOM");
411+
412+
const exe_bench_process_epoch = b.addExecutable(.{
413+
.name = "bench_process_epoch",
414+
.root_module = module_bench_process_epoch,
415+
});
416+
417+
const install_exe_bench_process_epoch = b.addInstallArtifact(exe_bench_process_epoch, .{});
418+
419+
const tls_install_exe_bench_process_epoch = b.step("build-exe:bench_process_epoch", "Install the bench_process_epoch executable");
420+
tls_install_exe_bench_process_epoch.dependOn(&install_exe_bench_process_epoch.step);
421+
b.getInstallStep().dependOn(&install_exe_bench_process_epoch.step);
422+
423+
const run_exe_bench_process_epoch = b.addRunArtifact(exe_bench_process_epoch);
424+
if (b.args) |args| run_exe_bench_process_epoch.addArgs(args);
425+
const tls_run_exe_bench_process_epoch = b.step("run:bench_process_epoch", "Run the bench_process_epoch executable");
426+
tls_run_exe_bench_process_epoch.dependOn(&run_exe_bench_process_epoch.step);
427+
382428
const tls_run_test = b.step("test", "Run all tests");
383429

384430
const test_constants = b.addTest(.{
@@ -675,6 +721,34 @@ pub fn build(b: *std.Build) void {
675721
tls_run_test_bench_hashing.dependOn(&run_test_bench_hashing.step);
676722
tls_run_test.dependOn(&run_test_bench_hashing.step);
677723

724+
const test_bench_process_block = b.addTest(.{
725+
.name = "bench_process_block",
726+
.root_module = module_bench_process_block,
727+
.filters = b.option([][]const u8, "bench_process_block.filters", "bench_process_block test filters") orelse &[_][]const u8{},
728+
});
729+
const install_test_bench_process_block = b.addInstallArtifact(test_bench_process_block, .{});
730+
const tls_install_test_bench_process_block = b.step("build-test:bench_process_block", "Install the bench_process_block test");
731+
tls_install_test_bench_process_block.dependOn(&install_test_bench_process_block.step);
732+
733+
const run_test_bench_process_block = b.addRunArtifact(test_bench_process_block);
734+
const tls_run_test_bench_process_block = b.step("test:bench_process_block", "Run the bench_process_block test");
735+
tls_run_test_bench_process_block.dependOn(&run_test_bench_process_block.step);
736+
tls_run_test.dependOn(&run_test_bench_process_block.step);
737+
738+
const test_bench_process_epoch = b.addTest(.{
739+
.name = "bench_process_epoch",
740+
.root_module = module_bench_process_epoch,
741+
.filters = b.option([][]const u8, "bench_process_epoch.filters", "bench_process_epoch test filters") orelse &[_][]const u8{},
742+
});
743+
const install_test_bench_process_epoch = b.addInstallArtifact(test_bench_process_epoch, .{});
744+
const tls_install_test_bench_process_epoch = b.step("build-test:bench_process_epoch", "Install the bench_process_epoch test");
745+
tls_install_test_bench_process_epoch.dependOn(&install_test_bench_process_epoch.step);
746+
747+
const run_test_bench_process_epoch = b.addRunArtifact(test_bench_process_epoch);
748+
const tls_run_test_bench_process_epoch = b.step("test:bench_process_epoch", "Run the bench_process_epoch test");
749+
tls_run_test_bench_process_epoch.dependOn(&run_test_bench_process_epoch.step);
750+
tls_run_test.dependOn(&run_test_bench_process_epoch.step);
751+
678752
const module_int = b.createModule(.{
679753
.root_source_file = b.path("test/int/root.zig"),
680754
.target = target,
@@ -858,6 +932,16 @@ pub fn build(b: *std.Build) void {
858932
module_bench_hashing.addImport("hashing", module_hashing);
859933
module_bench_hashing.addImport("zbench", dep_zbench.module("zbench"));
860934

935+
module_bench_process_block.addImport("state_transition", module_state_transition);
936+
module_bench_process_block.addImport("consensus_types", module_consensus_types);
937+
module_bench_process_block.addImport("config", module_config);
938+
module_bench_process_block.addImport("zbench", dep_zbench.module("zbench"));
939+
940+
module_bench_process_epoch.addImport("state_transition", module_state_transition);
941+
module_bench_process_epoch.addImport("consensus_types", module_consensus_types);
942+
module_bench_process_epoch.addImport("config", module_config);
943+
module_bench_process_epoch.addImport("zbench", dep_zbench.module("zbench"));
944+
861945
module_int.addImport("build_options", options_module_build_options);
862946
module_int.addImport("ssz", module_ssz);
863947
module_int.addImport("state_transition", module_state_transition);

src/state_transition/root.zig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ pub const processEth1Data = @import("./block/process_eth1_data.zig").processEth1
5656
pub const processOperations = @import("./block/process_operations.zig").processOperations;
5757
pub const processSyncAggregate = @import("./block/process_sync_committee.zig").processSyncAggregate;
5858
pub const processBlobKzgCommitments = @import("./block/process_blob_kzg_commitments.zig").processBlobKzgCommitments;
59+
pub const processBlock = @import("./block/process_block.zig").processBlock;
5960
pub const processAttestations = @import("./block/process_attestations.zig").processAttestations;
6061
pub const processAttesterSlashing = @import("./block/process_attester_slashing.zig").processAttesterSlashing;
6162
pub const processDeposit = @import("./block/process_deposit.zig").processDeposit;
@@ -78,9 +79,12 @@ pub const test_utils = @import("test_utils/root.zig");
7879
pub const bls = @import("utils/bls.zig");
7980
const seed = @import("./utils/seed.zig");
8081
pub const state_transition = @import("./state_transition.zig");
82+
pub const BlockExternalData = state_transition.BlockExternalData;
83+
pub const preset = @import("preset").preset;
8184
const EpochShuffling = @import("./utils/epoch_shuffling.zig");
8285
pub const SignedBlock = @import("./types/block.zig").SignedBlock;
8386
pub const Block = @import("./types/block.zig").Block;
87+
pub const Body = @import("./types/block.zig").Body;
8488
pub const SignedBeaconBlock = @import("./types/beacon_block.zig").SignedBeaconBlock;
8589
pub const Attestations = @import("./types/attestation.zig").Attestations;
8690
pub const processProposerLookahead = @import("./epoch/process_proposer_lookahead.zig").processProposerLookahead;

src/state_transition/signature_sets/indexed_attestation.zig

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ const PublicKey = blst.PublicKey;
55
const CachedBeaconStateAllForks = @import("../cache/state_cache.zig").CachedBeaconStateAllForks;
66
const BeaconBlock = @import("../types/beacon_block.zig").BeaconBlock;
77
const SignedBeaconBlock = @import("../types/beacon_block.zig").SignedBeaconBlock;
8-
const computeEpochAtSlot = @import("../utils/epoch.zig").computeEpochAtSlot;
98
const c = @import("constants");
109
const computeSigningRoot = @import("../utils/signing_root.zig").computeSigningRoot;
10+
const computeStartSlotAtEpoch = @import("../utils/epoch.zig").computeStartSlotAtEpoch;
1111
const types = @import("consensus_types");
12-
1312
const AttestationData = types.phase0.AttestationData.Type;
1413
const Attestation = types.primitive.Attestation.Type;
1514
const BLSSignature = types.primitive.BLSSignature.Type;
@@ -19,7 +18,7 @@ const createAggregateSignatureSetFromComponents = @import("../utils/signature_se
1918
const IndexedAttestation = @import("../types/attestation.zig").IndexedAttestation;
2019

2120
pub fn getAttestationDataSigningRoot(cached_state: *const CachedBeaconStateAllForks, data: *const AttestationData, out: *[32]u8) !void {
22-
const slot = computeEpochAtSlot(data.target.epoch);
21+
const slot = computeStartSlotAtEpoch(data.target.epoch);
2322
const config = cached_state.config;
2423
const state = cached_state.state;
2524
const domain = try config.getDomain(state.slot(), c.DOMAIN_BEACON_ATTESTER, slot);

src/state_transition/state_transition.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const Slot = types.primitive.Slot.Type;
1414
const CachedBeaconStateAllForks = @import("cache/state_cache.zig").CachedBeaconStateAllForks;
1515
pub const SignedBeaconBlock = @import("types/beacon_block.zig").SignedBeaconBlock;
1616
const verifyProposerSignature = @import("./signature_sets/proposer.zig").verifyProposerSignature;
17-
const processBlock = @import("./block/process_block.zig").processBlock;
17+
pub const processBlock = @import("./block/process_block.zig").processBlock;
1818
const BeaconBlock = @import("types/beacon_block.zig").BeaconBlock;
1919
const SignedVoluntaryExit = types.phase0.SignedVoluntaryExit.Type;
2020
const Attestation = @import("types/attestation.zig").Attestation;

test/spec/runner/transition.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ pub fn Transition(comptime fork: ForkSeq) type {
129129
},
130130
.{
131131
.verify_state_root = true,
132-
.verify_proposer = false,
133-
.verify_signatures = false,
132+
.verify_proposer = true,
133+
.verify_signatures = true,
134134
},
135135
);
136136

zbuild.zon

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,18 @@
183183
.imports = .{ .hashing, .zbench },
184184
},
185185
},
186+
.bench_process_block = .{
187+
.root_module = .{
188+
.root_source_file = "bench/state_transition/process_block.zig",
189+
.imports = .{ .state_transition, .consensus_types, .config, .zbench },
190+
},
191+
},
192+
.bench_process_epoch = .{
193+
.root_module = .{
194+
.root_source_file = "bench/state_transition/process_epoch.zig",
195+
.imports = .{ .state_transition, .consensus_types, .config, .zbench },
196+
},
197+
},
186198
},
187199
.tests = .{
188200
.int = .{

0 commit comments

Comments
 (0)