-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathbuild.zig
More file actions
916 lines (811 loc) · 43.7 KB
/
build.zig
File metadata and controls
916 lines (811 loc) · 43.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
const std = @import("std");
const Modules = @import("src/modules.build.zig");
const GuillotineExe = @import("src/build.zig");
const lib_build = @import("lib/build.zig");
// DevtoolExe removed - apps/ not included in package distribution
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
// Download KZG trusted setup if it doesn't exist
const kzg_path = "src/kzg/trusted_setup.txt";
std.fs.cwd().access(kzg_path, .{}) catch {
const download_kzg = b.addSystemCommand(&[_][]const u8{
"curl",
"-L",
"-o",
kzg_path,
"https://github.com/ethereum/c-kzg-4844/raw/main/src/trusted_setup.txt",
});
b.getInstallStep().dependOn(&download_kzg.step);
};
// Build configuration
const build_options = b.addOptions();
build_options.addOption(bool, "enable_tracing", b.option(bool, "enable-tracing", "Enable EVM instruction tracing") orelse false);
build_options.addOption(bool, "disable_tailcall_dispatch", b.option(bool, "disable-tailcall-dispatch", "Disable tailcall-based dispatch") orelse true);
build_options.addOption([]const u8, "hardfork", b.option([]const u8, "evm-hardfork", "EVM hardfork (default: CANCUN)") orelse "CANCUN");
build_options.addOption(bool, "disable_gas_checks", b.option(bool, "evm-disable-gas", "Disable gas checks for testing") orelse false);
build_options.addOption(bool, "enable_fusion", b.option(bool, "evm-enable-fusion", "Enable bytecode fusion") orelse true);
build_options.addOption([]const u8, "optimize_strategy", b.option([]const u8, "evm-optimize", "EVM optimization strategy") orelse "safe");
build_options.addOption(u11, "max_call_depth", b.option(u11, "max-call-depth", "Maximum call depth (default: 1024)") orelse 1024);
build_options.addOption(u12, "stack_size", b.option(u12, "stack-size", "Maximum stack size (default: 1024)") orelse 1024);
build_options.addOption(u32, "max_bytecode_size", b.option(u32, "max-bytecode-size", "Maximum bytecode size (default: 24576)") orelse 24576);
build_options.addOption(u32, "max_initcode_size", b.option(u32, "max-initcode-size", "Maximum initcode size (default: 49152)") orelse 49152);
build_options.addOption(u64, "block_gas_limit", b.option(u64, "block-gas-limit", "Block gas limit (default: 30000000)") orelse 30_000_000);
build_options.addOption(usize, "memory_initial_capacity", b.option(usize, "memory-initial-capacity", "Memory initial capacity (default: 4096)") orelse 4096);
build_options.addOption(u64, "memory_limit", b.option(u64, "memory-limit", "Memory limit (default: 0xFFFFFF)") orelse 0xFFFFFF);
build_options.addOption(usize, "arena_capacity_limit", b.option(usize, "arena-capacity-limit", "Arena capacity limit (default: 64MB)") orelse (64 * 1024 * 1024));
build_options.addOption(bool, "disable_balance_checks", b.option(bool, "disable-balance-checks", "Disable balance checks") orelse false);
const options_mod = build_options.createModule();
const rust_target = b: {
const os = target.result.os.tag;
const arch = target.result.cpu.arch;
break :b switch (os) {
.macos => switch (arch) {
.aarch64 => "aarch64-apple-darwin",
.x86_64 => "x86_64-apple-darwin",
else => "x86_64-apple-darwin",
},
.linux => switch (arch) {
.aarch64 => "aarch64-unknown-linux-gnu",
.x86_64 => "x86_64-unknown-linux-gnu",
else => "x86_64-unknown-linux-gnu",
},
.windows => "x86_64-pc-windows-msvc",
else => "x86_64-unknown-linux-gnu",
};
};
// Dependencies
const primitives_dep = b.dependency("voltaire", .{ .target = target, .optimize = optimize });
// Use Rust build step for Guillotine-specific libraries
const rust_build_step = lib_build.FoundryLib.createRustBuildStep(b, rust_target, optimize);
const bn254_lib = lib_build.Bn254Lib.createBn254Library(b, target, optimize, .{ .enable_tracy = false }, rust_build_step, rust_target);
const foundry_lib = lib_build.FoundryLib.createFoundryLibrary(b, target, optimize, rust_build_step, rust_target);
// Install Guillotine-specific libraries
if (bn254_lib) |bn254| b.installArtifact(bn254);
// Modules (zbench no longer needed for core evm_mod)
const modules = Modules.createModules(b, target, optimize, options_mod, primitives_dep, bn254_lib, foundry_lib);
// Executables
const guillotine_exe = GuillotineExe.createExecutable(b, modules.exe_mod);
_ = GuillotineExe.createRunStep(b, guillotine_exe);
// Bench runner executables are removed (moved to separate repo)
// Shared library for FFI bindings
const shared_lib_mod = b.createModule(.{
.root_source_file = b.path("src/evm_c_api.zig"),
.target = target,
.optimize = optimize,
});
shared_lib_mod.addImport("evm", modules.evm_mod);
shared_lib_mod.addImport("voltaire", modules.primitives_mod);
shared_lib_mod.addImport("crypto", modules.crypto_mod);
shared_lib_mod.addImport("build_options", options_mod);
const shared_lib = b.addLibrary(.{
.name = "guillotine_ffi",
.linkage = .dynamic,
.root_module = shared_lib_mod,
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
});
if (bn254_lib) |bn254| shared_lib.linkLibrary(bn254);
shared_lib.linkLibC();
// Export all symbols for Linux to ensure BLS symbols are available
shared_lib.rdynamic = true;
b.installArtifact(shared_lib);
const shared_lib_step = b.step("shared", "Build shared library for FFI");
shared_lib_step.dependOn(&b.addInstallArtifact(shared_lib, .{}).step);
// Also create a static library for Rust FFI
const static_lib = b.addLibrary(.{
.name = "guillotine_ffi_static",
.linkage = .static,
.root_module = shared_lib_mod,
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
});
if (bn254_lib) |bn254| static_lib.linkLibrary(bn254);
static_lib.linkLibC();
b.installArtifact(static_lib);
const static_lib_step = b.step("static", "Build static library for FFI");
static_lib_step.dependOn(&b.addInstallArtifact(static_lib, .{}).step);
// Test configuration options
const test_filter = b.option([]const u8, "test-filter", "Filter tests by pattern (applies to all test types)");
const test_verbose = b.option(bool, "test-verbose", "Enable verbose test output") orelse false;
const test_fail_fast = b.option(bool, "test-fail-fast", "Stop on first test failure") orelse false;
const test_no_color = b.option(bool, "test-no-color", "Disable colored output") orelse false;
const test_quiet = b.option(bool, "test-quiet", "Minimal output (dots only)") orelse false;
// Unit tests from src/root.zig (same as evm_mod, just run its tests)
const unit_tests = b.addTest(.{
.name = "unit-tests",
.root_module = modules.evm_mod,
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
// Temporarily disable custom test runner to debug
// .test_runner = .{ .path = b.path("test_runner.zig"), .mode = .simple },
});
if (test_filter) |filter| {
unit_tests.filters = &[_][]const u8{filter};
}
const run_unit_tests = b.addRunArtifact(unit_tests);
// Pass test configuration as environment variables for the custom runner
if (test_filter) |filter| {
run_unit_tests.setEnvironmentVariable("TEST_FILTER", filter);
}
if (test_verbose) run_unit_tests.setEnvironmentVariable("TEST_VERBOSE", "1");
if (test_fail_fast) run_unit_tests.setEnvironmentVariable("TEST_FAIL_FAST", "1");
if (test_no_color) run_unit_tests.setEnvironmentVariable("TEST_NO_COLOR", "1");
if (test_quiet) run_unit_tests.setEnvironmentVariable("TEST_QUIET", "1");
const unit_test_step = b.step("test-unit", "Run unit tests from src/**/*.zig");
unit_test_step.dependOn(&run_unit_tests.step);
// Library tests from lib/root.zig
const lib_tests = b.addTest(.{
.name = "lib-tests",
.root_module = b.createModule(.{
.root_source_file = b.path("lib/root.zig"),
.target = target,
.optimize = optimize,
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
.test_runner = .{ .path = b.path("test_runner.zig"), .mode = .simple },
});
if (foundry_lib) |foundry| {
lib_tests.linkLibrary(foundry);
lib_tests.addIncludePath(b.path("lib/foundry-compilers"));
}
if (bn254_lib) |bn254| lib_tests.linkLibrary(bn254);
lib_tests.linkLibC();
if (test_filter) |filter| {
lib_tests.filters = &[_][]const u8{filter};
}
const run_lib_tests = b.addRunArtifact(lib_tests);
// Pass test configuration as environment variables for the custom runner
if (test_filter) |filter| {
run_lib_tests.setEnvironmentVariable("TEST_FILTER", filter);
}
if (test_verbose) run_lib_tests.setEnvironmentVariable("TEST_VERBOSE", "1");
if (test_fail_fast) run_lib_tests.setEnvironmentVariable("TEST_FAIL_FAST", "1");
if (test_no_color) run_lib_tests.setEnvironmentVariable("TEST_NO_COLOR", "1");
if (test_quiet) run_lib_tests.setEnvironmentVariable("TEST_QUIET", "1");
const lib_test_step = b.step("test-lib", "Run library tests from lib/**/*.zig");
lib_test_step.dependOn(&run_lib_tests.step);
// Integration tests from test/root.zig
const integration_tests = b.addTest(.{
.name = "integration-tests",
.root_module = b.createModule(.{
.root_source_file = b.path("test/root.zig"),
.target = target,
.optimize = optimize,
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
.test_runner = .{ .path = b.path("test_runner.zig"), .mode = .simple },
});
integration_tests.root_module.addImport("evm", modules.evm_mod);
integration_tests.root_module.addImport("voltaire", modules.primitives_mod);
integration_tests.root_module.addImport("crypto", modules.crypto_mod);
integration_tests.root_module.addImport("compilers", modules.compilers_mod);
integration_tests.root_module.addImport("provider", modules.provider_mod);
integration_tests.root_module.addImport("trie", modules.trie_mod);
integration_tests.root_module.addImport("Guillotine_lib", modules.lib_mod);
if (bn254_lib) |bn254| integration_tests.linkLibrary(bn254);
integration_tests.linkLibC();
if (test_filter) |filter| {
integration_tests.filters = &[_][]const u8{filter};
}
const run_integration_tests = b.addRunArtifact(integration_tests);
// Pass test configuration as environment variables for the custom runner
if (test_filter) |filter| {
run_integration_tests.setEnvironmentVariable("TEST_FILTER", filter);
}
if (test_verbose) run_integration_tests.setEnvironmentVariable("TEST_VERBOSE", "1");
if (test_fail_fast) run_integration_tests.setEnvironmentVariable("TEST_FAIL_FAST", "1");
if (test_no_color) run_integration_tests.setEnvironmentVariable("TEST_NO_COLOR", "1");
if (test_quiet) run_integration_tests.setEnvironmentVariable("TEST_QUIET", "1");
const integration_test_step = b.step("test-integration", "Run integration tests from test/**/*.zig");
integration_test_step.dependOn(&run_integration_tests.step);
// Fixture tests - test all Solidity fixtures with both EVMs
const fixture_tests = b.addTest(.{
.name = "fixture-tests",
.root_module = b.createModule(.{
.root_source_file = b.path("test/fixtures.zig"),
.target = target,
.optimize = optimize,
}),
.use_llvm = true,
.test_runner = .{ .path = b.path("test_runner.zig"), .mode = .simple },
});
fixture_tests.root_module.addImport("evm", modules.evm_mod);
fixture_tests.root_module.addImport("voltaire", modules.primitives_mod);
if (bn254_lib) |bn254| fixture_tests.linkLibrary(bn254);
if (foundry_lib) |foundry| {
fixture_tests.linkLibrary(foundry);
fixture_tests.addIncludePath(b.path("lib/foundry-compilers"));
}
fixture_tests.linkLibC();
if (test_filter) |filter| {
fixture_tests.filters = &[_][]const u8{filter};
}
const run_fixture_tests = b.addRunArtifact(fixture_tests);
if (test_filter) |filter| {
run_fixture_tests.setEnvironmentVariable("TEST_FILTER", filter);
}
if (test_verbose) run_fixture_tests.setEnvironmentVariable("TEST_VERBOSE", "1");
if (test_fail_fast) run_fixture_tests.setEnvironmentVariable("TEST_FAIL_FAST", "1");
if (test_no_color) run_fixture_tests.setEnvironmentVariable("TEST_NO_COLOR", "1");
if (test_quiet) run_fixture_tests.setEnvironmentVariable("TEST_QUIET", "1");
const fixture_test_step = b.step("test-fixtures", "Run fixture tests comparing MainEvm and MinimalEvm");
fixture_test_step.dependOn(&run_fixture_tests.step);
// Main test step runs tests in priority order: specs -> integration -> unit
const test_step = b.step("test", "Run all tests (specs -> integration -> unit)");
// Mini EVM unit tests (guillotine-mini)
const mini_test_cmd = b.addSystemCommand(&.{ "zig", "build", "unit" });
mini_test_cmd.setCwd(b.path("mini"));
const mini_test_step = b.step("test-mini", "Run guillotine-mini unit tests");
mini_test_step.dependOn(&mini_test_cmd.step);
// Mini EVM full tests (requires Python dependencies for spec tests)
const mini_full_test_cmd = b.addSystemCommand(&.{ "zig", "build", "test" });
mini_full_test_cmd.setCwd(b.path("mini"));
const mini_full_test_step = b.step("test-mini-full", "Run all guillotine-mini tests (requires Python)");
mini_full_test_step.dependOn(&mini_full_test_cmd.step);
// Mini EVM specs tests
const mini_specs_cmd = b.addSystemCommand(&.{ "zig", "build", "specs" });
mini_specs_cmd.setCwd(b.path("mini"));
const mini_specs_step = b.step("test-mini-specs", "Run guillotine-mini spec tests");
mini_specs_step.dependOn(&mini_specs_cmd.step);
// ERC20 deployment gas issue test
const erc20_gas_test = b.addTest(.{
.name = "test-erc20-gas",
.root_module = b.createModule(.{
.root_source_file = b.path("test/erc20_deployment_gas_issue.zig"),
.target = target,
.optimize = .Debug, // Debug for better logging
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
});
erc20_gas_test.root_module.addImport("evm", modules.evm_mod);
erc20_gas_test.root_module.addImport("voltaire", modules.primitives_mod);
erc20_gas_test.root_module.addImport("crypto", modules.crypto_mod);
erc20_gas_test.root_module.addImport("build_options", options_mod);
erc20_gas_test.root_module.addImport("log", b.createModule(.{
.root_source_file = b.path("src/log.zig"),
.target = target,
.optimize = .Debug,
}));
if (bn254_lib) |bn254| erc20_gas_test.linkLibrary(bn254);
erc20_gas_test.linkLibC();
const run_erc20_gas_test = b.addRunArtifact(erc20_gas_test);
const erc20_gas_test_step = b.step("test-erc20-gas", "Test ERC20 deployment gas issue");
erc20_gas_test_step.dependOn(&run_erc20_gas_test.step);
// Jump table issue test
const jump_table_test = b.addTest(.{
.name = "test-jump-table",
.root_module = b.createModule(.{
.root_source_file = b.path("test/jump_table_issue.zig"),
.target = target,
.optimize = .Debug,
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
});
jump_table_test.root_module.addImport("evm", modules.evm_mod);
jump_table_test.root_module.addImport("voltaire", modules.primitives_mod);
jump_table_test.root_module.addImport("crypto", modules.crypto_mod);
jump_table_test.root_module.addImport("build_options", options_mod);
jump_table_test.root_module.addImport("log", b.createModule(.{
.root_source_file = b.path("src/log.zig"),
.target = target,
.optimize = .Debug,
}));
if (bn254_lib) |bn254| jump_table_test.linkLibrary(bn254);
jump_table_test.linkLibC();
const run_jump_table_test = b.addRunArtifact(jump_table_test);
const jump_table_test_step = b.step("test-jump-table", "Test jump table JUMPDEST recognition");
jump_table_test_step.dependOn(&run_jump_table_test.step);
// ERC20 deployment issue test
const erc20_deployment_test = b.addTest(.{
.name = "test-erc20-deployment",
.root_module = b.createModule(.{
.root_source_file = b.path("test/evm/erc20_deployment_issue.zig"),
.target = target,
.optimize = .Debug,
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
});
erc20_deployment_test.root_module.addImport("evm", modules.evm_mod);
erc20_deployment_test.root_module.addImport("voltaire", modules.primitives_mod);
erc20_deployment_test.root_module.addImport("crypto", modules.crypto_mod);
erc20_deployment_test.root_module.addImport("build_options", options_mod);
erc20_deployment_test.root_module.addImport("log", b.createModule(.{
.root_source_file = b.path("src/log.zig"),
.target = target,
.optimize = .Debug,
}));
// Using MinimalEvm for differential testing (REVM removed)
if (bn254_lib) |bn254| erc20_deployment_test.linkLibrary(bn254);
erc20_deployment_test.linkLibC();
const run_erc20_deployment_test = b.addRunArtifact(erc20_deployment_test);
const erc20_deployment_test_step = b.step("test-erc20-deployment", "Test ERC20 deployment issue");
erc20_deployment_test_step.dependOn(&run_erc20_deployment_test.step);
// Fixtures comprehensive differential test
const fixtures_differential_test = b.addTest(.{
.name = "fixtures-differential-test",
.root_module = b.createModule(.{
.root_source_file = b.path("test/differential/fixtures_comprehensive_differential_test.zig"),
.target = target,
.optimize = .Debug,
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
});
fixtures_differential_test.root_module.addImport("evm", modules.evm_mod);
fixtures_differential_test.root_module.addImport("voltaire", modules.primitives_mod);
fixtures_differential_test.root_module.addImport("crypto", modules.crypto_mod);
fixtures_differential_test.root_module.addImport("build_options", options_mod);
fixtures_differential_test.root_module.addImport("log", b.createModule(.{
.root_source_file = b.path("src/log.zig"),
.target = target,
.optimize = .Debug,
}));
// Using MinimalEvm for differential testing (REVM removed)
if (bn254_lib) |bn254| fixtures_differential_test.linkLibrary(bn254);
fixtures_differential_test.linkLibC();
const run_fixtures_differential_test = b.addRunArtifact(fixtures_differential_test);
const fixtures_differential_test_step = b.step("test-fixtures-differential", "Run differential tests for benchmark fixtures (ERC20, etc.)");
fixtures_differential_test_step.dependOn(&run_fixtures_differential_test.step);
// GT opcode bug test
const gt_bug_test = b.addTest(.{
.name = "gt-bug-test",
.root_module = b.createModule(.{
.root_source_file = b.path("test_gt_exact.zig"),
.target = target,
.optimize = .Debug,
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
});
gt_bug_test.root_module.addImport("evm", modules.evm_mod);
gt_bug_test.root_module.addImport("voltaire", modules.primitives_mod);
gt_bug_test.root_module.addImport("crypto", modules.crypto_mod);
gt_bug_test.root_module.addImport("build_options", options_mod);
gt_bug_test.root_module.addImport("log", b.createModule(.{
.root_source_file = b.path("src/log.zig"),
.target = target,
.optimize = .Debug,
}));
if (bn254_lib) |bn254| gt_bug_test.linkLibrary(bn254);
gt_bug_test.linkLibC();
const test_gt_bug = b.step("test-gt-bug", "Test GT opcode bug");
test_gt_bug.dependOn(&b.addRunArtifact(gt_bug_test).step);
// Development test for quick debugging
const dev_test = b.addTest(.{
.name = "dev-test",
.root_module = b.createModule(.{
.root_source_file = b.path("test/dev_test.zig"),
.target = target,
.optimize = .Debug,
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
});
dev_test.root_module.addImport("evm", modules.evm_mod);
dev_test.root_module.addImport("voltaire", modules.primitives_mod);
dev_test.root_module.addImport("crypto", modules.crypto_mod);
dev_test.root_module.addImport("build_options", options_mod);
if (bn254_lib) |bn254| dev_test.linkLibrary(bn254);
dev_test.linkLibC();
const test_dev = b.step("test-dev", "Run development test for debugging");
test_dev.dependOn(&b.addRunArtifact(dev_test).step);
// Per-opcode differential tests discovered in test/evm/opcodes
// We dynamically scan the directory and add a test target for each file matching *_test.zig
const opcode_tests_step = b.step("test-opcodes", "Run all per-opcode differential tests");
if (std.fs.cwd().openDir("test/evm/opcodes", .{ .iterate = true }) catch null) |op_dir_val| {
var op_dir = op_dir_val; // make mutable for close()
defer op_dir.close();
var it = op_dir.iterate();
while (it.next() catch null) |entry| {
if (entry.kind != .file) continue;
if (!std.mem.endsWith(u8, entry.name, "_test.zig")) continue;
const file_path = b.fmt("test/evm/opcodes/{s}", .{entry.name});
const test_name = b.fmt("opcode-{s}", .{entry.name});
// Extract opcode hex from filename (e.g., "01_test.zig" -> "0x01")
const opcode_hex = entry.name[0 .. std.mem.indexOf(u8, entry.name, "_") orelse continue];
const individual_step_name = b.fmt("test-opcodes-0x{s}", .{opcode_hex});
const individual_step_desc = b.fmt("Test opcode 0x{s}", .{opcode_hex});
const t = b.addTest(.{
.name = test_name,
.root_module = b.createModule(.{
.root_source_file = b.path(file_path),
.target = target,
.optimize = .Debug,
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
});
// Apply test filter if specified
if (test_filter) |filter| {
t.filters = &[_][]const u8{filter};
}
// Inject module dependencies used by the differential harness
t.root_module.addImport("evm", modules.evm_mod);
t.root_module.addImport("voltaire", modules.primitives_mod);
t.root_module.addImport("crypto", modules.crypto_mod);
t.root_module.addImport("build_options", options_mod);
t.root_module.addImport("log", b.createModule(.{
.root_source_file = b.path("src/log.zig"),
.target = target,
.optimize = .Debug,
}));
// Link external libs
if (bn254_lib) |bn254| t.linkLibrary(bn254);
t.linkLibC();
// Using MinimalEvm for differential testing (REVM removed)
const run_t = b.addRunArtifact(t);
// Add to the "all opcodes" step
opcode_tests_step.dependOn(&run_t.step);
// Create individual test step for this opcode
const individual_step = b.step(individual_step_name, individual_step_desc);
individual_step.dependOn(&run_t.step);
}
}
// ERC20 mint differential test
{
const erc20_mint_test = b.addTest(.{
.name = "erc20_mint_test",
.root_module = b.createModule(.{
.root_source_file = b.path("test/evm/erc20_mint_test.zig"),
.target = target,
.optimize = optimize,
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
});
// Add all the required dependencies
erc20_mint_test.root_module.addImport("evm", modules.evm_mod);
erc20_mint_test.root_module.addImport("voltaire", modules.primitives_mod);
erc20_mint_test.root_module.addImport("crypto", modules.crypto_mod);
// Using MinimalEvm for differential testing (REVM removed)
// Link other required libraries
if (bn254_lib) |bn254| erc20_mint_test.linkLibrary(bn254);
erc20_mint_test.linkLibC();
const run_erc20_mint_test = b.addRunArtifact(erc20_mint_test);
const erc20_mint_step = b.step("test-erc20-mint", "Run ERC20 mint differential test");
erc20_mint_step.dependOn(&run_erc20_mint_test.step);
}
// ERC20 transfer test
{
const erc20_transfer_test = b.addTest(.{
.name = "erc20_transfer_test",
.root_module = b.createModule(.{
.root_source_file = b.path("test/evm/erc20_transfer_test.zig"),
.target = target,
.optimize = optimize,
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
});
erc20_transfer_test.root_module.addImport("evm", modules.evm_mod);
erc20_transfer_test.root_module.addImport("voltaire", modules.primitives_mod);
erc20_transfer_test.root_module.addImport("crypto", modules.crypto_mod);
erc20_transfer_test.root_module.addImport("build_options", options_mod);
// Link required libraries
if (bn254_lib) |bn254| erc20_transfer_test.linkLibrary(bn254);
erc20_transfer_test.linkLibC();
const run_erc20_transfer_test = b.addRunArtifact(erc20_transfer_test);
const erc20_transfer_step = b.step("test-erc20-transfer", "Run ERC20 transfer test");
erc20_transfer_step.dependOn(&run_erc20_transfer_test.step);
}
// Static jumps test - temporarily disabled as file was removed
// TODO: Re-enable when test/evm/static_jumps.zig is restored
// {
// const static_jumps_test = b.addTest(.{
// .name = "static_jumps_test",
// .root_module = b.createModule(.{
// .root_source_file = b.path("test/evm/static_jumps.zig"),
// .target = target,
// .optimize = optimize,
// }),
// });
//
// static_jumps_test.root_module.addImport("evm", modules.evm_mod);
// static_jumps_test.root_module.addImport("voltaire", modules.primitives_mod);
// static_jumps_test.root_module.addImport("crypto", modules.crypto_mod);
// static_jumps_test.root_module.addImport("build_options", options_mod);
//
// // Link required libraries
// static_jumps_test.linkLibrary(c_kzg_lib);
// static_jumps_test.linkLibrary(blst_lib);
// if (bn254_lib) |bn254| static_jumps_test.linkLibrary(bn254);
// static_jumps_test.linkLibC();
//
// const run_static_jumps_test = b.addRunArtifact(static_jumps_test);
// const static_jumps_step = b.step("test-static-jumps", "Run static jumps test");
// static_jumps_step.dependOn(&run_static_jumps_test.step);
//
// // Add to main test step
// test_step.dependOn(&run_static_jumps_test.step);
// }
// CODECOPY+RETURN test
{
const codecopy_test = b.addTest(.{
.name = "codecopy_return_test",
.root_module = b.createModule(.{
.root_source_file = b.path("test/evm/codecopy_return_test.zig"),
.target = target,
.optimize = optimize,
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
});
codecopy_test.root_module.addImport("evm", modules.evm_mod);
codecopy_test.root_module.addImport("voltaire", modules.primitives_mod);
codecopy_test.root_module.addImport("crypto", modules.crypto_mod);
codecopy_test.root_module.addImport("build_options", options_mod);
const run_codecopy_test = b.addRunArtifact(codecopy_test);
const codecopy_step = b.step("test-codecopy-return", "Test CODECOPY and RETURN opcodes");
codecopy_step.dependOn(&run_codecopy_test.step);
}
// Official execution-spec state fixture smoke test
{
const official_state_test = b.addTest(.{
.name = "official_state_fixtures_smoke",
.root_module = b.createModule(.{
.root_source_file = b.path("test/official/state_smoke_test.zig"),
.target = target,
.optimize = optimize,
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
});
// Add required imports
official_state_test.root_module.addImport("evm", modules.evm_mod);
official_state_test.root_module.addImport("voltaire", modules.primitives_mod);
official_state_test.root_module.addImport("crypto", modules.crypto_mod);
official_state_test.root_module.addImport("build_options", options_mod);
// Link libraries used by EVM
if (bn254_lib) |bn254| official_state_test.linkLibrary(bn254);
official_state_test.linkLibC();
const run_official_state_test = b.addRunArtifact(official_state_test);
// Non-strict by default to avoid failing on WIP EVM differences
run_official_state_test.setEnvironmentVariable("OFFICIAL_STRICT", "0");
const official_state_step = b.step("test-official", "Run execution-spec state fixture smoke test (non-strict)");
official_state_step.dependOn(&run_official_state_test.step);
// Strict mode (will compare post-state and likely fail until parity improves)
const run_official_state_test_strict = b.addRunArtifact(official_state_test);
run_official_state_test_strict.setEnvironmentVariable("OFFICIAL_STRICT", "1");
const official_state_strict_step = b.step("test-official-strict", "Run execution-spec state fixture smoke test (strict)");
official_state_strict_step.dependOn(&run_official_state_test_strict.step);
}
// Official execution-spec blockchain fixture smoke test
{
const official_chain_test = b.addTest(.{
.name = "official_blockchain_fixtures_smoke",
.root_module = b.createModule(.{
.root_source_file = b.path("test/official/blockchain_smoke_test.zig"),
.target = target,
.optimize = optimize,
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
});
official_chain_test.root_module.addImport("evm", modules.evm_mod);
official_chain_test.root_module.addImport("voltaire", modules.primitives_mod);
official_chain_test.root_module.addImport("crypto", modules.crypto_mod);
official_chain_test.root_module.addImport("build_options", options_mod);
if (bn254_lib) |bn254| official_chain_test.linkLibrary(bn254);
official_chain_test.linkLibC();
const run_official_chain_test = b.addRunArtifact(official_chain_test);
run_official_chain_test.setEnvironmentVariable("OFFICIAL_STRICT", "0");
const official_chain_step = b.step("test-official-blockchain", "Run execution-spec blockchain fixture smoke test (non-strict)");
official_chain_step.dependOn(&run_official_chain_test.step);
const run_official_chain_test_strict = b.addRunArtifact(official_chain_test);
run_official_chain_test_strict.setEnvironmentVariable("OFFICIAL_STRICT", "1");
const official_chain_strict_step = b.step("test-official-blockchain-strict", "Run execution-spec blockchain fixture smoke test (strict)");
official_chain_strict_step.dependOn(&run_official_chain_test_strict.step);
}
// Synthetic opcodes tests
{
const synthetic_test = b.addTest(.{
.name = "synthetic_opcodes_test",
.root_module = b.createModule(.{
.root_source_file = b.path("src/evm/test_synthetic_opcodes.zig"),
.target = target,
.optimize = optimize,
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
});
// Add module imports needed by the test
synthetic_test.root_module.addImport("voltaire", modules.primitives_mod);
synthetic_test.root_module.addImport("crypto", modules.crypto_mod);
synthetic_test.root_module.addImport("build_options", options_mod);
if (bn254_lib) |bn254| synthetic_test.linkLibrary(bn254);
synthetic_test.linkLibC();
const run_synthetic_test = b.addRunArtifact(synthetic_test);
const synthetic_step = b.step("test-synthetic", "Test synthetic opcodes");
synthetic_step.dependOn(&run_synthetic_test.step);
}
// Zig specs runner (new default)
const specs_test = b.addTest(.{
.name = "ethereum-specs-test",
.root_module = b.createModule(.{
.root_source_file = b.path("specs/cases/root.zig"),
.target = target,
.optimize = .Debug,
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
.test_runner = .{ .path = b.path("test_runner.zig"), .mode = .simple },
});
specs_test.root_module.addImport("evm", modules.evm_mod);
specs_test.root_module.addImport("voltaire", modules.primitives_mod);
specs_test.root_module.addImport("crypto", modules.crypto_mod);
specs_test.root_module.addImport("build_options", options_mod);
const runner_module = b.createModule(.{
.root_source_file = b.path("specs/runner.zig"),
});
runner_module.addImport("evm", modules.evm_mod);
runner_module.addImport("voltaire", modules.primitives_mod);
specs_test.root_module.addImport("runner", runner_module);
if (bn254_lib) |bn254| specs_test.linkLibrary(bn254);
specs_test.linkLibC();
// Apply test filter if specified
if (test_filter) |filter| {
specs_test.filters = &[_][]const u8{filter};
}
const run_specs_test = b.addRunArtifact(specs_test);
// Pass test configuration as environment variables for the custom runner
if (test_filter) |filter| {
run_specs_test.setEnvironmentVariable("TEST_FILTER", filter);
}
if (test_verbose) run_specs_test.setEnvironmentVariable("TEST_VERBOSE", "1");
if (test_fail_fast) run_specs_test.setEnvironmentVariable("TEST_FAIL_FAST", "1");
if (test_no_color) run_specs_test.setEnvironmentVariable("TEST_NO_COLOR", "1");
if (test_quiet) run_specs_test.setEnvironmentVariable("TEST_QUIET", "1");
// Set MAX_SPEC_FILES environment variable
const spec_max_files = b.option([]const u8, "spec-max-files", "Maximum number of spec files to run (default: all)");
if (spec_max_files) |max_files| {
run_specs_test.setEnvironmentVariable("MAX_SPEC_FILES", max_files);
} else {
run_specs_test.setEnvironmentVariable("MAX_SPEC_FILES", "999999"); // Run all test files
}
// Set SKIP_SPEC_FILES environment variable to skip the first N files
const spec_skip_files = b.option([]const u8, "spec-skip-files", "Number of spec files to skip from the beginning");
if (spec_skip_files) |skip_files| {
run_specs_test.setEnvironmentVariable("SKIP_SPEC_FILES", skip_files);
}
const specs_step = b.step("specs", "Run Ethereum execution spec tests (Zig version) - use -Dspec-max-files=N to limit, -Dtest-filter=pattern to filter");
specs_step.dependOn(&run_specs_test.step);
// State tests runner using manifest
const state_tests = b.addTest(.{
.name = "state-tests",
.root_module = b.createModule(.{
.root_source_file = b.path("specs/cases/root.zig"),
.target = target,
.optimize = optimize,
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
.test_runner = .{ .path = b.path("test_runner.zig"), .mode = .simple },
});
state_tests.root_module.addImport("evm", modules.evm_mod);
state_tests.root_module.addImport("voltaire", modules.primitives_mod);
state_tests.root_module.addImport("crypto", modules.crypto_mod);
state_tests.root_module.addImport("build_options", options_mod);
state_tests.root_module.addImport("runner", runner_module); // Reuse runner_module from specs_test
if (bn254_lib) |bn254| state_tests.linkLibrary(bn254);
state_tests.linkLibC();
// Apply test filter if specified
if (test_filter) |filter| {
state_tests.filters = &[_][]const u8{filter};
}
const run_state_tests = b.addRunArtifact(state_tests);
// Pass test configuration as environment variables
if (test_filter) |filter| {
run_state_tests.setEnvironmentVariable("TEST_FILTER", filter);
}
if (test_verbose) run_state_tests.setEnvironmentVariable("TEST_VERBOSE", "1");
if (test_fail_fast) run_state_tests.setEnvironmentVariable("TEST_FAIL_FAST", "1");
if (test_no_color) run_state_tests.setEnvironmentVariable("TEST_NO_COLOR", "1");
if (test_quiet) run_state_tests.setEnvironmentVariable("TEST_QUIET", "1");
const state_tests_step = b.step("state-tests", "Run Ethereum state tests from manifest - use -Dtest-filter=pattern to filter");
state_tests_step.dependOn(&run_state_tests.step);
// Bun specs runner (kept as alternative)
const bun_check = b.addSystemCommand(&[_][]const u8{ "which", "bun" });
bun_check.addCheck(.{ .expect_stdout_match = "bun" });
const run_specs_bun = b.addSystemCommand(&[_][]const u8{ "bun", "test", "ethereum-specs.test.ts" });
run_specs_bun.setCwd(b.path("specs/bun-runner"));
run_specs_bun.step.dependOn(&bun_check.step);
// Set MAX_SPEC_FILES to run all tests by default for Bun version
if (spec_max_files) |max_files| {
run_specs_bun.setEnvironmentVariable("MAX_SPEC_FILES", max_files);
} else {
run_specs_bun.setEnvironmentVariable("MAX_SPEC_FILES", "999999"); // Run all test files
}
// Pass test filter to bun tests if specified
if (test_filter) |filter| {
run_specs_bun.setEnvironmentVariable("TEST_FILTER", filter);
}
const specs_bun_step = b.step("specs-bun", "Run Ethereum execution spec tests (Bun/TypeScript version) - use -Dspec-max-files=N to limit, -Dtest-filter=pattern to filter");
specs_bun_step.dependOn(&run_specs_bun.step);
// Language bindings
// Language bindings - TODO: Re-enable when SDK build files are created
// _ = WasmBindings.createWasmSteps(b, optimize, options_mod);
// _ = PythonBindings.createPythonSteps(b);
// _ = SwiftBindings.createSwiftSteps(b);
// _ = GoBindings.createGoSteps(b);
// _ = TypeScriptBindings.createTypeScriptSteps(b);
// Focused fusion tests aggregator
{
// Basic fusion detection and execution tests
const fusions_basic = b.addTest(.{
.name = "fusions_basic",
.root_module = b.createModule(.{
.root_source_file = b.path("test/fusions.zig"),
.target = target,
.optimize = .Debug,
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
});
fusions_basic.root_module.addImport("evm", modules.evm_mod);
fusions_basic.root_module.addImport("voltaire", modules.primitives_mod);
fusions_basic.root_module.addImport("crypto", modules.crypto_mod);
fusions_basic.root_module.addImport("build_options", options_mod);
fusions_basic.root_module.addImport("log", b.createModule(.{ .root_source_file = b.path("src/log.zig"), .target = target, .optimize = .Debug }));
if (bn254_lib) |bn254| fusions_basic.linkLibrary(bn254);
fusions_basic.linkLibC();
// Dispatch-specific fusion tests (jump resolution, etc.)
const fusions_dispatch = b.addTest(.{
.name = "fusions_dispatch",
.root_module = b.createModule(.{
.root_source_file = b.path("test/fusions_dispatch.zig"),
.target = target,
.optimize = .Debug,
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
});
fusions_dispatch.root_module.addImport("evm", modules.evm_mod);
fusions_dispatch.root_module.addImport("voltaire", modules.primitives_mod);
fusions_dispatch.root_module.addImport("crypto", modules.crypto_mod);
fusions_dispatch.root_module.addImport("build_options", options_mod);
fusions_dispatch.root_module.addImport("log", b.createModule(.{ .root_source_file = b.path("src/log.zig"), .target = target, .optimize = .Debug }));
if (bn254_lib) |bn254| fusions_dispatch.linkLibrary(bn254);
fusions_dispatch.linkLibC();
// Differential harness: non-fuseable pattern sanity check
const fusions_diff_toggle = b.addTest(.{
.name = "fusions_diff_toggle",
.root_module = b.createModule(.{
.root_source_file = b.path("test/differential/synthetic_toggle_test.zig"),
.target = target,
.optimize = .Debug,
}),
// Force LLVM backend: native Zig backend on Linux x86 doesn't support tail calls yet
.use_llvm = true,
});
fusions_diff_toggle.root_module.addImport("evm", modules.evm_mod);
fusions_diff_toggle.root_module.addImport("voltaire", modules.primitives_mod);
fusions_diff_toggle.root_module.addImport("crypto", modules.crypto_mod);
fusions_diff_toggle.root_module.addImport("build_options", options_mod);
fusions_diff_toggle.root_module.addImport("log", b.createModule(.{ .root_source_file = b.path("src/log.zig"), .target = target, .optimize = .Debug }));
// Using MinimalEvm for differential testing (REVM removed)
if (bn254_lib) |bn254| fusions_diff_toggle.linkLibrary(bn254);
fusions_diff_toggle.linkLibC();
const run_fusions_basic = b.addRunArtifact(fusions_basic);
const run_fusions_dispatch = b.addRunArtifact(fusions_dispatch);
const run_fusions_diff_toggle = b.addRunArtifact(fusions_diff_toggle);
const test_fusions_step = b.step("test-fusions", "Run focused fusion tests (unit + dispatch + differential)");
test_fusions_step.dependOn(&run_fusions_basic.step);
test_fusions_step.dependOn(&run_fusions_dispatch.step);
test_fusions_step.dependOn(&run_fusions_diff_toggle.step);
}
// Configure main test step dependencies in priority order:
// 1. First: Run specs tests (Ethereum compliance)
test_step.dependOn(specs_step);
// 2. Second: Run integration tests (test/**/*.zig)
test_step.dependOn(&run_integration_tests.step);
// 3. Third: Run unit tests (src/**/*.zig)
test_step.dependOn(&run_unit_tests.step);
// 4. Fourth: Run library tests (lib/**/*.zig)
test_step.dependOn(&run_lib_tests.step);
}