Skip to content

Commit 29f9976

Browse files
jayantkJayant Krishnamurthy
andauthored
make room for more specific errors (#226)
Co-authored-by: Jayant Krishnamurthy <jkrishnamurthy@jumptrading.com>
1 parent b39b536 commit 29f9976

File tree

1 file changed

+58
-36
lines changed

1 file changed

+58
-36
lines changed

program/rust/src/rust_oracle.rs

Lines changed: 58 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,19 @@ pub fn init_mapping(
7575
accounts: &[AccountInfo],
7676
instruction_data: &[u8],
7777
) -> OracleResult {
78-
let [_funding_account, fresh_mapping_account] = match accounts {
79-
[x, y]
80-
if valid_funding_account(x)
81-
&& valid_signable_account(program_id, y, size_of::<pc_map_table_t>())
82-
&& valid_fresh_account(y) =>
83-
{
84-
Ok([x, y])
85-
}
78+
let [funding_account, fresh_mapping_account] = match accounts {
79+
[x, y] => Ok([x, y]),
8680
_ => Err(ProgramError::InvalidArgument),
8781
}?;
8882

83+
check_valid_funding_account(funding_account)?;
84+
check_valid_signable_account(
85+
program_id,
86+
fresh_mapping_account,
87+
size_of::<pc_map_table_t>(),
88+
)?;
89+
check_valid_fresh_account(fresh_mapping_account)?;
90+
8991
// Initialize by setting to zero again (just in case) and populating the account header
9092
let hdr = load::<cmd_hdr_t>(instruction_data)?;
9193
initialize_mapping_account(fresh_mapping_account, hdr.ver_)?;
@@ -98,18 +100,16 @@ pub fn add_mapping(
98100
accounts: &[AccountInfo],
99101
instruction_data: &[u8],
100102
) -> OracleResult {
101-
let [_funding_account, cur_mapping, next_mapping] = match accounts {
102-
[x, y, z]
103-
if valid_funding_account(x)
104-
&& valid_signable_account(program_id, y, size_of::<pc_map_table_t>())
105-
&& valid_signable_account(program_id, z, size_of::<pc_map_table_t>())
106-
&& valid_fresh_account(z) =>
107-
{
108-
Ok([x, y, z])
109-
}
103+
let [funding_account, cur_mapping, next_mapping] = match accounts {
104+
[x, y, z] => Ok([x, y, z]),
110105
_ => Err(ProgramError::InvalidArgument),
111106
}?;
112107

108+
check_valid_funding_account(funding_account)?;
109+
check_valid_signable_account(program_id, cur_mapping, size_of::<pc_map_table_t>())?;
110+
check_valid_signable_account(program_id, next_mapping, size_of::<pc_map_table_t>())?;
111+
check_valid_fresh_account(next_mapping)?;
112+
113113
let hdr = load::<cmd_hdr_t>(instruction_data)?;
114114
let mut cur_mapping = load_mapping_account_mut(cur_mapping, hdr.ver_)?;
115115
pyth_assert(
@@ -142,18 +142,16 @@ pub fn add_price(
142142
return Err(ProgramError::InvalidArgument);
143143
}
144144

145-
let [_funding_account, product_account, price_account] = match accounts {
146-
[x, y, z]
147-
if valid_funding_account(x)
148-
&& valid_signable_account(program_id, y, PC_PROD_ACC_SIZE as usize)
149-
&& valid_signable_account(program_id, z, size_of::<pc_price_t>())
150-
&& valid_fresh_account(z) =>
151-
{
152-
Ok([x, y, z])
153-
}
145+
let [funding_account, product_account, price_account] = match accounts {
146+
[x, y, z] => Ok([x, y, z]),
154147
_ => Err(ProgramError::InvalidArgument),
155148
}?;
156149

150+
check_valid_funding_account(funding_account)?;
151+
check_valid_signable_account(program_id, product_account, PC_PROD_ACC_SIZE as usize)?;
152+
check_valid_signable_account(program_id, price_account, size_of::<pc_price_t>())?;
153+
check_valid_fresh_account(price_account)?;
154+
157155
let mut product_data = load_product_account_mut(product_account, cmd_args.ver_)?;
158156

159157
clear_account(price_account)?;
@@ -177,18 +175,20 @@ pub fn add_product(
177175
accounts: &[AccountInfo],
178176
instruction_data: &[u8],
179177
) -> OracleResult {
180-
let [_funding_account, tail_mapping_account, new_product_account] = match accounts {
181-
[x, y, z]
182-
if valid_funding_account(x)
183-
&& valid_signable_account(program_id, y, size_of::<pc_map_table_t>())
184-
&& valid_signable_account(program_id, z, PC_PROD_ACC_SIZE as usize)
185-
&& valid_fresh_account(z) =>
186-
{
187-
Ok([x, y, z])
188-
}
178+
let [funding_account, tail_mapping_account, new_product_account] = match accounts {
179+
[x, y, z] => Ok([x, y, z]),
189180
_ => Err(ProgramError::InvalidArgument),
190181
}?;
191182

183+
check_valid_funding_account(funding_account)?;
184+
check_valid_signable_account(
185+
program_id,
186+
tail_mapping_account,
187+
size_of::<pc_map_table_t>(),
188+
)?;
189+
check_valid_signable_account(program_id, new_product_account, PC_PROD_ACC_SIZE as usize)?;
190+
check_valid_fresh_account(new_product_account)?;
191+
192192
let hdr = load::<cmd_hdr_t>(instruction_data)?;
193193
let mut mapping_data = load_mapping_account_mut(tail_mapping_account, hdr.ver_)?;
194194
// The mapping account must have free space to add the product account
@@ -217,6 +217,13 @@ fn valid_funding_account(account: &AccountInfo) -> bool {
217217
account.is_signer && account.is_writable
218218
}
219219

220+
fn check_valid_funding_account(account: &AccountInfo) -> Result<(), ProgramError> {
221+
pyth_assert(
222+
valid_funding_account(account),
223+
ProgramError::InvalidArgument,
224+
)
225+
}
226+
220227
fn valid_signable_account(program_id: &Pubkey, account: &AccountInfo, minimum_size: usize) -> bool {
221228
account.is_signer
222229
&& account.is_writable
@@ -225,6 +232,17 @@ fn valid_signable_account(program_id: &Pubkey, account: &AccountInfo, minimum_si
225232
&& Rent::default().is_exempt(account.lamports(), account.data_len())
226233
}
227234

235+
fn check_valid_signable_account(
236+
program_id: &Pubkey,
237+
account: &AccountInfo,
238+
minimum_size: usize,
239+
) -> Result<(), ProgramError> {
240+
pyth_assert(
241+
valid_signable_account(program_id, account, minimum_size),
242+
ProgramError::InvalidArgument,
243+
)
244+
}
245+
228246
/// Returns `true` if the `account` is fresh, i.e., its data can be overwritten.
229247
/// Use this check to prevent accidentally overwriting accounts whose data is already populated.
230248
fn valid_fresh_account(account: &AccountInfo) -> bool {
@@ -235,6 +253,10 @@ fn valid_fresh_account(account: &AccountInfo) -> bool {
235253
}
236254
}
237255

256+
fn check_valid_fresh_account(account: &AccountInfo) -> Result<(), ProgramError> {
257+
pyth_assert(valid_fresh_account(account), ProgramError::InvalidArgument)
258+
}
259+
238260
/// Sets the data of account to all-zero
239261
pub fn clear_account(account: &AccountInfo) -> Result<(), ProgramError> {
240262
let mut data = account
@@ -275,7 +297,7 @@ pub fn initialize_mapping_account(account: &AccountInfo, version: u32) -> Result
275297
mapping_account.ver_ = version;
276298
mapping_account.type_ = PC_ACCTYPE_MAPPING;
277299
mapping_account.size_ =
278-
(size_of::<pc_map_table_t>() - size_of_val(&mapping_account.prod_)) as u32;
300+
try_convert(size_of::<pc_map_table_t>() - size_of_val(&mapping_account.prod_))?;
279301

280302
Ok(())
281303
}

0 commit comments

Comments
 (0)