Skip to content

Commit b7a7ecf

Browse files
committed
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.
1 parent 43effd4 commit b7a7ecf

File tree

2 files changed

+35
-15
lines changed

2 files changed

+35
-15
lines changed

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)