From b7a7ecf802d0518b4b1bcd8f4ed25858309bbbf5 Mon Sep 17 00:00:00 2001 From: Jon C Date: Sun, 17 Aug 2025 21:22:33 +0200 Subject: [PATCH 1/4] Fix account.info(), turn Pubkey back into bytes #### Problem `Account.info()` doesn't work with `PublicKey` as a packed struct because the alignment is incorrect. #### Summary of changes Make `PublicKey` back into an array of bytes, remove rent_epoch, and add a test to make sure the `info()` function works. --- src/account.zig | 36 ++++++++++++++++++++++++++++-------- src/public_key.zig | 14 +++++++------- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/account.zig b/src/account.zig index fa4c3f0..4389a7e 100644 --- a/src/account.zig +++ b/src/account.zig @@ -1,12 +1,13 @@ const std = @import("std"); const PublicKey = @import("public_key.zig").PublicKey; +const testing = std.testing; pub const ACCOUNT_DATA_PADDING = 10 * 1024; pub const Account = struct { pub const DATA_HEADER = 88; /// A Solana account sliced from what is provided as inputs to the BPF virtual machine. - pub const Data = packed struct { + pub const Data = extern struct { duplicate_index: u8, is_signer: u8, is_writable: u8, @@ -44,16 +45,16 @@ pub const Account = struct { data_len: u64, data: [*]u8, owner_id: *const PublicKey, - rent_epoch: u64, - is_signer: bool, - is_writable: bool, - is_executable: bool, + unused: u64 = undefined, + is_signer: u8, + is_writable: u8, + is_executable: u8, }; ptr: *Account.Data, pub fn fromDataPtr(ptr: *Account.Data) Account { - return Account { .ptr = ptr }; + return Account{ .ptr = ptr }; } pub fn id(self: Account) PublicKey { @@ -107,7 +108,6 @@ pub const Account = struct { pub fn info(self: Account) Account.Info { const data_ptr = @as([*]u8, @ptrFromInt(@intFromPtr(self.ptr))) + DATA_HEADER; - const rent_epoch = @as(*u64, @ptrFromInt(std.mem.alignForward(u64, @intFromPtr(self.ptr) + self.ptr.data_len + ACCOUNT_DATA_PADDING, @alignOf(u64)))); return .{ .id = &self.ptr.id, @@ -115,10 +115,30 @@ pub const Account = struct { .data_len = self.ptr.data_len, .data = data_ptr, .owner_id = &self.ptr.owner_id, - .rent_epoch = rent_epoch.*, .is_signer = self.ptr.is_signer, .is_writable = self.ptr.is_writable, .is_executable = self.ptr.is_executable, }; } }; + +test "account: create info from account" { + var data: Account.Data = .{ + .duplicate_index = 255, + .is_signer = 1, + .is_writable = 1, + .is_executable = 0, + .original_data_len = 10, + .id = PublicKey.from(.{1} ** 32), + .owner_id = PublicKey.from(.{2} ** 32), + .lamports = 1, + .data_len = 10, + }; + const account: Account = .{ .ptr = &data }; + const info = account.info(); + try testing.expectEqual(info.id, &data.id); + try testing.expectEqual(info.is_signer, data.is_signer); + try testing.expectEqual(info.is_writable, data.is_writable); + try testing.expectEqual(info.lamports, &data.lamports); + try testing.expectEqual(info.data, account.data().ptr); +} diff --git a/src/public_key.zig b/src/public_key.zig index 8be20fd..778b5c8 100644 --- a/src/public_key.zig +++ b/src/public_key.zig @@ -13,17 +13,17 @@ pub const ProgramDerivedAddress = struct { bump_seed: [1]u8, }; -pub const PublicKey = packed struct { +pub const PublicKey = extern struct { pub const length: usize = 32; pub const base58_length: usize = 44; pub const max_num_seeds: usize = 16; pub const max_seed_length: usize = 32; - bytes: u256, + bytes: [32]u8, pub fn from(bytes: [PublicKey.length]u8) PublicKey { - return .{ .bytes = mem.bytesToValue(u256, &bytes) }; + return .{ .bytes = bytes }; } pub fn comptimeFromBase58(comptime encoded: []const u8) PublicKey { @@ -51,7 +51,7 @@ pub const PublicKey = packed struct { } pub fn isPointOnCurve(self: PublicKey) bool { - const Y = std.crypto.ecc.Curve25519.Fe.fromBytes(mem.toBytes(self.bytes)); + const Y = std.crypto.ecc.Curve25519.Fe.fromBytes(self.bytes); const Z = std.crypto.ecc.Curve25519.Fe.one; const YY = Y.sq(); const u = YY.sub(Z); @@ -125,9 +125,9 @@ pub const PublicKey = packed struct { inline while (i < seeds.len) : (i += 1) { hasher.update(seeds[i]); } - hasher.update(mem.asBytes(&program_id.bytes)); + hasher.update(&program_id.bytes); hasher.update("ProgramDerivedAddress"); - hasher.final(mem.asBytes(&address.bytes)); + hasher.final(&address.bytes); if (address.isPointOnCurve()) { return error.InvalidSeeds; @@ -222,7 +222,7 @@ pub const PublicKey = packed struct { _ = fmt; _ = options; var buffer: [base58.bitcoin.getEncodedLengthUpperBound(PublicKey.length)]u8 = undefined; - try writer.print("{s}", .{base58.bitcoin.encode(&buffer, mem.asBytes(&self.bytes))}); + try writer.print("{s}", .{base58.bitcoin.encode(&buffer, &self.bytes)}); } }; From 4eb407f46f2c0a235faba5c796994e7c0950fa01 Mon Sep 17 00:00:00 2001 From: Jon C Date: Sun, 17 Aug 2025 21:31:17 +0200 Subject: [PATCH 2/4] Bump version to 0.16.1 --- build.zig.zon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.zig.zon b/build.zig.zon index 1d00ad8..c898699 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -1,7 +1,7 @@ .{ .fingerprint = 0xdc47aff950fd68c0, .name = .solana_program_sdk, - .version = "0.16.0", + .version = "0.16.1", .minimum_zig_version = "0.14.0", // This field is optional. From 2ac3711e767ae30e6d8e5766c728c34291d56cf0 Mon Sep 17 00:00:00 2001 From: Jon C Date: Sun, 17 Aug 2025 21:31:29 +0200 Subject: [PATCH 3/4] windows: Don't install openssl with choco --- program-test/install-build-deps.sh | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/program-test/install-build-deps.sh b/program-test/install-build-deps.sh index a2320f2..e443543 100755 --- a/program-test/install-build-deps.sh +++ b/program-test/install-build-deps.sh @@ -2,9 +2,22 @@ set -e case $(uname -s | cut -c1-7) in "Windows" | "MINGW64") - choco install openssl --version 3.4.1 --install-arguments="'/DIR=C:\OpenSSL'" -y - export OPENSSL_LIB_DIR='C:\OpenSSL\lib\VC\x64\MT' - export OPENSSL_INCLUDE_DIR='C:\OpenSSL\include' + cat > vcpkg.json < Date: Sun, 17 Aug 2025 21:35:33 +0200 Subject: [PATCH 4/4] Only run on pull requests to main, and not on all pushes --- .github/workflows/main.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 93c75df..e883997 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,12 @@ name: Build library and test programs -on: [pull_request, push] +on: + push: + branches: + - 'main' + pull_request: + branches: + - 'main' env: SOLANA_ZIG_VERSION: v1.47.0