@@ -22,31 +22,14 @@ pub trait ProgramAccount: HasOwnerProgram {
2222 }
2323}
2424
25- #[ derive( Debug , Derivative , Copy , Clone ) ]
26- // #[derivative(Copy(bound = ""), Clone(bound = ""))]
27- pub struct NormalizeRent < ' a , ' info , F > {
28- pub system_program : & ' a Program < ' info , SystemProgram > ,
29- pub funder : & ' a F ,
30- }
31-
32- #[ derive( Debug , Copy , Clone ) ]
33- pub struct NormalizeRentAuto ;
25+ #[ derive( Copy , Clone , Debug , PartialEq , Eq , Default ) ]
26+ pub struct NormalizeRent < T > ( pub T ) ;
3427
35- #[ derive( Debug , Copy , Clone ) ]
36- pub struct RefundRent < ' a , F > {
37- pub recipient : & ' a F ,
38- }
28+ #[ derive( Copy , Clone , Debug , PartialEq , Eq , Default ) ]
29+ pub struct RefundRent < T > ( pub T ) ;
3930
40- #[ derive( Debug , Copy , Clone ) ]
41- pub struct RefundRentAuto ;
42-
43- #[ derive( Debug , Copy , Clone ) ]
44- pub struct CloseAccount < ' a , F > {
45- pub recipient : & ' a F ,
46- }
47-
48- #[ derive( Debug , Copy , Clone ) ]
49- pub struct CloseAccountAuto ;
31+ #[ derive( Copy , Clone , Debug , PartialEq , Eq , Default ) ]
32+ pub struct CloseAccount < T > ( pub T ) ;
5033
5134#[ derive( AccountSet , Debug ) ]
5235#[ account_set( skip_default_idl, skip_default_cleanup) ]
@@ -57,47 +40,46 @@ pub struct CloseAccountAuto;
5740) ]
5841#[ cleanup(
5942 id = "normalize_rent" ,
60- generics = [ <' a, F > where F : WritableAccount <' info> + SignedAccount <' info>] ,
61- arg = NormalizeRent <' a , ' info , F >,
62- extra_cleanup = self . normalize_rent( arg. funder , arg . system_program , syscalls)
43+ generics = [ <' a, Funder > where Funder : WritableAccount <' info> + SignedAccount <' info>] ,
44+ arg = NormalizeRent <& ' a Funder >,
45+ extra_cleanup = self . normalize_rent( arg. 0 , syscalls)
6346) ]
6447#[ cleanup(
65- id = "normalize_rent_auto " ,
66- arg = NormalizeRentAuto ,
48+ id = "normalize_rent_cached " ,
49+ arg = NormalizeRent < ( ) > ,
6750 generics = [ ] ,
6851 extra_cleanup = {
69- let funder = syscalls. get_funder( ) . context( "Missing `funder` for NormalizeRentAuto" ) ?;
70- let system_program = syscalls. get_program( ) . context( "Missing `system_program` for NormalizeRentAuto" ) ?;
71- self . normalize_rent( funder, system_program, syscalls)
52+ let funder = syscalls. get_funder( ) . context( "Missing `funder` in cache for `NormalizeRent`" ) ?;
53+ self . normalize_rent( funder, syscalls)
7254 } ,
7355) ]
7456#[ cleanup(
7557 id = "refund_rent" ,
76- generics = [ <' a, F > where F : WritableAccount <' info>] ,
77- arg = RefundRent <' a , F >,
78- extra_cleanup = self . refund_rent( arg. recipient , syscalls)
58+ generics = [ <' a, Recipient > where Recipient : WritableAccount <' info>] ,
59+ arg = RefundRent <& ' a Recipient >,
60+ extra_cleanup = self . refund_rent( arg. 0 , syscalls)
7961) ]
8062#[ cleanup(
81- id = "refund_rent_auto " ,
82- arg = RefundRentAuto ,
63+ id = "refund_rent_cached " ,
64+ arg = RefundRent < ( ) > ,
8365 generics = [ ] ,
8466 extra_cleanup = {
85- let recipient = syscalls. get_recipient( ) . context( "Missing `recipient` for RefundRentAuto " ) ?;
67+ let recipient = syscalls. get_recipient( ) . context( "Missing `recipient` in cache for `RefundRent` " ) ?;
8668 self . refund_rent( recipient, syscalls)
8769 }
8870) ]
8971#[ cleanup(
9072 id = "close_account" ,
91- generics = [ <' a, F > where F : WritableAccount <' info>] ,
92- arg = CloseAccount <' a , F >,
93- extra_cleanup = self . close( arg. recipient )
73+ generics = [ <' a, Recipient > where Recipient : WritableAccount <' info>] ,
74+ arg = CloseAccount <& ' a Recipient >,
75+ extra_cleanup = self . close( arg. 0 )
9476) ]
9577#[ cleanup(
96- id = "close_account_auto " ,
97- arg = CloseAccountAuto ,
78+ id = "close_account_cached " ,
79+ arg = CloseAccount < ( ) > ,
9880 generics = [ ] ,
9981 extra_cleanup = {
100- let recipient = syscalls. get_recipient( ) . context( "Missing `recipient` for CloseAccountAuto " ) ?;
82+ let recipient = syscalls. get_recipient( ) . context( "Missing `recipient` in cache for `CloseAccount` " ) ?;
10183 self . close( recipient)
10284 }
10385) ]
@@ -229,74 +211,117 @@ where
229211 type Seeds = T :: Seeds ;
230212}
231213
232- impl < ' info , T : ProgramAccount + UnsizedType + ?Sized > CanInitAccount < ' info , Create < ( ) > >
214+ impl < ' info , T : ProgramAccount + UnsizedType + ?Sized > CanInitAccount < ' info , CreateIfNeeded < ( ) > >
233215 for DataAccount < ' info , T >
234216where
235217 T : UnsizedInit < Zeroed > ,
236218{
237219 fn init_account (
238220 & mut self ,
239- _arg : Create < ( ) > ,
221+ _arg : CreateIfNeeded < ( ) > ,
240222 syscalls : & mut impl SyscallInvoke < ' info > ,
241223 account_seeds : Option < Vec < & [ u8 ] > > ,
242224 ) -> Result < ( ) > {
243- let create = CreateAccount :: new_from_syscalls ( syscalls) ?;
244- self . init_account ( Create ( create) , syscalls, account_seeds)
225+ self . init_account ( CreateIfNeeded ( ( Zeroed , ) ) , syscalls, account_seeds)
245226 }
246227}
247228
248- impl < ' info , T : ProgramAccount + UnsizedType + ?Sized , A > CanInitAccount < ' info , Create < ( A , ) > >
249- for DataAccount < ' info , T >
229+ impl < ' info , T : ProgramAccount + UnsizedType + ?Sized , InitArg >
230+ CanInitAccount < ' info , CreateIfNeeded < ( InitArg , ) > > for DataAccount < ' info , T >
250231where
251- T : UnsizedInit < A > ,
232+ T : UnsizedInit < InitArg > ,
252233{
253234 fn init_account (
254235 & mut self ,
255- arg : Create < ( A , ) > ,
236+ arg : CreateIfNeeded < ( InitArg , ) > ,
256237 syscalls : & mut impl SyscallInvoke < ' info > ,
257238 account_seeds : Option < Vec < & [ u8 ] > > ,
258239 ) -> Result < ( ) > {
259- let create = CreateAccount :: new_with_arg_from_syscalls ( arg. 0 . 0 , syscalls) ?;
260- self . init_account ( Create ( create) , syscalls, account_seeds)
240+ let funder = syscalls
241+ . get_funder ( )
242+ . context ( "Missing `funder` for `CreateIfNeeded`" ) ?;
243+ self . init_account (
244+ CreateIfNeeded ( ( arg. 0 . 0 , funder. clone ( ) ) ) ,
245+ syscalls,
246+ account_seeds,
247+ )
261248 }
262249}
263250
264- impl < ' info , T : ProgramAccount + UnsizedType + ?Sized > CanInitAccount < ' info , CreateIfNeeded < ( ) > >
251+ impl < ' info , T : ProgramAccount + UnsizedType + ?Sized , InitArg , Funder >
252+ CanInitAccount < ' info , CreateIfNeeded < ( InitArg , Funder ) > > for DataAccount < ' info , T >
253+ where
254+ T : UnsizedInit < InitArg > ,
255+ Funder : SignedAccount < ' info > + WritableAccount < ' info > ,
256+ {
257+ fn init_account (
258+ & mut self ,
259+ arg : CreateIfNeeded < ( InitArg , Funder ) > ,
260+ syscalls : & mut impl SyscallInvoke < ' info > ,
261+ account_seeds : Option < Vec < & [ u8 ] > > ,
262+ ) -> Result < ( ) > {
263+ if self . owner ( ) == & SystemProgram :: PROGRAM_ID
264+ || self . account_info ( ) . data . borrow_mut ( )
265+ [ ..size_of :: < <T :: OwnerProgram as StarFrameProgram >:: AccountDiscriminant > ( ) ]
266+ . iter ( )
267+ . all ( |x| * x == 0 )
268+ {
269+ self . init_account ( Create ( arg. 0 ) , syscalls, account_seeds) ?;
270+ }
271+ Ok ( ( ) )
272+ }
273+ }
274+
275+ impl < ' info , T : ProgramAccount + UnsizedType + ?Sized > CanInitAccount < ' info , Create < ( ) > >
265276 for DataAccount < ' info , T >
266277where
267278 T : UnsizedInit < Zeroed > ,
268279{
269280 fn init_account (
270281 & mut self ,
271- _arg : CreateIfNeeded < ( ) > ,
282+ _arg : Create < ( ) > ,
283+ syscalls : & mut impl SyscallInvoke < ' info > ,
284+ account_seeds : Option < Vec < & [ u8 ] > > ,
285+ ) -> Result < ( ) > {
286+ self . init_account ( Create ( ( Zeroed , ) ) , syscalls, account_seeds)
287+ }
288+ }
289+
290+ impl < ' info , T : ProgramAccount + UnsizedType + ?Sized , InitArg >
291+ CanInitAccount < ' info , Create < ( InitArg , ) > > for DataAccount < ' info , T >
292+ where
293+ T : UnsizedInit < InitArg > ,
294+ {
295+ fn init_account (
296+ & mut self ,
297+ arg : Create < ( InitArg , ) > ,
272298 syscalls : & mut impl SyscallInvoke < ' info > ,
273299 account_seeds : Option < Vec < & [ u8 ] > > ,
274300 ) -> Result < ( ) > {
275- let create = CreateAccount :: new_from_syscalls ( syscalls) ?;
276- self . init_account ( CreateIfNeeded ( create) , syscalls, account_seeds)
301+ let funder = syscalls
302+ . get_funder ( )
303+ . context ( "Missing `funder` for `Create`" ) ?
304+ . clone ( ) ;
305+ self . init_account ( Create ( ( arg. 0 . 0 , funder) ) , syscalls, account_seeds)
277306 }
278307}
279308
280- impl < ' info , T : ProgramAccount + UnsizedType + ?Sized , A , WT >
281- CanInitAccount < ' info , Create < CreateAccount < ' info , A , WT > > > for DataAccount < ' info , T >
309+ impl < ' info , T : ProgramAccount + UnsizedType + ?Sized , InitArg , Funder >
310+ CanInitAccount < ' info , Create < ( InitArg , Funder ) > > for DataAccount < ' info , T >
282311where
283- T : UnsizedInit < A > ,
284- WT : SignedAccount < ' info > + WritableAccount < ' info > ,
312+ T : UnsizedInit < InitArg > ,
313+ Funder : SignedAccount < ' info > + WritableAccount < ' info > ,
285314{
286315 fn init_account (
287316 & mut self ,
288- arg : Create < CreateAccount < ' info , A , WT > > ,
317+ arg : Create < ( InitArg , Funder ) > ,
289318 syscalls : & mut impl SyscallInvoke < ' info > ,
290319 account_seeds : Option < Vec < & [ u8 ] > > ,
291320 ) -> Result < ( ) > {
292321 self . check_writable ( )
293322 . context ( "InitAccount must be writable" ) ?;
294- let CreateAccount {
295- arg,
296- system_program,
297- funder,
298- } = arg. 0 ;
299- if self . owner ( ) != system_program. key ( ) || funder. owner ( ) != system_program. key ( ) {
323+ let ( arg, funder) = arg. 0 ;
324+ if self . owner ( ) != & SystemProgram :: PROGRAM_ID {
300325 bail ! ( ProgramError :: IllegalOwner ) ;
301326 }
302327 let rent = syscalls. get_rent ( ) ?;
@@ -348,47 +373,6 @@ where
348373 }
349374}
350375
351- impl < ' info , T : ProgramAccount + UnsizedType + ?Sized , A > CanInitAccount < ' info , CreateIfNeeded < ( A , ) > >
352- for DataAccount < ' info , T >
353- where
354- T : UnsizedInit < A > ,
355- {
356- fn init_account (
357- & mut self ,
358- arg : CreateIfNeeded < ( A , ) > ,
359- syscalls : & mut impl SyscallInvoke < ' info > ,
360- account_seeds : Option < Vec < & [ u8 ] > > ,
361- ) -> Result < ( ) > {
362- let create = CreateAccount :: new_with_arg_from_syscalls ( arg. 0 . 0 , syscalls) ?;
363- self . init_account ( CreateIfNeeded ( create) , syscalls, account_seeds)
364- }
365- }
366-
367- impl < ' info , T : ProgramAccount + UnsizedType + ?Sized , A , WT >
368- CanInitAccount < ' info , CreateIfNeeded < CreateAccount < ' info , A , WT > > > for DataAccount < ' info , T >
369- where
370- T : UnsizedInit < A > ,
371- WT : SignedAccount < ' info > + WritableAccount < ' info > ,
372- {
373- fn init_account (
374- & mut self ,
375- arg : CreateIfNeeded < CreateAccount < ' info , A , WT > > ,
376- syscalls : & mut impl SyscallInvoke < ' info > ,
377- account_seeds : Option < Vec < & [ u8 ] > > ,
378- ) -> Result < ( ) > {
379- let init_create = arg. 0 ;
380- if self . owner ( ) == & SystemProgram :: PROGRAM_ID
381- || self . account_info ( ) . data . borrow_mut ( )
382- [ ..size_of :: < <T :: OwnerProgram as StarFrameProgram >:: AccountDiscriminant > ( ) ]
383- . iter ( )
384- . all ( |x| * x == 0 )
385- {
386- self . init_account ( Create ( init_create) , syscalls, account_seeds) ?;
387- }
388- Ok ( ( ) )
389- }
390- }
391-
392376#[ derive( Debug ) ]
393377pub struct AccountInfoRef < ' a > {
394378 pub ( crate ) r : Ref < ' a , [ u8 ] > ,
0 commit comments