Skip to content

Commit a53ee89

Browse files
wemeetagainspiral-ladder
authored andcommitted
wip
1 parent 5f9a7b0 commit a53ee89

34 files changed

+1896
-4803
lines changed

build.zig

Lines changed: 70 additions & 182 deletions
Original file line numberDiff line numberDiff line change
@@ -3,216 +3,104 @@ const Compile = std.Build.Step.Compile;
33
const ResolvedTarget = std.Build.ResolvedTarget;
44
const OptimizeMode = std.builtin.OptimizeMode;
55

6-
// Although this function looks imperative, note that its job is to
7-
// declaratively construct a build graph that will be executed by an external
8-
// runner.
96
pub fn build(b: *std.Build) !void {
10-
// Standard target options allows the person running `zig build` to choose
11-
// what target to build for. Here we do not override the defaults, which
12-
// means any target is allowed, and the default is native. Other options
13-
// for restricting supported target set are available.
147
const target = b.standardTargetOptions(.{});
15-
16-
// Standard optimization options allow the person running `zig build` to select
17-
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
18-
// set a preferred release mode, allowing the user to decide how to optimize.
198
const optimize = b.standardOptimizeOption(.{});
9+
const portable = b.option(bool, "portable", "turn on portable mode") orelse false;
2010

21-
const blst_dep = b.dependency("blst", .{ .target = target, .optimize = optimize });
22-
23-
// passed by "zig build -Dportable=true"
24-
const portable = b.option(bool, "portable", "Enable portable implementation") orelse false;
25-
// passed by "zig build -Dforce-adx=true"
26-
const force_adx = b.option(bool, "force-adx", "Enable ADX optimizations") orelse false;
27-
28-
// build blst-z static library
29-
const staticLib = b.addStaticLibrary(.{
30-
.name = "blst-z",
31-
// In this case the main source file is merely a path, however, in more
32-
// complicated build scripts, this could be a generated file.
11+
// blst module (for downstream zig consumers)
12+
const blst_mod = b.addModule("blst", .{
3313
.root_source_file = b.path("src/root.zig"),
3414
.target = target,
3515
.optimize = optimize,
36-
});
37-
38-
const module_blst_min_pk = b.createModule(.{
39-
.root_source_file = b.path("src/root_min_pk.zig"),
40-
.target = target,
41-
.optimize = optimize,
42-
});
43-
try withBlst(blst_dep, module_blst_min_pk, target, false, portable, force_adx);
44-
45-
b.modules.put(b.dupe("blst_min_pk"), module_blst_min_pk) catch @panic("OOM");
46-
47-
const module_blst_min_sig = b.createModule(.{
48-
.root_source_file = b.path("src/root_min_sig.zig"),
49-
.target = target,
50-
.optimize = optimize,
51-
});
52-
try withBlst(blst_dep, module_blst_min_sig, target, false, portable, force_adx);
53-
b.modules.put(b.dupe("blst_min_sig"), module_blst_min_sig) catch @panic("OOM");
5416

55-
// blst does not need libc, however we need to link it to enable threading
56-
// see https://github.com/ChainSafe/blst-bun/issues/4
57-
staticLib.linkLibC();
58-
// the folder where blst.h is located
59-
try withBlst(blst_dep, staticLib.root_module, target, false, portable, force_adx);
60-
61-
// This declares intent for the library to be installed into the standard
62-
// location when the user invokes the "install" step (the default step when
63-
// running `zig build`).
64-
b.installArtifact(staticLib);
65-
66-
// build blst-z shared library
67-
const sharedLib = b.addSharedLibrary(.{
68-
.name = "blst_min_pk",
69-
.root_source_file = b.path("src/root_c_abi_min_pk.zig"),
70-
.target = target,
71-
.optimize = optimize,
17+
// blst does not need libc, however we need to link it to enable threading
18+
// see https://github.com/ChainSafe/blst-bun/issues/4
19+
.link_libc = true,
7220
});
73-
74-
// blst does not need libc, however we need to link it to enable threading
75-
// see https://github.com/ChainSafe/blst-bun/issues/4
76-
sharedLib.linkLibC();
77-
try withBlst(blst_dep, sharedLib.root_module, target, true, portable, force_adx);
78-
b.installArtifact(sharedLib);
79-
80-
const exe = b.addExecutable(.{
81-
.name = "blst-z",
82-
.root_source_file = b.path("src/main.zig"),
83-
.target = target,
84-
.optimize = optimize,
21+
try configureBlst(b, blst_mod, target, portable);
22+
23+
// blst dynamic library (for bun consumers)
24+
const blst_dylib = b.addLibrary(.{
25+
.root_module = b.createModule(.{
26+
.root_source_file = b.path("src/eth_c_abi.zig"),
27+
.target = target,
28+
.optimize = optimize,
29+
// blst does not need libc, however we need to link it to enable threading
30+
// see https://github.com/ChainSafe/blst-bun/issues/4
31+
.link_libc = true,
32+
.pic = true,
33+
}),
34+
.name = "eth_blst",
35+
.linkage = .dynamic,
8536
});
37+
try configureBlst(b, blst_dylib.root_module, target, portable);
8638

87-
// This declares intent for the executable to be installed into the
88-
// standard location when the user invokes the "install" step (the default
89-
// step when running `zig build`).
90-
b.installArtifact(exe);
91-
92-
// This *creates* a Run step in the build graph, to be executed when another
93-
// step is evaluated that depends on it. The next line below will establish
94-
// such a dependency.
95-
const run_cmd = b.addRunArtifact(exe);
96-
97-
// By making the run step depend on the install step, it will be run from the
98-
// installation directory rather than directly from within the cache directory.
99-
// This is not necessary, however, if the application depends on other installed
100-
// files, this ensures they will be present and in the expected location.
101-
run_cmd.step.dependOn(b.getInstallStep());
102-
103-
// This allows the user to pass arguments to the application in the build
104-
// command itself, like this: `zig build run -- arg1 arg2 etc`
105-
if (b.args) |args| {
106-
run_cmd.addArgs(args);
107-
}
108-
109-
// This creates a build step. It will be visible in the `zig build --help` menu,
110-
// and can be selected like this: `zig build run`
111-
// This will evaluate the `run` step rather than the default, which is "install".
112-
const run_step = b.step("run", "Run the app");
113-
run_step.dependOn(&run_cmd.step);
39+
b.installArtifact(blst_dylib);
11440

11541
// Creates a step for unit testing. This only builds the test executable
11642
// but does not run it.
117-
const lib_unit_tests = b.addTest(.{
118-
.root_source_file = b.path("src/root.zig"),
119-
.target = target,
120-
.optimize = optimize,
121-
});
122-
123-
try withBlst(blst_dep, lib_unit_tests.root_module, target, true, portable, force_adx);
124-
125-
const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
126-
127-
const exe_unit_tests = b.addTest(.{
128-
.root_source_file = b.path("src/main.zig"),
43+
const unit_tests = b.addTest(.{
44+
.root_module = blst_mod,
12945
.target = target,
13046
.optimize = optimize,
13147
});
13248

133-
const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
134-
135-
// Similar to creating the run step earlier, this exposes a `test` step to
136-
// the `zig build --help` menu, providing a way for the user to request
137-
// running the unit tests.
49+
const run_unit_tests = b.addRunArtifact(unit_tests);
13850
const test_step = b.step("test", "Run unit tests");
139-
test_step.dependOn(&run_lib_unit_tests.step);
140-
test_step.dependOn(&run_exe_unit_tests.step);
51+
test_step.dependOn(&run_unit_tests.step);
14152
}
14253

143-
/// instead of treating blst as a dependency lib, build and link it, we add its resource to our libs
144-
/// and zig will handle a mixture of C, assembly and Zig code
145-
/// reference to https://github.com/supranational/blst/blob/v0.3.13/bindings/rust/build.rs
146-
/// TODO: port all missing flows from the Rust build script
147-
fn withBlst(blst_dep: *std.Build.Dependency, module: *std.Build.Module, target: ResolvedTarget, is_shared_lib: bool, portable: bool, force_adx: bool) !void {
148-
module.addIncludePath(blst_dep.path("bindings"));
149-
// add later, once we have cflags
150-
const arch = target.result.cpu.arch;
151-
152-
// TODO: how to get target_env?
153-
// TODO: may have a separate build version for adx
154-
// then at Bun side, it has to detect if the target is x86_64 and has adx or not
155-
if (portable == true and force_adx == false) {
156-
// TODO: panic if target_env is sgx
157-
// use this instead
158-
module.addCMacro("__BLST_PORTABLE__", "");
159-
} else if (portable == false and force_adx == true) {
160-
if (arch == .x86_64) {
161-
module.addCMacro("__ADX__", "");
162-
} else {
163-
std.debug.print("`force-adx` is ignored for non-x86_64 targets \n", .{});
164-
}
165-
} else if (portable == false and force_adx == false) {
166-
// TODO: how to detect adx like this Rust call
167-
// if std::is_x86_feature_detected!("adx") {
168-
if (arch == .x86_64) {
169-
std.debug.print("ADX is turned on by default for x86_64 targets \n", .{});
170-
module.addCMacro("__ADX__", "");
171-
}
172-
// otherwise get: "undefined symbol redcx_mont_256" when run tests in Linux
173-
} else {
174-
// both are true
175-
@panic("Cannot set both `portable` and `force-adx` to true");
176-
}
177-
178-
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
179-
const allocator = gpa.allocator();
180-
181-
defer _ = gpa.deinit();
182-
183-
var cflags = std.ArrayList([]const u8).init(allocator);
54+
/// Configure the blst module, based on the upstream build.sh and build.rs
55+
/// reference https://github.com/supranational/blst/blob/v0.3.13/build.sh
56+
/// and https://github.com/supranational/blst/blob/v0.3.13/bindings/rust/build.rs
57+
/// TODO: port all missing flows
58+
fn configureBlst(b: *std.Build, blst_mod: *std.Build.Module, target: ResolvedTarget, portable: bool) !void {
59+
var cflags = std.ArrayList([]const u8).init(b.allocator);
18460
defer cflags.deinit();
18561

186-
// get this error in Mac arm: unsupported option '-mno-avx' for target 'aarch64-unknown-macosx15.1.0-unknown'
187-
if (arch == .x86_64) {
188-
try cflags.append("-mno-avx"); // avoid costly transitions
189-
}
190-
// the no_builtin should help, set here just to make sure
19162
try cflags.append("-fno-builtin");
19263
try cflags.append("-Wno-unused-function");
19364
try cflags.append("-Wno-unused-command-line-argument");
194-
195-
if (is_shared_lib) {
196-
try cflags.append("-fPIC");
65+
if (target.result.cpu.arch == .x86_64) {
66+
try cflags.append("-mno-avx"); // avoid costly transitions
19767
}
19868

199-
module.addCSourceFile(.{ .file = blst_dep.path("src/server.c"), .flags = cflags.items });
200-
module.addCSourceFile(.{ .file = blst_dep.path("build/assembly.S"), .flags = cflags.items });
201-
202-
// TODO: we may not need this since we linkLibC() above
203-
const os = target.result.os;
204-
// fix this error on Linux: 'stdlib.h' file not found
205-
// otherwise blst-bun cannot load the shared library on Linux
206-
// with error "Failed to open library. This is usually caused by a missing library or an invalid library path"
207-
if (os.tag == .linux) {
208-
// since "zig cc" works fine, we just follow it
209-
// zig cc -E -Wp,-v -
210-
module.addIncludePath(.{ .cwd_relative = "/usr/local/include" });
211-
module.addIncludePath(.{ .cwd_relative = "/usr/include" });
212-
if (arch == .x86_64) {
213-
module.addIncludePath(.{ .cwd_relative = "/usr/include/x86_64-linux-gnu" });
214-
} else if (arch == .aarch64) {
215-
module.addIncludePath(.{ .cwd_relative = "/usr/include/aarch64-linux-gnu" });
69+
if (portable) {
70+
blst_mod.addCMacro("__BLST_PORTABLE__", "");
71+
} else {
72+
if (std.Target.x86.featureSetHas(target.result.cpu.features, .adx)) {
73+
blst_mod.addCMacro("__ADX__", "");
21674
}
21775
}
76+
if (target.result.cpu.arch != .x86_64 and target.result.cpu.arch != .aarch64) {
77+
blst_mod.addCMacro("__BLST_NO_ASM__", "");
78+
}
79+
80+
blst_mod.addIncludePath(b.path("blst/bindings"));
81+
blst_mod.addCSourceFiles(.{
82+
.root = b.path("blst"),
83+
.files = &[_][]const u8{
84+
"src/server.c",
85+
"build/assembly.S",
86+
},
87+
.flags = cflags.items,
88+
});
89+
90+
// // TODO: we may not need this since we linkLibC() above
91+
// const os = target.result.os;
92+
// // fix this error on Linux: 'stdlib.h' file not found
93+
// // otherwise blst-bun cannot load the shared library on Linux
94+
// // with error "Failed to open library. This is usually caused by a missing library or an invalid library path"
95+
// if (os.tag == .linux) {
96+
// // since "zig cc" works fine, we just follow it
97+
// // zig cc -E -Wp,-v -
98+
// blst_mod.addIncludePath(.{ .cwd_relative = "/usr/local/include" });
99+
// blst_mod.addIncludePath(.{ .cwd_relative = "/usr/include" });
100+
// if (arch == .x86_64) {
101+
// blst_mod.addIncludePath(.{ .cwd_relative = "/usr/include/x86_64-linux-gnu" });
102+
// } else if (arch == .aarch64) {
103+
// blst_mod.addIncludePath(.{ .cwd_relative = "/usr/include/aarch64-linux-gnu" });
104+
// }
105+
// }
218106
}

bun/bun.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"": {
55
"name": "blst-bun",
66
"dependencies": {
7-
"@chainsafe/bun-ffi-z": "^v1.0.0",
7+
"@chainsafe/bun-ffi-z": "^1.1.1",
88
},
99
"devDependencies": {
1010
"@biomejs/biome": "^1.9.3",
@@ -83,7 +83,7 @@
8383

8484
"@chainsafe/benchmark": ["@chainsafe/[email protected]", "", { "dependencies": { "@actions/cache": "^4.0.0", "@actions/github": "^6.0.0", "@vitest/runner": "^2.1.8", "ajv": "^8.17.1", "aws-sdk": "^2.932.0", "cli-table3": "^0.6.5", "csv-parse": "^5.6.0", "csv-stringify": "^6.5.2", "debug": "^4.4.0", "glob": "^10.4.5", "log-symbols": "^7.0.0", "yaml": "^2.7.0", "yargs": "^17.7.2" }, "bin": { "benchmark": "bin/index.js" } }, "sha512-5rQKK2ar1k8DwqEMU5hTQlTrtrPzNdlfrMtbRgtrfYT/QpSADXGq1vBlywofY1D8HuEuv1LhRrn3p2rgibIXew=="],
8585

86-
"@chainsafe/bun-ffi-z": ["@chainsafe/bun-ffi-z@1.0.0", "", { "peerDependencies": { "typescript": "^5" }, "bin": { "bun-ffi-z": "src/cli.ts" } }, "sha512-IRQrGWvDVSWQOcNYPZqPeqMN8qRotad/84RHSxQ8xzIuhVhkpUp2lx4VeD92Tnkcwbp5Gr+tUT4Lb47nbIe1Xg=="],
86+
"@chainsafe/bun-ffi-z": ["@chainsafe/bun-ffi-z@1.1.1", "", { "peerDependencies": { "typescript": "^5" }, "bin": { "bun-ffi-z": "src/cli.ts" } }, "sha512-RSJhdS8Ytj3NuEvwshAFRI/y9/GbD1IhVuYEjVt0u16Hw2owDvVUVAgiN4/g8WWcFMhs8i5a4VXiFzK25fARSA=="],
8787

8888
"@colors/colors": ["@colors/[email protected]", "", {}, "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ=="],
8989

bun/package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"module": "src/index.ts",
55
"type": "module",
66
"dependencies": {
7-
"@chainsafe/bun-ffi-z": "^v1.0.0"
7+
"@chainsafe/bun-ffi-z": "^1.1.1"
88
},
99
"devDependencies": {
1010
"@types/bun": "latest",
@@ -20,6 +20,7 @@
2020
},
2121
"scripts": {
2222
"build": "bun ./node_modules/.bin/bun-ffi-z build",
23+
"generate": "bun ./node_modules/.bin/bun-ffi-z generate-binding",
2324
"prepublishOnly": "bun ./node_modules/.bin/bun-ffi-z prepublish --artifacts artifacts",
2425
"publish": "bun ./node_modules/.bin/bun-ffi-z publish",
2526
"test:unit": "bun test test/unit",
@@ -39,6 +40,9 @@
3940
"darwin-arm64"
4041
],
4142
"optimize": "ReleaseSafe",
42-
"zigCwd": ".."
43+
"zigCwd": "..",
44+
"zigExportFiles": [
45+
"src/eth_c_abi.zig"
46+
]
4347
}
4448
}

bun/src/aggregate.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {binding, writeUint8ArrayArray} from "./binding.js";
1+
import {binding} from "./binding.js";
22
import {MAX_AGGREGATE_PER_JOB} from "./const.js";
33
import {PublicKey, writePublicKeysReference} from "./publicKey.js";
44
import {Signature, writeSignaturesReference} from "./signature.js";
@@ -25,7 +25,7 @@ export function aggregatePublicKeys(pks: Array<PublicKey>, pksValidate?: boolean
2525
const pksBatch = pks.slice(i, Math.min(pks.length, i + MAX_AGGREGATE_PER_JOB));
2626
const pksRef = writePublicKeysReference(pksBatch);
2727
const outPk = PublicKey.defaultPublicKey();
28-
const res = binding.aggregatePublicKeys(outPk.blst_point, pksRef, pksBatch.length, pksValidate ?? false);
28+
const res = binding.aggregatePublicKeys(outPk.ptr, pksRef, pksBatch.length, pksValidate ?? false);
2929

3030
if (res !== 0) {
3131
throw new Error(`Failed to aggregate public keys: ${res}`);
@@ -52,7 +52,7 @@ export function aggregateSignatures(sigs: Array<Signature>, sigsGroupcheck?: boo
5252
const sigsBatch = sigs.slice(i, Math.min(sigs.length, i + MAX_AGGREGATE_PER_JOB));
5353
const sigsRef = writeSignaturesReference(sigsBatch);
5454
const outSig = Signature.defaultSignature();
55-
const res = binding.aggregateSignatures(outSig.blst_point, sigsRef, sigsBatch.length, sigsGroupcheck ?? false);
55+
const res = binding.aggregateSignatures(outSig.ptr, sigsRef, sigsBatch.length, sigsGroupcheck ?? false);
5656

5757
if (res !== 0) {
5858
throw new Error(`Failed to aggregate signatures: ${res}`);
@@ -83,7 +83,7 @@ export function aggregateSerializedPublicKeys(
8383
const pksRef = writeSerializedPublicKeysReference(pksBatch);
8484
const outPk = PublicKey.defaultPublicKey();
8585
const res = binding.aggregateSerializedPublicKeys(
86-
outPk.blst_point,
86+
outPk.ptr,
8787
pksRef,
8888
pksBatch.length,
8989
pks[0].length,
@@ -119,7 +119,7 @@ export function aggregateSerializedSignatures(
119119
const sigsRef = writeSerializedSignaturesReference(sigsBatch);
120120
const outSig = Signature.defaultSignature();
121121
const res = binding.aggregateSerializedSignatures(
122-
outSig.blst_point,
122+
outSig.ptr,
123123
sigsRef,
124124
sigsBatch.length,
125125
sigs[0].length,

bun/src/aggregateWithRandomness.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export function aggregateWithRandomness(sets: Array<PkAndSerializedSig>): PkAndS
3838
const pkOut = PublicKey.defaultPublicKey();
3939
const sigOut = Signature.defaultSignature();
4040

41-
const res = binding.aggregateWithRandomness(refs, sets.length, pkOut.blst_point, sigOut.blst_point);
41+
const res = binding.aggregateWithRandomness(refs, sets.length, pkOut.ptr, sigOut.ptr);
4242

4343
if (res !== 0) {
4444
throw new Error("Failed to aggregate with randomness res = " + res);
@@ -114,8 +114,8 @@ export function asyncAggregateWithRandomness(sets: Array<PkAndSerializedSig>): P
114114
const res = binding.asyncAggregateWithRandomness(
115115
refs,
116116
sets.length,
117-
pkOut.blst_point,
118-
sigOut.blst_point,
117+
pkOut.ptr,
118+
sigOut.ptr,
119119
// it's noted in bun:ffi doc that using JSCallback.prototype.ptr is faster than JSCallback object
120120
jscallback.ptr
121121
);

0 commit comments

Comments
 (0)