Skip to content

Commit 08940f1

Browse files
authored
Remove bincode (#314)
* Update authority check to use PDA * Format * Remove bincode from the program code * Comments
1 parent 895eb59 commit 08940f1

File tree

2 files changed

+35
-20
lines changed

2 files changed

+35
-20
lines changed

program/rust/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ bytemuck = "1.11.0"
1414
thiserror = "1.0"
1515
num-derive = "0.3"
1616
num-traits = "0.2"
17-
bincode = "1.3.3"
1817

1918
[dev-dependencies]
2019
solana-program-test = "=1.13.3"
@@ -23,6 +22,7 @@ tokio = "1.14.1"
2322
hex = "0.3.1"
2423
quickcheck = "1"
2524
quickcheck_macros = "1"
25+
bincode = "1.3.3"
2626

2727
[features]
2828
debug = []

program/rust/src/utils.rs

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,21 @@ use {
1717
},
1818
OracleError,
1919
},
20+
bytemuck::{
21+
Pod,
22+
Zeroable,
23+
},
2024
num_traits::FromPrimitive,
2125
solana_program::{
2226
account_info::AccountInfo,
23-
bpf_loader_upgradeable::{
24-
self,
25-
UpgradeableLoaderState,
26-
},
27+
bpf_loader_upgradeable,
2728
program::invoke,
2829
program_error::ProgramError,
2930
pubkey::Pubkey,
3031
system_instruction::transfer,
3132
sysvar::rent::Rent,
3233
},
34+
std::cell::Ref,
3335
};
3436

3537

@@ -210,6 +212,23 @@ pub fn is_component_update(cmd_args: &UpdPriceArgs) -> Result<bool, OracleError>
210212
}
211213
}
212214

215+
/// This struct represents UpgradeableLoaderState from bpf-upgradable-loader.
216+
/// Solana uses bincode for the struct. However the bincode crate is too big the space we have onchain,
217+
/// therefore we will use bytemuck for deserialization
218+
#[repr(C)]
219+
#[derive(Pod, Zeroable, Copy, Clone)]
220+
struct ProgramdataAccount {
221+
/// 3 is the variant for programdata
222+
pub account_type: u32,
223+
/// Space for slot of last upgrade (we don't use this field)
224+
pub slot: [u32; 2],
225+
/// 0 if immutable, 1 if has upgrade authority
226+
pub has_upgrade_authority: u8,
227+
/// Upgrade authority of the program
228+
pub upgrade_authority: Pubkey,
229+
/// Unused field needed for this struct to be Pod
230+
pub unused: [u8; 3],
231+
}
213232

214233
/// Check that `programdata_account` is actually the buffer for `program_id`.
215234
/// Check that the authority in `programdata_account` matches `upgrade_authority_account`.
@@ -218,9 +237,8 @@ pub fn check_is_upgrade_authority_for_program(
218237
programdata_account: &AccountInfo,
219238
program_id: &Pubkey,
220239
) -> Result<(), ProgramError> {
221-
let programdata_deserialized: UpgradeableLoaderState =
222-
bincode::deserialize(&programdata_account.try_borrow_data()?)
223-
.map_err(|_| OracleError::DeserializationError)?;
240+
let programdata_deserialized: Ref<ProgramdataAccount> =
241+
load_account_as::<ProgramdataAccount>(programdata_account)?;
224242

225243
// 1. programdata_account is actually this program's buffer
226244
let (programdata_address, _) =
@@ -233,18 +251,15 @@ pub fn check_is_upgrade_authority_for_program(
233251

234252

235253
// 2. upgrade_authority_account is actually the authority inside programdata_account
236-
if let UpgradeableLoaderState::ProgramData {
237-
slot: _,
238-
upgrade_authority_address: Some(upgrade_authority_key),
239-
} = programdata_deserialized
240-
{
241-
pyth_assert(
242-
upgrade_authority_key.eq(upgrade_authority_account.key),
243-
OracleError::InvalidUpgradeAuthority.into(),
244-
)?;
245-
} else {
246-
return Err(OracleError::InvalidUpgradeAuthority.into());
247-
}
254+
pyth_assert(
255+
programdata_deserialized
256+
.upgrade_authority
257+
.eq(upgrade_authority_account.key)
258+
&& programdata_deserialized.account_type == 3
259+
&& programdata_deserialized.has_upgrade_authority == 1,
260+
OracleError::InvalidUpgradeAuthority.into(),
261+
)?;
262+
248263
Ok(())
249264
}
250265

0 commit comments

Comments
 (0)