Skip to content

Commit 09d9160

Browse files
authored
Merge pull request #64 from staratlasmeta/stegaBOB/fix/stuff
Fix: stuff
2 parents f0ad87b + 5a0d526 commit 09d9160

File tree

18 files changed

+270
-518
lines changed

18 files changed

+270
-518
lines changed

framework/example_programs/counter/src/lib.rs

Lines changed: 24 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -56,27 +56,22 @@ impl StarFrameInstruction for CreateCounterIx {
5656
type RunArg<'a> = &'a Option<u64>;
5757
type CleanupArg<'a> = ();
5858
type ReturnType = ();
59-
type Accounts<'b, 'c, 'info> = CreateCounterAccounts<'info>
60-
where
61-
'info: 'b;
59+
type Accounts<'b, 'c, 'info> = CreateCounterAccounts<'info>;
6260

63-
fn split_to_args<'a>(r: &Self) -> SplitToArgsReturn<Self> {
64-
SplitToArgsReturn {
61+
fn split_to_args<'a>(r: &Self) -> IxArgs<Self> {
62+
IxArgs {
6563
decode: (),
6664
cleanup: (),
6765
run: &r.start_at,
6866
validate: (),
6967
}
7068
}
7169

72-
fn run_instruction<'b, 'info>(
73-
account_set: &mut Self::Accounts<'b, '_, 'info>,
70+
fn run_instruction(
71+
account_set: &mut Self::Accounts<'_, '_, '_>,
7472
start_at: Self::RunArg<'_>,
7573
_syscalls: &mut impl SyscallInvoke,
76-
) -> Result<Self::ReturnType>
77-
where
78-
'info: 'b,
79-
{
74+
) -> Result<Self::ReturnType> {
8075
*account_set.counter.data_mut()? = CounterAccount {
8176
version: 0,
8277
signer: *account_set.owner.key(),
@@ -115,24 +110,19 @@ impl StarFrameInstruction for UpdateCounterSignerIx {
115110
type RunArg<'a> = ();
116111
type CleanupArg<'a> = ();
117112
type ReturnType = ();
118-
type Accounts<'b, 'c, 'info> = UpdateCounterSignerAccounts<'info>
119-
where
120-
'info: 'b;
113+
type Accounts<'b, 'c, 'info> = UpdateCounterSignerAccounts<'info>;
121114

122-
fn split_to_args<'a>(_r: &Self) -> SplitToArgsReturn<Self> {
123-
SplitToArgsReturn {
115+
fn split_to_args<'a>(_r: &Self) -> IxArgs<Self> {
116+
IxArgs {
124117
..Default::default()
125118
}
126119
}
127120

128-
fn run_instruction<'b, 'info>(
129-
account_set: &mut Self::Accounts<'b, '_, 'info>,
121+
fn run_instruction(
122+
account_set: &mut Self::Accounts<'_, '_, '_>,
130123
_run_args: Self::RunArg<'_>,
131124
_syscalls: &mut impl SyscallInvoke,
132-
) -> Result<Self::ReturnType>
133-
where
134-
'info: 'b,
135-
{
125+
) -> Result<Self::ReturnType> {
136126
let mut counter = account_set.counter.data_mut()?;
137127
counter.signer = *account_set.new_signer.key();
138128

@@ -168,25 +158,20 @@ impl StarFrameInstruction for CountIx {
168158
type RunArg<'a> = (u64, bool);
169159
type CleanupArg<'a> = ();
170160
type ReturnType = ();
171-
type Accounts<'b, 'c, 'info> = CountAccounts<'info>
172-
where
173-
'info: 'b;
161+
type Accounts<'b, 'c, 'info> = CountAccounts<'info>;
174162

175-
fn split_to_args<'a>(r: &Self) -> SplitToArgsReturn<Self> {
176-
SplitToArgsReturn {
163+
fn split_to_args<'a>(r: &Self) -> IxArgs<Self> {
164+
IxArgs {
177165
run: (r.amount, r.subtract),
178166
..Default::default()
179167
}
180168
}
181169

182-
fn run_instruction<'b, 'info>(
183-
account_set: &mut Self::Accounts<'b, '_, 'info>,
170+
fn run_instruction(
171+
account_set: &mut Self::Accounts<'_, '_, '_>,
184172
(amount, subtract): Self::RunArg<'_>,
185173
_syscalls: &mut impl SyscallInvoke,
186-
) -> Result<Self::ReturnType>
187-
where
188-
'info: 'b,
189-
{
174+
) -> Result<Self::ReturnType> {
190175
let mut counter = account_set.counter.data_mut()?;
191176
let new_count: u64 = if subtract {
192177
counter.count - amount
@@ -228,24 +213,17 @@ impl StarFrameInstruction for CloseCounterIx {
228213
type RunArg<'a> = ();
229214
type CleanupArg<'a> = ();
230215
type ReturnType = ();
231-
type Accounts<'b, 'c, 'info> = CloseCounterAccounts<'info>
232-
where
233-
'info: 'b;
216+
type Accounts<'b, 'c, 'info> = CloseCounterAccounts<'info>;
234217

235-
fn split_to_args<'a>(_r: &Self) -> SplitToArgsReturn<Self> {
236-
SplitToArgsReturn {
237-
..Default::default()
238-
}
218+
fn split_to_args<'a>(_r: &Self) -> IxArgs<Self> {
219+
Default::default()
239220
}
240221

241-
fn run_instruction<'b, 'info>(
242-
_account_set: &mut Self::Accounts<'b, '_, 'info>,
222+
fn run_instruction(
223+
_account_set: &mut Self::Accounts<'_, '_, '_>,
243224
_run_args: Self::RunArg<'_>,
244225
_syscalls: &mut impl SyscallInvoke,
245-
) -> Result<Self::ReturnType>
246-
where
247-
'info: 'b,
248-
{
226+
) -> Result<Self::ReturnType> {
249227
Ok(())
250228
}
251229
}

framework/example_programs/faction_enlistment/src/lib.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,11 @@ impl StarFrameInstruction for ProcessEnlistPlayerIx {
4242
type ReturnType = ();
4343
// type RunArg<'a> = (FactionId, &'a Vec<u8>);
4444
type RunArg<'a> = FactionId;
45-
type Accounts<'b, 'c, 'info> = ProcessEnlistPlayer<'info>
46-
where 'info: 'b;
45+
type Accounts<'b, 'c, 'info> = ProcessEnlistPlayer<'info>;
4746
// type ReturnType = usize;
4847

49-
fn split_to_args<'a>(r: &Self) -> SplitToArgsReturn<Self> {
50-
SplitToArgsReturn {
48+
fn split_to_args<'a>(r: &Self) -> IxArgs<Self> {
49+
IxArgs {
5150
validate: r.bump,
5251
run: r.faction_id,
5352
// run: (r.faction_id, &r.buncha_data),
@@ -56,14 +55,11 @@ impl StarFrameInstruction for ProcessEnlistPlayerIx {
5655
}
5756
}
5857

59-
fn run_instruction<'b, 'info>(
60-
account_set: &mut Self::Accounts<'b, '_, 'info>,
58+
fn run_instruction(
59+
account_set: &mut Self::Accounts<'_, '_, '_>,
6160
faction_id: Self::RunArg<'_>,
6261
syscalls: &mut impl SyscallInvoke,
63-
) -> Result<Self::ReturnType>
64-
where
65-
'info: 'b,
66-
{
62+
) -> Result<Self::ReturnType> {
6763
let clock = syscalls.get_clock()?;
6864

6965
let bump = account_set.player_faction_account.access_seeds().bump;

framework/star_frame/src/account_set/data_account.rs

Lines changed: 32 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,6 @@ pub trait ProgramAccount {
1717
const DISCRIMINANT: <Self::OwnerProgram as StarFrameProgram>::AccountDiscriminant;
1818
}
1919

20-
fn validate_data_account<T>(account: &DataAccount<T>, _syscalls: &impl SyscallCore) -> Result<()>
21-
where
22-
T: ProgramAccount + UnsizedType + ?Sized,
23-
{
24-
if account.info.owner != &T::OwnerProgram::PROGRAM_ID {
25-
bail!(ProgramError::IllegalOwner);
26-
}
27-
28-
let data = account.info.try_borrow_data()?;
29-
if data.len() < size_of::<<T::OwnerProgram as StarFrameProgram>::AccountDiscriminant>() {
30-
bail!(ProgramError::InvalidAccountData);
31-
}
32-
let discriminant: &<T::OwnerProgram as StarFrameProgram>::AccountDiscriminant = from_bytes(
33-
&data[0..size_of::<<T::OwnerProgram as StarFrameProgram>::AccountDiscriminant>()],
34-
);
35-
if discriminant != &T::DISCRIMINANT {
36-
bail!(ProgramError::InvalidAccountData);
37-
}
38-
Ok(())
39-
}
40-
4120
#[derive(Debug, Derivative)]
4221
#[derivative(Copy(bound = ""), Clone(bound = ""))]
4322
pub struct NormalizeRent<'a, 'info, F> {
@@ -56,7 +35,15 @@ pub struct CloseAccount<'a, F> {
5635
}
5736

5837
#[derive(AccountSet, Debug)]
59-
#[validate(extra_validation = validate_data_account(self, syscalls))]
38+
#[validate(extra_validation = self.validate())]
39+
#[validate(
40+
id = "address",
41+
arg = &Pubkey,
42+
extra_validation = {
43+
anyhow::ensure!(self.key() == arg);
44+
self.validate()
45+
}
46+
)]
6047
#[cleanup(extra_cleanup = self.check_cleanup(syscalls))]
6148
#[cleanup(
6249
id = "normalize_rent",
@@ -85,6 +72,17 @@ impl<'info, T> DataAccount<'info, T>
8572
where
8673
T: ProgramAccount + UnsizedType + ?Sized,
8774
{
75+
/// Validates the owner and the discriminant of the account.
76+
fn validate(&self) -> Result<()> {
77+
if self.info.owner != &T::OwnerProgram::PROGRAM_ID {
78+
bail!(ProgramError::IllegalOwner);
79+
}
80+
let data = self.info.try_borrow_data()?;
81+
82+
Self::check_discriminant(&data)?;
83+
Ok(())
84+
}
85+
8886
fn check_discriminant(bytes: &[u8]) -> Result<()> {
8987
if bytes.len() < size_of::<<T::OwnerProgram as StarFrameProgram>::AccountDiscriminant>()
9088
|| from_bytes::<PackedValue<<T::OwnerProgram as StarFrameProgram>::AccountDiscriminant>>(
@@ -123,7 +121,8 @@ where
123121
T::from_bytes(account_info_ref_mut).map(|ret| ret.ref_wrapper)
124122
}
125123

126-
/// Closes the account
124+
/// Closes the account by zeroing the lamports and leaving the data as the
125+
/// [`StarFrameProgram::CLOSED_ACCOUNT_DISCRIMINANT`], reallocating down to size.
127126
pub fn close(&mut self, recipient: &impl WritableAccount<'info>) -> Result<()> {
128127
self.info.realloc(
129128
size_of::<<T::OwnerProgram as StarFrameProgram>::AccountDiscriminant>(),
@@ -137,8 +136,8 @@ where
137136
Ok(())
138137
}
139138

140-
/// Closes the account by reallocing and transfering. This is the same as calling `close` but
141-
/// not abusable and harder for indexer detection.
139+
/// Closes the account by reallocating to zero and assigning to the System program.
140+
/// This is the same as calling `close` but not abusable and harder for indexer detection.
142141
pub fn close_full(&mut self, recipient: &impl WritableAccount<'info>) -> Result<()> {
143142
self.info.realloc(
144143
size_of::<<T::OwnerProgram as StarFrameProgram>::AccountDiscriminant>(),
@@ -154,6 +153,7 @@ where
154153
Ok(())
155154
}
156155

156+
/// See [`normalize_rent`]
157157
pub fn normalize_rent(
158158
&mut self,
159159
funder: &(impl WritableAccount<'info> + SignedAccount<'info>),
@@ -163,6 +163,7 @@ where
163163
normalize_rent(self.account_info(), funder, system_program, syscalls)
164164
}
165165

166+
/// See [`refund_rent`]
166167
pub fn refund_rent(
167168
&mut self,
168169
recipient: &impl WritableAccount<'info>,
@@ -171,34 +172,21 @@ where
171172
refund_rent(self.account_info(), recipient, sys_calls)
172173
}
173174

175+
/// Emits a warning message if the account has more lamports than required by rent.
174176
pub fn check_cleanup(&self, sys_calls: &mut impl SyscallCore) -> Result<()> {
175177
#[cfg(feature = "cleanup_rent_warning")]
176178
{
177-
use anyhow::Context;
178179
use std::cmp::Ordering;
179180
if self.is_writable() {
180181
let rent = sys_calls.get_rent()?;
181182
let lamports = self.account_info().lamports();
182183
let data_len = self.account_info().data_len();
183184
let rent_lamports = rent.minimum_balance(data_len);
184-
match rent_lamports.cmp(&lamports) {
185-
Ordering::Greater => {
186-
// is this more descriptive than just letting the runtime error out?
187-
return Err(anyhow::anyhow!(ProgramError::AccountNotRentExempt))
188-
.with_context(|| {
189-
format!(
190-
"{} was left with less lamports than required by rent",
191-
self.key()
192-
)
193-
});
194-
}
195-
Ordering::Less => {
196-
msg!(
197-
"{} was left with more lamports than required by rent",
198-
self.key()
199-
);
200-
}
201-
Ordering::Equal => {}
185+
if rent_lamports.cmp(&lamports) == Ordering::Less {
186+
msg!(
187+
"{} was left with more lamports than required by rent",
188+
self.key()
189+
);
202190
}
203191
}
204192
}

framework/star_frame/src/data_types/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ mod key_for;
55
mod optional_key_for;
66
mod packed_value;
77
mod pod_bool;
8+
mod remaining_data;
89
mod unit_val;
910

1011
pub use divisor::*;
1112
pub use key_for::*;
1213
pub use optional_key_for::*;
1314
pub use packed_value::*;
1415
pub use pod_bool::*;
16+
pub use remaining_data::*;
1517
pub use unit_val::*;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use borsh::{BorshDeserialize, BorshSerialize};
2+
use derive_more::{Deref, DerefMut, From, Into};
3+
use std::io::{Read, Write};
4+
5+
/// A helper struct for Borsh that consumes the remaining bytes in a buffer. This is most useful for replicating remaining
6+
/// data in an instruction without the 4 byte length overhead for [`borsh`]'s serialize and deserialize on `Vec`.
7+
#[derive(
8+
Debug, Clone, PartialEq, Eq, Deref, DerefMut, Default, Hash, Ord, PartialOrd, From, Into,
9+
)]
10+
#[repr(transparent)]
11+
pub struct RemainingData(Vec<u8>);
12+
13+
impl BorshDeserialize for RemainingData {
14+
fn deserialize_reader<R: Read>(reader: &mut R) -> std::io::Result<Self> {
15+
let mut data = vec![];
16+
reader.read_to_end(&mut data)?;
17+
Ok(Self(data))
18+
}
19+
}
20+
21+
impl BorshSerialize for RemainingData {
22+
fn serialize<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
23+
writer.write_all(&self.0)
24+
}
25+
}

framework/star_frame/src/entrypoint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/// Macro to define the entrypoint for a `star_frame` program. This wraps the default [`solana_program::entrypoint!`] macro
2-
/// and only needs to take in the [`StarFrameProgram`] type. This will be automatically called by the
2+
/// and only needs to take in the [`StarFrameProgram`](crate::prelude::StarFrameProgram) type. This will be automatically called by the
33
/// [`StarFrameProgram`](star_frame_proc::StarFrameProgram) derive macro if the `no_entrypoint` argument
44
/// is not present.
55
///

0 commit comments

Comments
 (0)