Skip to content

Commit 95404ad

Browse files
authored
Fix account.info(), turn Pubkey back into bytes (#12)
* 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. * Bump version to 0.16.1 * windows: Don't install openssl with choco * Only run on pull requests to main, and not on all pushes
1 parent 43effd4 commit 95404ad

File tree

5 files changed

+59
-20
lines changed

5 files changed

+59
-20
lines changed

.github/workflows/main.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
name: Build library and test programs
22

3-
on: [pull_request, push]
3+
on:
4+
push:
5+
branches:
6+
- 'main'
7+
pull_request:
8+
branches:
9+
- 'main'
410

511
env:
612
SOLANA_ZIG_VERSION: v1.47.0

build.zig.zon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.{
22
.fingerprint = 0xdc47aff950fd68c0,
33
.name = .solana_program_sdk,
4-
.version = "0.16.0",
4+
.version = "0.16.1",
55
.minimum_zig_version = "0.14.0",
66

77
// This field is optional.

program-test/install-build-deps.sh

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,22 @@
22
set -e
33
case $(uname -s | cut -c1-7) in
44
"Windows" | "MINGW64")
5-
choco install openssl --version 3.4.1 --install-arguments="'/DIR=C:\OpenSSL'" -y
6-
export OPENSSL_LIB_DIR='C:\OpenSSL\lib\VC\x64\MT'
7-
export OPENSSL_INCLUDE_DIR='C:\OpenSSL\include'
5+
cat > vcpkg.json <<EOL
6+
{
7+
"dependencies": ["openssl"],
8+
"overrides": [
9+
{
10+
"name": "openssl",
11+
"version": "3.4.1"
12+
}
13+
],
14+
"builtin-baseline": "5ee5eee0d3e9c6098b24d263e9099edcdcef6631"
15+
}
16+
EOL
17+
vcpkg install --triplet x64-windows-static-md
18+
rm vcpkg.json
19+
export "OPENSSL_LIB_DIR=$GITHUB_WORKSPACE/vcpkg_installed/x64-windows-static-md/lib"
20+
export "OPENSSL_INCLUDE_DIR=$GITHUB_WORKSPACE/vcpkg_installed/x64-windows-static-md/include"
821
choco install protoc
922
export PROTOC='C:\ProgramData\chocolatey\lib\protoc\tools\bin\protoc.exe'
1023
;;

src/account.zig

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
const std = @import("std");
22
const PublicKey = @import("public_key.zig").PublicKey;
3+
const testing = std.testing;
34

45
pub const ACCOUNT_DATA_PADDING = 10 * 1024;
56

67
pub const Account = struct {
78
pub const DATA_HEADER = 88;
89
/// A Solana account sliced from what is provided as inputs to the BPF virtual machine.
9-
pub const Data = packed struct {
10+
pub const Data = extern struct {
1011
duplicate_index: u8,
1112
is_signer: u8,
1213
is_writable: u8,
@@ -44,16 +45,16 @@ pub const Account = struct {
4445
data_len: u64,
4546
data: [*]u8,
4647
owner_id: *const PublicKey,
47-
rent_epoch: u64,
48-
is_signer: bool,
49-
is_writable: bool,
50-
is_executable: bool,
48+
unused: u64 = undefined,
49+
is_signer: u8,
50+
is_writable: u8,
51+
is_executable: u8,
5152
};
5253

5354
ptr: *Account.Data,
5455

5556
pub fn fromDataPtr(ptr: *Account.Data) Account {
56-
return Account { .ptr = ptr };
57+
return Account{ .ptr = ptr };
5758
}
5859

5960
pub fn id(self: Account) PublicKey {
@@ -107,18 +108,37 @@ pub const Account = struct {
107108

108109
pub fn info(self: Account) Account.Info {
109110
const data_ptr = @as([*]u8, @ptrFromInt(@intFromPtr(self.ptr))) + DATA_HEADER;
110-
const rent_epoch = @as(*u64, @ptrFromInt(std.mem.alignForward(u64, @intFromPtr(self.ptr) + self.ptr.data_len + ACCOUNT_DATA_PADDING, @alignOf(u64))));
111111

112112
return .{
113113
.id = &self.ptr.id,
114114
.lamports = &self.ptr.lamports,
115115
.data_len = self.ptr.data_len,
116116
.data = data_ptr,
117117
.owner_id = &self.ptr.owner_id,
118-
.rent_epoch = rent_epoch.*,
119118
.is_signer = self.ptr.is_signer,
120119
.is_writable = self.ptr.is_writable,
121120
.is_executable = self.ptr.is_executable,
122121
};
123122
}
124123
};
124+
125+
test "account: create info from account" {
126+
var data: Account.Data = .{
127+
.duplicate_index = 255,
128+
.is_signer = 1,
129+
.is_writable = 1,
130+
.is_executable = 0,
131+
.original_data_len = 10,
132+
.id = PublicKey.from(.{1} ** 32),
133+
.owner_id = PublicKey.from(.{2} ** 32),
134+
.lamports = 1,
135+
.data_len = 10,
136+
};
137+
const account: Account = .{ .ptr = &data };
138+
const info = account.info();
139+
try testing.expectEqual(info.id, &data.id);
140+
try testing.expectEqual(info.is_signer, data.is_signer);
141+
try testing.expectEqual(info.is_writable, data.is_writable);
142+
try testing.expectEqual(info.lamports, &data.lamports);
143+
try testing.expectEqual(info.data, account.data().ptr);
144+
}

src/public_key.zig

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ pub const ProgramDerivedAddress = struct {
1313
bump_seed: [1]u8,
1414
};
1515

16-
pub const PublicKey = packed struct {
16+
pub const PublicKey = extern struct {
1717
pub const length: usize = 32;
1818
pub const base58_length: usize = 44;
1919

2020
pub const max_num_seeds: usize = 16;
2121
pub const max_seed_length: usize = 32;
2222

23-
bytes: u256,
23+
bytes: [32]u8,
2424

2525
pub fn from(bytes: [PublicKey.length]u8) PublicKey {
26-
return .{ .bytes = mem.bytesToValue(u256, &bytes) };
26+
return .{ .bytes = bytes };
2727
}
2828

2929
pub fn comptimeFromBase58(comptime encoded: []const u8) PublicKey {
@@ -51,7 +51,7 @@ pub const PublicKey = packed struct {
5151
}
5252

5353
pub fn isPointOnCurve(self: PublicKey) bool {
54-
const Y = std.crypto.ecc.Curve25519.Fe.fromBytes(mem.toBytes(self.bytes));
54+
const Y = std.crypto.ecc.Curve25519.Fe.fromBytes(self.bytes);
5555
const Z = std.crypto.ecc.Curve25519.Fe.one;
5656
const YY = Y.sq();
5757
const u = YY.sub(Z);
@@ -125,9 +125,9 @@ pub const PublicKey = packed struct {
125125
inline while (i < seeds.len) : (i += 1) {
126126
hasher.update(seeds[i]);
127127
}
128-
hasher.update(mem.asBytes(&program_id.bytes));
128+
hasher.update(&program_id.bytes);
129129
hasher.update("ProgramDerivedAddress");
130-
hasher.final(mem.asBytes(&address.bytes));
130+
hasher.final(&address.bytes);
131131

132132
if (address.isPointOnCurve()) {
133133
return error.InvalidSeeds;
@@ -222,7 +222,7 @@ pub const PublicKey = packed struct {
222222
_ = fmt;
223223
_ = options;
224224
var buffer: [base58.bitcoin.getEncodedLengthUpperBound(PublicKey.length)]u8 = undefined;
225-
try writer.print("{s}", .{base58.bitcoin.encode(&buffer, mem.asBytes(&self.bytes))});
225+
try writer.print("{s}", .{base58.bitcoin.encode(&buffer, &self.bytes)});
226226
}
227227
};
228228

0 commit comments

Comments
 (0)