@@ -125,11 +125,10 @@ where
125125{
126126 /// Validates the owner and the discriminant of the account.
127127 pub fn validate ( & self ) -> Result < ( ) > {
128- if self . info . owner != & T :: OwnerProgram :: PROGRAM_ID {
128+ if self . owner ( ) != & T :: OwnerProgram :: PROGRAM_ID {
129129 bail ! ( ProgramError :: IllegalOwner ) ;
130130 }
131- let data = self . info . try_borrow_data ( ) ?;
132-
131+ let data = self . info_data_bytes ( ) ?;
133132 Self :: check_discriminant ( & data) ?;
134133 Ok ( ( ) )
135134 }
@@ -146,10 +145,10 @@ where
146145 }
147146
148147 pub fn data < ' a > ( & ' a self ) -> Result < RefWrapper < AccountInfoRef < ' a > , T :: RefData > > {
149- let r: Ref < ' a , _ > = self . info . try_borrow_data ( ) ?;
148+ let r: Ref < ' a , _ > = self . info_data_bytes ( ) ?;
150149 Self :: check_discriminant ( & r) ?;
151150 let r = try_map_ref ( r, |bytes| {
152- let bytes = & mut & * * bytes;
151+ let bytes = & mut & * bytes;
153152 bytes. try_advance ( size_of :: <
154153 <T :: OwnerProgram as StarFrameProgram >:: AccountDiscriminant ,
155154 > ( ) ) ?;
@@ -162,7 +161,7 @@ where
162161 pub fn data_mut < ' a > (
163162 & ' a mut self ,
164163 ) -> Result < RefWrapper < AccountInfoRefMut < ' a , ' info , T :: OwnerProgram > , T :: RefData > > {
165- let r: RefMut < ' a , _ > = self . info . try_borrow_mut_data ( ) ?;
164+ let r: RefMut < ' a , _ > = self . info_data_bytes_mut ( ) ?;
166165 Self :: check_discriminant ( & r) ?;
167166 let account_info_ref_mut = AccountInfoRefMut {
168167 account_info : & self . info ,
@@ -210,111 +209,63 @@ where
210209 type Seeds = T :: Seeds ;
211210}
212211
213- impl < ' info , T : ProgramAccount + UnsizedType + ?Sized > CanInitAccount < ' info , CreateIfNeeded < ( ) > >
212+ impl < ' info , T : ProgramAccount + UnsizedType + ?Sized > CanInitAccount < ' info , ( ) >
214213 for DataAccount < ' info , T >
215214where
216215 T : UnsizedInit < Zeroed > ,
217216{
218- fn init_account (
219- & mut self ,
220- _arg : CreateIfNeeded < ( ) > ,
221- syscalls : & impl SyscallInvoke < ' info > ,
222- account_seeds : Option < Vec < & [ u8 ] > > ,
223- ) -> Result < ( ) > {
224- self . init_account ( CreateIfNeeded ( ( Zeroed , ) ) , syscalls, account_seeds)
225- }
226- }
227-
228- impl < ' info , T : ProgramAccount + UnsizedType + ?Sized , InitArg >
229- CanInitAccount < ' info , CreateIfNeeded < ( InitArg , ) > > for DataAccount < ' info , T >
230- where
231- T : UnsizedInit < InitArg > ,
232- {
233- fn init_account (
217+ fn init_account < const IF_NEEDED : bool > (
234218 & mut self ,
235- arg : CreateIfNeeded < ( InitArg , ) > ,
236- syscalls : & impl SyscallInvoke < ' info > ,
219+ _arg : ( ) ,
237220 account_seeds : Option < Vec < & [ u8 ] > > ,
238- ) -> Result < ( ) > {
239- let funder = syscalls
240- . get_funder ( )
241- . context ( "Missing `funder` for `CreateIfNeeded`" ) ?;
242- self . init_account ( CreateIfNeeded ( ( arg. 0 . 0 , funder) ) , syscalls, account_seeds)
243- }
244- }
245-
246- impl < ' info , T : ProgramAccount + UnsizedType + ?Sized , InitArg , Funder >
247- CanInitAccount < ' info , CreateIfNeeded < ( InitArg , & Funder ) > > for DataAccount < ' info , T >
248- where
249- T : UnsizedInit < InitArg > ,
250- Funder : SignedAccount < ' info > + WritableAccount < ' info > ,
251- {
252- fn init_account (
253- & mut self ,
254- arg : CreateIfNeeded < ( InitArg , & Funder ) > ,
255221 syscalls : & impl SyscallInvoke < ' info > ,
256- account_seeds : Option < Vec < & [ u8 ] > > ,
257222 ) -> Result < ( ) > {
258- if self . owner ( ) == & SystemProgram :: PROGRAM_ID
259- || self . account_info ( ) . data . borrow_mut ( )
260- [ ..size_of :: < <T :: OwnerProgram as StarFrameProgram >:: AccountDiscriminant > ( ) ]
261- . iter ( )
262- . all ( |x| * x == 0 )
263- {
264- self . init_account ( Create ( arg. 0 ) , syscalls, account_seeds) ?;
265- }
266- Ok ( ( ) )
223+ self . init_account :: < IF_NEEDED > ( ( Zeroed , ) , account_seeds, syscalls)
267224 }
268225}
269226
270- impl < ' info , T : ProgramAccount + UnsizedType + ?Sized > CanInitAccount < ' info , Create < ( ) > >
227+ impl < ' info , T : ProgramAccount + UnsizedType + ?Sized , InitArg > CanInitAccount < ' info , ( InitArg , ) >
271228 for DataAccount < ' info , T >
272- where
273- T : UnsizedInit < Zeroed > ,
274- {
275- fn init_account (
276- & mut self ,
277- _arg : Create < ( ) > ,
278- syscalls : & impl SyscallInvoke < ' info > ,
279- account_seeds : Option < Vec < & [ u8 ] > > ,
280- ) -> Result < ( ) > {
281- self . init_account ( Create ( ( Zeroed , ) ) , syscalls, account_seeds)
282- }
283- }
284-
285- impl < ' info , T : ProgramAccount + UnsizedType + ?Sized , InitArg >
286- CanInitAccount < ' info , Create < ( InitArg , ) > > for DataAccount < ' info , T >
287229where
288230 T : UnsizedInit < InitArg > ,
289231{
290- fn init_account (
232+ fn init_account < const IF_NEEDED : bool > (
291233 & mut self ,
292- arg : Create < ( InitArg , ) > ,
293- syscalls : & impl SyscallInvoke < ' info > ,
234+ arg : ( InitArg , ) ,
294235 account_seeds : Option < Vec < & [ u8 ] > > ,
236+ syscalls : & impl SyscallInvoke < ' info > ,
295237 ) -> Result < ( ) > {
296238 let funder = syscalls
297239 . get_funder ( )
298- . context ( "Missing `funder` for `Create `" ) ?;
299- self . init_account ( Create ( ( arg. 0 . 0 , funder) ) , syscalls , account_seeds )
240+ . context ( "Missing tagged `funder` for DataAccount `init_account `" ) ?;
241+ self . init_account :: < IF_NEEDED > ( ( arg. 0 , funder) , account_seeds , syscalls )
300242 }
301243}
302244
303245impl < ' info , T : ProgramAccount + UnsizedType + ?Sized , InitArg , Funder >
304- CanInitAccount < ' info , Create < ( InitArg , & Funder ) > > for DataAccount < ' info , T >
246+ CanInitAccount < ' info , ( InitArg , & Funder ) > for DataAccount < ' info , T >
305247where
306248 T : UnsizedInit < InitArg > ,
307249 Funder : SignedAccount < ' info > + WritableAccount < ' info > ,
308250{
309- fn init_account (
251+ fn init_account < const IF_NEEDED : bool > (
310252 & mut self ,
311- arg : Create < ( InitArg , & Funder ) > ,
312- syscalls : & impl SyscallInvoke < ' info > ,
253+ arg : ( InitArg , & Funder ) ,
313254 account_seeds : Option < Vec < & [ u8 ] > > ,
255+ syscalls : & impl SyscallInvoke < ' info > ,
314256 ) -> Result < ( ) > {
315- self . check_writable ( )
316- . context ( "InitAccount must be writable" ) ?;
317- let ( arg, funder) = arg. 0 ;
257+ if IF_NEEDED {
258+ let needs_init = self . owner ( ) == & SystemProgram :: PROGRAM_ID
259+ || self . info_data_bytes ( ) ?
260+ [ ..size_of :: < <T :: OwnerProgram as StarFrameProgram >:: AccountDiscriminant > ( ) ]
261+ . iter ( )
262+ . all ( |x| * x == 0 ) ;
263+ if !needs_init {
264+ return Ok ( ( ) ) ;
265+ }
266+ }
267+ self . check_writable ( ) ?;
268+ let ( arg, funder) = arg;
318269 let size =
319270 T :: INIT_BYTES + size_of :: < <T :: OwnerProgram as StarFrameProgram >:: AccountDiscriminant > ( ) ;
320271 self . system_create_account (
0 commit comments