Skip to content

Commit 4c8adff

Browse files
authored
Merge pull request #77 from staratlasmeta/discriminants
Feat: instruction set repr discriminants and system program client (better than native!)
2 parents 8e1569b + f28be11 commit 4c8adff

File tree

9 files changed

+238
-146
lines changed

9 files changed

+238
-146
lines changed

framework/star_frame/src/account_set/data_account.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
use crate::prelude::*;
2+
use crate::program::system_program;
3+
use crate::program::system_program::CreateAccountCpiAccounts;
24
use crate::util::*;
35
use advance::Advance;
46
use anyhow::{bail, Context};
57
use bytemuck::{bytes_of, from_bytes};
68
use derivative::Derivative;
79
use solana_program::entrypoint::MAX_PERMITTED_DATA_INCREASE;
810
use solana_program::program_memory::sol_memset;
9-
use solana_program::system_instruction;
1011
pub use star_frame_proc::ProgramAccount;
1112
use std::cell::{Ref, RefMut};
1213
use std::marker::PhantomData;
@@ -301,30 +302,30 @@ where
301302
let rent = syscalls.get_rent()?;
302303
let size =
303304
T::INIT_BYTES + size_of::<<T::OwnerProgram as StarFrameProgram>::AccountDiscriminant>();
304-
let ix = system_instruction::create_account(
305-
funder.key(),
306-
self.key(),
307-
rent.minimum_balance(size),
308-
size as u64,
309-
&T::OwnerProgram::PROGRAM_ID,
310-
);
311-
let accounts: &[AccountInfo<'info>] = &[
312-
self.account_info_cloned(),
313-
system_program.account_info_cloned(),
314-
funder.account_info_cloned(),
315-
];
305+
let cpi = SystemProgram::cpi(
306+
&system_program::CreateAccount {
307+
lamports: rent.minimum_balance(size),
308+
owner: T::OwnerProgram::PROGRAM_ID,
309+
space: size as u64,
310+
},
311+
CreateAccountCpiAccounts {
312+
funder: funder.account_info_cloned(),
313+
new_account: self.account_info_cloned(),
314+
},
315+
)?;
316+
316317
match (funder.signer_seeds(), account_seeds) {
317318
(None, None) => {
318-
syscalls.invoke(&ix, accounts)?;
319+
cpi.invoke(syscalls)?;
319320
}
320321
(Some(funder), None) => {
321-
syscalls.invoke_signed(&ix, accounts, &[&funder])?;
322+
cpi.invoke_signed(syscalls, &[&funder])?;
322323
}
323324
(None, Some(account_seeds)) => {
324-
syscalls.invoke_signed(&ix, accounts, &[&account_seeds])?;
325+
cpi.invoke_signed(syscalls, &[&account_seeds])?;
325326
}
326327
(Some(funder), Some(account_seeds)) => {
327-
syscalls.invoke_signed(&ix, accounts, &[&account_seeds, &funder])?;
328+
cpi.invoke_signed(syscalls, &[&account_seeds, &funder])?;
328329
}
329330
}
330331
{

framework/star_frame/src/account_set/single_set.rs

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use crate::account_set::{AccountSet, HasOwnerProgram, Program, SignedAccount, WritableAccount};
22
use crate::anyhow::Result;
3-
use crate::client::ClientAccountSet;
3+
use crate::client::{ClientAccountSet, MakeCpi};
44
use crate::prelude::{StarFrameProgram, SyscallInvoke, SystemProgram};
5+
use crate::program::system_program::{Transfer, TransferCpiAccounts};
56
use anyhow::anyhow;
67
use solana_program::account_info::AccountInfo;
78
use solana_program::instruction::AccountMeta;
89
use solana_program::program_error::ProgramError;
910
use solana_program::pubkey::Pubkey;
10-
use solana_program::system_instruction::transfer;
1111
use star_frame::client::CpiAccountSet;
1212
use std::cell::{Ref, RefMut};
1313
use std::cmp::Ordering;
@@ -146,8 +146,8 @@ where
146146
}
147147

148148
pub trait CanCloseAccount<'info>: SingleAccountSet<'info> {
149-
/// Closes the account by zeroing the lamports and leaving the data as the
150-
/// [`StarFrameProgram::CLOSED_ACCOUNT_DISCRIMINANT`], reallocating down to size.
149+
/// Closes the account by zeroing the lamports and replacing the discriminant with all `u8::MAX`,
150+
/// reallocating down to size.
151151
fn close(&self, recipient: &impl WritableAccount<'info>) -> Result<()>
152152
where
153153
Self: HasOwnerProgram,
@@ -185,7 +185,7 @@ pub trait CanModifyRent<'info>: SingleAccountSet<'info> {
185185
fn normalize_rent<F: WritableAccount<'info> + SignedAccount<'info>>(
186186
&self,
187187
funder: &F,
188-
system_program: &Program<'info, SystemProgram>,
188+
_system_program: &Program<'info, SystemProgram>,
189189
syscalls: &impl SyscallInvoke<'info>,
190190
) -> Result<()> {
191191
let rent = syscalls.get_rent()?;
@@ -199,25 +199,20 @@ pub trait CanModifyRent<'info>: SingleAccountSet<'info> {
199199
return Ok(());
200200
}
201201
let transfer_amount = rent_lamports - lamports;
202-
if funder.owner() == system_program.key() {
203-
let transfer_ix = transfer(funder.key(), self.key(), transfer_amount);
204-
let transfer_accounts =
205-
&[self.account_info_cloned(), funder.account_info_cloned()];
206-
match funder.signer_seeds() {
207-
None => syscalls
208-
.invoke(&transfer_ix, transfer_accounts)
209-
.map_err(Into::into),
210-
Some(seeds) => syscalls
211-
.invoke_signed(&transfer_ix, transfer_accounts, &[&seeds])
212-
.map_err(Into::into),
213-
}
214-
} else {
215-
Err(anyhow!(
216-
"Funder account `{}` is not owned by the system program, owned by `{}`",
217-
funder.key(),
218-
funder.owner()
219-
))
220-
}
202+
let cpi = SystemProgram::cpi(
203+
&Transfer {
204+
lamports: transfer_amount,
205+
},
206+
TransferCpiAccounts {
207+
funder: funder.account_info_cloned(),
208+
recipient: self.account_info_cloned(),
209+
},
210+
)?;
211+
match funder.signer_seeds() {
212+
None => cpi.invoke(syscalls)?,
213+
Some(seeds) => cpi.invoke_signed(syscalls, &[&seeds])?,
214+
};
215+
Ok(())
221216
}
222217
Ordering::Less => {
223218
let transfer_amount = lamports - rent_lamports;

framework/star_frame/src/client.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ impl<'info> CpiBuilder<'info> {
4848

4949
pub fn invoke_signed(
5050
&self,
51-
signer_seeds: &[&[&[u8]]],
5251
syscalls: &impl SyscallInvoke<'info>,
52+
signer_seeds: &[&[&[u8]]],
5353
) -> ProgramResult {
5454
syscalls.invoke_signed(&self.instruction, &self.accounts, signer_seeds)
5555
}

framework/star_frame/src/instruction/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ mod test {
302302

303303
#[allow(dead_code)]
304304
#[derive(InstructionSet)]
305+
#[ix_set(skip_idl)]
305306
enum TestInstructionSet3 {
306307
Ix1(Ix1),
307308
Ix2(Ix2),

framework/star_frame/src/program/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ pub trait StarFrameProgram {
1515
type InstructionSet: InstructionSet;
1616

1717
type AccountDiscriminant: Pod + Eq;
18-
const CLOSED_ACCOUNT_DISCRIMINANT: Self::AccountDiscriminant;
1918

2019
const PROGRAM_ID: Pubkey;
2120

0 commit comments

Comments
 (0)