Skip to content

Commit 55de148

Browse files
Merge pull request #30 from ChainSafe/bing/state-transition-fn
A high level overview of the changes in this PR - implement block processing with sanity unit tests - move test_utils into state_transition - unOOP types - implement blinded types - implement state upgrade
2 parents 1285d3b + 3a39bea commit 55de148

File tree

123 files changed

+2382
-1576
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

123 files changed

+2382
-1576
lines changed

build.zig

Lines changed: 159 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,48 @@ pub fn build(b: *std.Build) void {
88

99
const dep_ssz = b.dependency("ssz", .{});
1010

11+
const dep_blst_z = b.dependency("blst_z", .{});
12+
1113
const options_build_options = b.addOptions();
1214
const option_preset = b.option([]const u8, "preset", "") orelse "mainnet";
1315
options_build_options.addOption([]const u8, "preset", option_preset);
1416
const options_module_build_options = options_build_options.createModule();
1517

18+
const module_hex = b.createModule(.{
19+
.root_source_file = b.path("src/hex.zig"),
20+
.target = target,
21+
.optimize = optimize,
22+
});
23+
b.modules.put(b.dupe("hex"), module_hex) catch @panic("OOM");
24+
25+
const module_config = b.createModule(.{
26+
.root_source_file = b.path("src/config/root.zig"),
27+
.target = target,
28+
.optimize = optimize,
29+
});
30+
b.modules.put(b.dupe("config"), module_config) catch @panic("OOM");
31+
1632
const module_consensus_types = b.createModule(.{
1733
.root_source_file = b.path("src/consensus_types/root.zig"),
1834
.target = target,
1935
.optimize = optimize,
2036
});
2137
b.modules.put(b.dupe("consensus_types"), module_consensus_types) catch @panic("OOM");
2238

39+
const module_params = b.createModule(.{
40+
.root_source_file = b.path("src/params/root.zig"),
41+
.target = target,
42+
.optimize = optimize,
43+
});
44+
b.modules.put(b.dupe("params"), module_params) catch @panic("OOM");
45+
46+
const module_state_transition = b.createModule(.{
47+
.root_source_file = b.path("src/state_transition/root.zig"),
48+
.target = target,
49+
.optimize = optimize,
50+
});
51+
b.modules.put(b.dupe("state_transition"), module_state_transition) catch @panic("OOM");
52+
2353
const module_state_transition_utils = b.createModule(.{
2454
.root_source_file = b.path("src/lib_state_transition_utils.zig"),
2555
.target = target,
@@ -34,19 +64,46 @@ pub fn build(b: *std.Build) void {
3464
.linkage = .dynamic,
3565
});
3666

37-
const install_lib_state_transition_utils = b.addInstallArtifact(lib_state_transition_utils, .{
38-
});
67+
const install_lib_state_transition_utils = b.addInstallArtifact(lib_state_transition_utils, .{});
3968

4069
const tls_install_lib_state_transition_utils = b.step("build-lib:state_transition_utils", "Install the state_transition_utils library");
4170
tls_install_lib_state_transition_utils.dependOn(&install_lib_state_transition_utils.step);
4271
b.getInstallStep().dependOn(&install_lib_state_transition_utils.step);
4372

4473
const tls_run_test = b.step("test", "Run all tests");
4574

75+
const test_hex = b.addTest(.{
76+
.name = "hex",
77+
.root_module = module_hex,
78+
.filters = &[_][]const u8{},
79+
});
80+
const install_test_hex = b.addInstallArtifact(test_hex, .{});
81+
const tls_install_test_hex = b.step("build-test:hex", "Install the hex test");
82+
tls_install_test_hex.dependOn(&install_test_hex.step);
83+
84+
const run_test_hex = b.addRunArtifact(test_hex);
85+
const tls_run_test_hex = b.step("test:hex", "Run the hex test");
86+
tls_run_test_hex.dependOn(&run_test_hex.step);
87+
tls_run_test.dependOn(&run_test_hex.step);
88+
89+
const test_config = b.addTest(.{
90+
.name = "config",
91+
.root_module = module_config,
92+
.filters = &[_][]const u8{},
93+
});
94+
const install_test_config = b.addInstallArtifact(test_config, .{});
95+
const tls_install_test_config = b.step("build-test:config", "Install the config test");
96+
tls_install_test_config.dependOn(&install_test_config.step);
97+
98+
const run_test_config = b.addRunArtifact(test_config);
99+
const tls_run_test_config = b.step("test:config", "Run the config test");
100+
tls_run_test_config.dependOn(&run_test_config.step);
101+
tls_run_test.dependOn(&run_test_config.step);
102+
46103
const test_consensus_types = b.addTest(.{
47104
.name = "consensus_types",
48105
.root_module = module_consensus_types,
49-
.filters = &[_][]const u8{ },
106+
.filters = &[_][]const u8{},
50107
});
51108
const install_test_consensus_types = b.addInstallArtifact(test_consensus_types, .{});
52109
const tls_install_test_consensus_types = b.step("build-test:consensus_types", "Install the consensus_types test");
@@ -57,10 +114,38 @@ pub fn build(b: *std.Build) void {
57114
tls_run_test_consensus_types.dependOn(&run_test_consensus_types.step);
58115
tls_run_test.dependOn(&run_test_consensus_types.step);
59116

117+
const test_params = b.addTest(.{
118+
.name = "params",
119+
.root_module = module_params,
120+
.filters = &[_][]const u8{},
121+
});
122+
const install_test_params = b.addInstallArtifact(test_params, .{});
123+
const tls_install_test_params = b.step("build-test:params", "Install the params test");
124+
tls_install_test_params.dependOn(&install_test_params.step);
125+
126+
const run_test_params = b.addRunArtifact(test_params);
127+
const tls_run_test_params = b.step("test:params", "Run the params test");
128+
tls_run_test_params.dependOn(&run_test_params.step);
129+
tls_run_test.dependOn(&run_test_params.step);
130+
131+
const test_state_transition = b.addTest(.{
132+
.name = "state_transition",
133+
.root_module = module_state_transition,
134+
.filters = &[_][]const u8{},
135+
});
136+
const install_test_state_transition = b.addInstallArtifact(test_state_transition, .{});
137+
const tls_install_test_state_transition = b.step("build-test:state_transition", "Install the state_transition test");
138+
tls_install_test_state_transition.dependOn(&install_test_state_transition.step);
139+
140+
const run_test_state_transition = b.addRunArtifact(test_state_transition);
141+
const tls_run_test_state_transition = b.step("test:state_transition", "Run the state_transition test");
142+
tls_run_test_state_transition.dependOn(&run_test_state_transition.step);
143+
tls_run_test.dependOn(&run_test_state_transition.step);
144+
60145
const test_state_transition_utils = b.addTest(.{
61146
.name = "state_transition_utils",
62147
.root_module = module_state_transition_utils,
63-
.filters = &[_][]const u8{ },
148+
.filters = &[_][]const u8{},
64149
});
65150
const install_test_state_transition_utils = b.addInstallArtifact(test_state_transition_utils, .{});
66151
const tls_install_test_state_transition_utils = b.step("build-test:state_transition_utils", "Install the state_transition_utils test");
@@ -71,7 +156,77 @@ pub fn build(b: *std.Build) void {
71156
tls_run_test_state_transition_utils.dependOn(&run_test_state_transition_utils.step);
72157
tls_run_test.dependOn(&run_test_state_transition_utils.step);
73158

159+
const module_unit = b.createModule(.{
160+
.root_source_file = b.path("src/state_transition/root.zig"),
161+
.target = target,
162+
.optimize = optimize,
163+
});
164+
b.modules.put(b.dupe("unit"), module_unit) catch @panic("OOM");
165+
166+
const test_unit = b.addTest(.{
167+
.name = "unit",
168+
.root_module = module_unit,
169+
.filters = &[_][]const u8{},
170+
});
171+
const install_test_unit = b.addInstallArtifact(test_unit, .{});
172+
const tls_install_test_unit = b.step("build-test:unit", "Install the unit test");
173+
tls_install_test_unit.dependOn(&install_test_unit.step);
174+
175+
const run_test_unit = b.addRunArtifact(test_unit);
176+
const tls_run_test_unit = b.step("test:unit", "Run the unit test");
177+
tls_run_test_unit.dependOn(&run_test_unit.step);
178+
tls_run_test.dependOn(&run_test_unit.step);
179+
180+
const module_int = b.createModule(.{
181+
.root_source_file = b.path("test/int/root.zig"),
182+
.target = target,
183+
.optimize = optimize,
184+
});
185+
b.modules.put(b.dupe("int"), module_int) catch @panic("OOM");
186+
187+
const test_int = b.addTest(.{
188+
.name = "int",
189+
.root_module = module_int,
190+
.filters = &[_][]const u8{},
191+
});
192+
const install_test_int = b.addInstallArtifact(test_int, .{});
193+
const tls_install_test_int = b.step("build-test:int", "Install the int test");
194+
tls_install_test_int.dependOn(&install_test_int.step);
195+
196+
const run_test_int = b.addRunArtifact(test_int);
197+
const tls_run_test_int = b.step("test:int", "Run the int test");
198+
tls_run_test_int.dependOn(&run_test_int.step);
199+
tls_run_test.dependOn(&run_test_int.step);
200+
201+
module_config.addImport("build_options", options_module_build_options);
202+
module_config.addImport("params", module_params);
203+
module_config.addImport("consensus_types", module_consensus_types);
204+
module_config.addImport("hex", module_hex);
205+
74206
module_consensus_types.addImport("build_options", options_module_build_options);
75207
module_consensus_types.addImport("ssz", dep_ssz.module("ssz"));
76208

209+
module_params.addImport("build_options", options_module_build_options);
210+
module_params.addImport("consensus_types", module_consensus_types);
211+
212+
module_state_transition.addImport("build_options", options_module_build_options);
213+
module_state_transition.addImport("ssz", dep_ssz.module("ssz"));
214+
module_state_transition.addImport("config", module_config);
215+
module_state_transition.addImport("consensus_types", module_consensus_types);
216+
module_state_transition.addImport("blst_min_pk", dep_blst_z.module("blst_min_pk"));
217+
module_state_transition.addImport("params", module_params);
218+
219+
module_unit.addImport("build_options", options_module_build_options);
220+
module_unit.addImport("ssz", dep_ssz.module("ssz"));
221+
module_unit.addImport("state_transition", module_state_transition);
222+
module_unit.addImport("config", module_config);
223+
module_unit.addImport("params", module_params);
224+
module_unit.addImport("consensus_types", module_consensus_types);
225+
module_unit.addImport("blst_min_pk", dep_blst_z.module("blst_min_pk"));
226+
227+
module_int.addImport("build_options", options_module_build_options);
228+
module_int.addImport("ssz", dep_ssz.module("ssz"));
229+
module_int.addImport("state_transition", module_state_transition);
230+
module_int.addImport("config", module_config);
231+
module_int.addImport("consensus_types", module_consensus_types);
77232
}

build.zig.zon

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@
77
.minimum_zig_version = "0.14.0",
88
.dependencies = .{
99
.ssz = .{
10-
.url = "git+https://github.com/chainsafe/ssz-z.git#0ce9e59d2ade40d6cf5008ab34e6f59825b14c21",
11-
.hash = "ssz-0.1.0-yORmzFS_BAAKlIsLQVVuYdWCcQ4vR5Fuocndt5H-5Oky",
10+
.url = "git+https://github.com/ChainSafe/ssz-z.git#19e243fcd3556b763cd2dc3355ac54de64ca0d9c",
11+
.hash = "ssz-0.1.0-yORmzAXKBABgcjHn54mdHaCO8_AU1rdM-ZHfJcYppP1_",
1212
},
1313
.blst_z = .{
14-
.url = "git+https://github.com/ChainSafe/blst-z.git?ref=te/fix_state_transition#d32eae183f19e5171fcb95a9d9fff6b7a8a7e4f7",
15-
.hash = "blst_z-0.0.0-td3FNPapAgBsI_LW6ef2NWvGL56PNHvrSv7qEyp8vcFL",
14+
.url = "git+https://github.com/ChainSafe/blst-z.git#5f9a7b06e58dbf913329c2f0f8f7f8547eb87671",
15+
.hash = "blst_z-0.0.0-td3FNFusAgCb9QSUjHFnQpWzvxamthe1XjEGmLG57yTj",
16+
},
17+
.blst_min_pk = .{
18+
.url = "git+https://github.com/ChainSafe/blst-z.git#ece895f9ca8cb64f2217955d292c692c28157090",
19+
.hash = "blst_z-0.0.0-td3FNCmjAgBFbOvNv7GhKnPDUfJ0ApbwCOwN-9PajThg",
1620
},
1721
},
1822
.paths = .{ "build.zig", "build.zig.zon", "src" },

src/config/beacon_config.zig

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ const DOMAIN_VOLUNTARY_EXIT = params.DOMAIN_VOLUNTARY_EXIT;
1313
const ForkSeq = params.ForkSeq;
1414
const ForkInfo = params.ForkInfo;
1515
const TOTAL_FORKS = params.TOTAL_FORKS;
16-
const getForkSeqByForkName = params.getForkSeqByForkName;
16+
const forkSeqByForkName = params.forkSeqByForkName;
1717

18-
const DomainByTypeHashMap = std.AutoHashMap([]const u8, []const u8);
18+
const DomainByTypeHashMap = std.StringHashMap([]const u8);
1919
const DomainByTypeByFork = std.ArrayList(DomainByTypeHashMap);
2020

2121
pub const ChainConfig = @import("./chain/chain_config.zig").ChainConfig;
@@ -120,12 +120,12 @@ pub const BeaconConfig = struct {
120120
self.allocator.destroy(self);
121121
}
122122

123-
pub fn getForkInfo(self: *const BeaconConfig, slot: Slot) ForkInfo {
123+
pub fn forkInfo(self: *const BeaconConfig, slot: Slot) ForkInfo {
124124
const epoch = @divFloor(slot, preset.SLOTS_PER_EPOCH);
125-
return self.getForkInfoAtEpoch(epoch);
125+
return self.forkInfoAtEpoch(epoch);
126126
}
127127

128-
pub fn getForkInfoAtEpoch(self: *const BeaconConfig, epoch: Epoch) ForkInfo {
128+
pub fn forkInfoAtEpoch(self: *const BeaconConfig, epoch: Epoch) ForkInfo {
129129
// NOTE: forks must be sorted by descending epoch, latest fork first
130130
for (self.forks_descending_epoch_order) |fork| {
131131
if (epoch >= fork.epoch) {
@@ -137,73 +137,74 @@ pub const BeaconConfig = struct {
137137
return self.forks_ascending_epoch_order[@intFromEnum(ForkSeq.phase0)];
138138
}
139139

140-
pub fn getForkName(self: *const BeaconConfig, slot: Slot) []const u8 {
141-
return self.getForkInfo(slot).name;
140+
pub fn forkName(self: *const BeaconConfig, slot: Slot) []const u8 {
141+
return self.forkInfo(slot).name;
142142
}
143143

144-
pub fn getForkSeq(self: *const BeaconConfig, slot: Slot) ForkSeq {
145-
return self.getForkInfo(slot).fork_seq;
144+
pub fn forkSeq(self: *const BeaconConfig, slot: Slot) ForkSeq {
145+
return self.forkInfo(slot).fork_seq;
146146
}
147147

148-
pub fn getForkSeqAtEpoch(self: *const BeaconConfig, epoch: Epoch) ForkSeq {
149-
return self.getForkInfoAtEpoch(epoch).fork_seq;
148+
pub fn forkSeqAtEpoch(self: *const BeaconConfig, epoch: Epoch) ForkSeq {
149+
return self.forkInfoAtEpoch(epoch).fork_seq;
150150
}
151151

152-
pub fn getForkVersion(self: *const BeaconConfig, slot: Slot) [4]u8 {
153-
return self.getForkInfo(slot).version;
152+
pub fn forkVersion(self: *const BeaconConfig, slot: Slot) [4]u8 {
153+
return self.forkInfo(slot).version;
154154
}
155155

156-
// TODO: is getForkTypes() necessary?
156+
// TODO: is forkTypes() necessary?
157157
// TODO: getPostBellatrixForkTypes
158158
// TODO: getPostAltairForkTypes
159159
// TODO: getPostDenebForkTypes
160160
pub fn getMaxBlobsPerBlock(self: *const BeaconConfig, epoch: Epoch) u64 {
161-
const fork = self.getForkInfoAtEpoch(epoch).fork_seq;
161+
const fork = self.forkInfoAtEpoch(epoch).fork_seq;
162162
return switch (fork) {
163163
.deneb => self.chain.MAX_BLOBS_PER_BLOCK,
164164
.electra => self.chain.MAX_BLOBS_PER_BLOCK_ELECTRA,
165-
else => {
166-
// For forks before Deneb, we assume no blobs
167-
0;
168-
},
165+
else =>
166+
// For forks before Deneb, we assume no blobs
167+
0,
169168
};
170169
}
171170

172171
pub fn getMaxRequestBlobSidecars(self: *const BeaconConfig, fork: ForkSeq) u64 {
173172
return if (fork.isForkPostElectra()) self.chain.MAX_REQUEST_BLOB_SIDECARS_ELECTRA else self.chain.MAX_REQUEST_BLOB_SIDECARS;
174173
}
175174

176-
pub fn getDomain(self: *BeaconConfig, state_slot: Slot, domain_type: DomainType, message_slot: ?Slot) ![32]u8 {
175+
pub fn getDomain(self: *const BeaconConfig, state_slot: Slot, domain_type: DomainType, message_slot: ?Slot) ![32]u8 {
177176
const slot = if (message_slot) |s| s else state_slot;
178177
const epoch = @divFloor(slot, preset.SLOTS_PER_EPOCH);
179-
const state_fork_info = self.getForkInfo(state_slot);
178+
const state_fork_info = self.forkInfo(state_slot);
180179
const fork_seq = if (epoch < state_fork_info.epoch) state_fork_info.prev_fork_seq else state_fork_info.fork_seq;
181180

182181
return self.getDomainByForkSeq(fork_seq, domain_type);
183182
}
184183

185184
// TODO: may not need this method
186-
pub fn getDomainByForkName(self: *BeaconConfig, fork_name: []const u8, domain_type: DomainType) ![32]u8 {
187-
const fork_seq = getForkSeqByForkName(fork_name);
185+
pub fn getDomainByForkName(self: *const BeaconConfig, fork_name: []const u8, domain_type: DomainType) ![32]u8 {
186+
const fork_seq = forkSeqByForkName(fork_name);
188187
return try self.getDomainByForkSeq(fork_seq, domain_type);
189188
}
190189

191-
pub fn getDomainByForkSeq(self: *BeaconConfig, fork_seq: ForkSeq, domain_type: DomainType) ![32]u8 {
192-
if (fork_seq >= TOTAL_FORKS) return error.ForkSeqOutOfRange;
190+
pub fn getDomainByForkSeq(self: *const BeaconConfig, fork_seq: ForkSeq, domain_type: DomainType) ![32]u8 {
191+
if (@intFromEnum(fork_seq) >= TOTAL_FORKS) return error.ForkSeqOutOfRange;
193192

194-
const domain_by_type = self.domain_cache.items[@intFromEnum(fork_seq)];
195-
const domain = domain_by_type.get(domain_type) orelse {
193+
var domain_by_type = self.domain_cache.items[@intFromEnum(fork_seq)];
194+
var domain: [32]u8 = undefined;
195+
196+
if (domain_by_type.get(&domain_type)) |d| @memcpy(&domain, d) else {
196197
const out = try self.allocator.create([32]u8);
197198
const fork_info = self.forks_ascending_epoch_order[@intFromEnum(fork_seq)];
198-
computeDomain(domain_type, fork_info.version, self.genesis_validator_root, out);
199-
try domain_by_type.put(domain_type, out);
200-
return out;
201-
};
199+
try computeDomain(domain_type, fork_info.version, self.genesis_validator_root, out);
200+
try domain_by_type.put(&domain_type, out);
201+
@memcpy(&domain, out);
202+
}
202203

203-
return domain.*;
204+
return domain;
204205
}
205206

206-
pub fn getDomainForVoluntaryExit(self: *BeaconConfig, state_slot: Slot, message_slot: ?Slot) ![32]u8 {
207+
pub fn getDomainForVoluntaryExit(self: *const BeaconConfig, state_slot: Slot, message_slot: ?Slot) ![32]u8 {
207208
const domain = if (state_slot < self.chain.DENEB_FORK_EPOCH * preset.SLOTS_PER_EPOCH) {
208209
return self.getDomain(state_slot, DOMAIN_VOLUNTARY_EXIT, message_slot);
209210
} else {
@@ -217,17 +218,17 @@ pub const BeaconConfig = struct {
217218
// may not need it for state-transition
218219
};
219220

220-
fn computeDomain(domain_type: DomainType, fork_version: Version, genesis_validators_root: Root, out: *[32]u8) void {
221-
computeForkDataRoot(fork_version, genesis_validators_root, out);
221+
fn computeDomain(domain_type: DomainType, fork_version: Version, genesis_validators_root: Root, out: *[32]u8) !void {
222+
try computeForkDataRoot(fork_version, genesis_validators_root, out);
222223
std.mem.copyForwards(u8, out[0..], domain_type[0..]);
223224
}
224225

225-
fn computeForkDataRoot(current_version: Version, genesis_validators_root: Root, out: *[32]u8) void {
226+
fn computeForkDataRoot(current_version: Version, genesis_validators_root: Root, out: *[32]u8) !void {
226227
const fork_data: ForkData = .{
227228
.current_version = current_version,
228229
.genesis_validators_root = genesis_validators_root,
229230
};
230-
ssz.phase0.ForkData.hashTreeRoot(&fork_data, out);
231+
try ssz.phase0.ForkData.hashTreeRoot(&fork_data, out);
231232
}
232233

233234
// TODO: unit tests

0 commit comments

Comments
 (0)