@@ -4,29 +4,30 @@ const PublicKey = @import("public_key.zig").PublicKey;
44pub const ACCOUNT_DATA_PADDING = 10 * 1024 ;
55
66pub const Account = struct {
7+ pub const DATA_HEADER = 88 ;
78 /// A Solana account sliced from what is provided as inputs to the BPF virtual machine.
8- pub const Data = extern struct {
9+ pub const Data = packed struct {
910 duplicate_index : u8 ,
10- is_signer : bool ,
11- is_writable : bool ,
12- is_executable : bool ,
13- _ : [ 4 ] u8 ,
11+ is_signer : u8 ,
12+ is_writable : u8 ,
13+ is_executable : u8 ,
14+ original_data_len : u32 ,
1415 id : PublicKey ,
1516 owner_id : PublicKey ,
1617 lamports : u64 ,
17- data_len : usize ,
18+ data_len : u64 ,
1819
1920 comptime {
2021 std .debug .assert (@offsetOf (Account .Data , "duplicate_index" ) == 0 );
2122 std .debug .assert (@offsetOf (Account .Data , "is_signer" ) == 0 + 1 );
2223 std .debug .assert (@offsetOf (Account .Data , "is_writable" ) == 0 + 1 + 1 );
2324 std .debug .assert (@offsetOf (Account .Data , "is_executable" ) == 0 + 1 + 1 + 1 );
24- std .debug .assert (@offsetOf (Account .Data , "_ " ) == 0 + 1 + 1 + 1 + 1 );
25+ std .debug .assert (@offsetOf (Account .Data , "original_data_len " ) == 0 + 1 + 1 + 1 + 1 );
2526 std .debug .assert (@offsetOf (Account .Data , "id" ) == 0 + 1 + 1 + 1 + 1 + 4 );
2627 std .debug .assert (@offsetOf (Account .Data , "owner_id" ) == 0 + 1 + 1 + 1 + 1 + 4 + 32 );
2728 std .debug .assert (@offsetOf (Account .Data , "lamports" ) == 0 + 1 + 1 + 1 + 1 + 4 + 32 + 32 );
2829 std .debug .assert (@offsetOf (Account .Data , "data_len" ) == 0 + 1 + 1 + 1 + 1 + 4 + 32 + 32 + 8 );
29- std .debug .assert (@sizeOf (Account .Data ) == 1 + 1 + 1 + 1 + 4 + 32 + 32 + 8 + 8 );
30+ std .debug .assert (@bitSizeOf (Account .Data ) == DATA_HEADER * 8 );
3031 }
3132 };
3233
@@ -63,30 +64,46 @@ pub const Account = struct {
6364 return self .ptr .owner_id ;
6465 }
6566
67+ pub fn assign (self : Account , new_owner_id : PublicKey ) void {
68+ self .ptr .owner_id = new_owner_id ;
69+ }
70+
6671 pub fn data (self : Account ) []u8 {
67- const data_ptr = @as ([* ]u8 , @ptrFromInt (@intFromPtr (self .ptr ))) + @sizeOf ( Account . Data ) ;
72+ const data_ptr = @as ([* ]u8 , @ptrFromInt (@intFromPtr (self .ptr ))) + DATA_HEADER ;
6873 return data_ptr [0.. self .ptr .data_len ];
6974 }
7075
7176 pub fn isWritable (self : Account ) bool {
72- return self .ptr .is_writable ;
77+ return self .ptr .is_writable == 1 ;
7378 }
7479
7580 pub fn isExecutable (self : Account ) bool {
76- return self .ptr .is_executable ;
81+ return self .ptr .is_executable == 1 ;
7782 }
7883
7984 pub fn isSigner (self : Account ) bool {
80- return self .ptr .is_signer ;
85+ return self .ptr .is_signer == 1 ;
8186 }
8287
83- pub fn dataLen (self : Account ) usize {
88+ pub fn dataLen (self : Account ) u64 {
8489 return self .ptr .data_len ;
8590 }
8691
92+ pub fn realloc (self : Account , new_data_len : u64 ) error.InvalidRealloc ! void {
93+ const diff = @subWithOverflow (new_data_len , self .original_data_len );
94+ if (diff [1 ] == 0 and diff [0 ] > ACCOUNT_DATA_PADDING ) {
95+ return error .InvalidRealloc ;
96+ }
97+ self .reallocUnchecked (new_data_len );
98+ }
99+
100+ pub fn reallocUnchecked (self : Account , new_data_len : u64 ) void {
101+ self .ptr .data_len = new_data_len ;
102+ }
103+
87104 pub fn info (self : Account ) Account.Info {
88- const data_ptr = @as ([* ]u8 , @ptrFromInt (@intFromPtr (self .ptr ))) + @sizeOf ( Account . Data ) ;
89- const rent_epoch = @as (* u64 , @ptrFromInt (std .mem .alignForward (usize , @intFromPtr (self .ptr ) + self .ptr .data_len + ACCOUNT_DATA_PADDING , @alignOf (usize ))));
105+ const data_ptr = @as ([* ]u8 , @ptrFromInt (@intFromPtr (self .ptr ))) + DATA_HEADER ;
106+ const rent_epoch = @as (* u64 , @ptrFromInt (std .mem .alignForward (u64 , @intFromPtr (self .ptr ) + self .ptr .data_len + ACCOUNT_DATA_PADDING , @alignOf (u64 ))));
90107
91108 return .{
92109 .id = & self .ptr .id ,
0 commit comments