From 94b9c8276c3d37338199bd3e6ed39551e0ea8f79 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Mon, 1 Aug 2022 12:16:44 -0700 Subject: [PATCH 01/60] v1 --- program/rust/src/rust_oracle.rs | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index a17970e9f..3b5b8e1c9 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -1,7 +1,11 @@ +use solana_program::program_error::ProgramError; use super::c_entrypoint_wrapper; use crate::error::OracleResult; use solana_program::pubkey::Pubkey; use solana_program::sysvar::slot_history::AccountInfo; +use solana_program::program_memory::sol_memset; +use c_oracle_headers::{pc_map_table_t, SUCCESS}; +use std::mem::{size_of, size_of_val}; ///Calls the c oracle update_price, and updates the Time Machine if needed pub fn update_price( @@ -25,3 +29,44 @@ pub fn update_version( panic!("Need to merge fix to pythd in order to implement this"); Ok(0) //SUCCESS } + + +pub fn init_mapping( + program_id: &Pubkey, + accounts: &Vec, + instruction_data: &[u8], +) -> OracleResult { + // FIXME: this is an extremely scary way to assert because if you forget the ? it doesn't do anything. + pyth_assert(accounts.len() == 2 && + valid_funding_account(accounts.get(0)) && + valid_signable_account(program_id, accounts.get(1), sizeof( pc_map_table_t )), + ERROR_INVALID_ARGUMENT)?; + + + let data = accounts.get(1) + .try_borrow_data() + .map_err(|_| PythError::InvalidAccountData)?; + let mapping_account = load::(*data)?; + + // Check that the account has not already been initialized + pyth_assert(mapping_account.magic_ == 0 && mapping_account.ver_ == 0, ERROR_INVALID_ARGUMENT)?; + + // Initialize by setting to zero again (just in case) and setting + // the version number + let hdr = load::(instruction_data); + sol_memset( data, 0, size_of::() ); + mapping_account.magic_ = PC_MAGIC; + mapping_account.ver_ = hdr.ver_; + mapping_account.type_ = PC_ACCTYPE_MAPPING; + mapping_account.size_ = size_of:: - size_of_val( mapping_account.prod_ ); + + return Result::Ok(SUCCESS); +} + +fn pyth_assert(condition: bool, error_code: ProgramError) -> Result<(), ProgramError> { + return if !condition { + Result::Err(error_code) + } else { + Result::Ok(()) + } +} From 85547e90c3b6b2a5fdca8e39e5a091ff9df5247e Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Mon, 1 Aug 2022 14:38:48 -0700 Subject: [PATCH 02/60] stuff --- program/rust/src/rust_oracle.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 3b5b8e1c9..84432b2ee 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -4,7 +4,7 @@ use crate::error::OracleResult; use solana_program::pubkey::Pubkey; use solana_program::sysvar::slot_history::AccountInfo; use solana_program::program_memory::sol_memset; -use c_oracle_headers::{pc_map_table_t, SUCCESS}; +use crate::c_oracle_headers::{pc_map_table_t, SUCCESS}; use std::mem::{size_of, size_of_val}; ///Calls the c oracle update_price, and updates the Time Machine if needed @@ -38,14 +38,13 @@ pub fn init_mapping( ) -> OracleResult { // FIXME: this is an extremely scary way to assert because if you forget the ? it doesn't do anything. pyth_assert(accounts.len() == 2 && - valid_funding_account(accounts.get(0)) && - valid_signable_account(program_id, accounts.get(1), sizeof( pc_map_table_t )), + valid_funding_account(accounts.get(0)!) && + valid_signable_account(program_id, accounts.get(1)!, sizeof( pc_map_table_t )), ERROR_INVALID_ARGUMENT)?; - - let data = accounts.get(1) + let data = accounts.get(1)! .try_borrow_data() - .map_err(|_| PythError::InvalidAccountData)?; + .map_err(|_| ERROR_INVALID_ARGUMENT)?; let mapping_account = load::(*data)?; // Check that the account has not already been initialized @@ -63,10 +62,18 @@ pub fn init_mapping( return Result::Ok(SUCCESS); } -fn pyth_assert(condition: bool, error_code: ProgramError) -> Result<(), ProgramError> { +pub fn pyth_assert(condition: bool, error_code: ProgramError) -> Result<(), ProgramError> { return if !condition { Result::Err(error_code) } else { Result::Ok(()) } } + +pub fn valid_funding_account(account: &AccountInfo) -> bool { + true +} + +pub fn valid_signable_account(program_id: &Pubkey, account: &AccountInfo, expected_size: usize) -> bool { + true +} \ No newline at end of file From d8bbde23aede1d58ee649bb0f34835ad091a54f8 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Mon, 1 Aug 2022 14:40:28 -0700 Subject: [PATCH 03/60] fix --- program/rust/src/rust_oracle.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 84432b2ee..3191eb41f 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -4,7 +4,7 @@ use crate::error::OracleResult; use solana_program::pubkey::Pubkey; use solana_program::sysvar::slot_history::AccountInfo; use solana_program::program_memory::sol_memset; -use crate::c_oracle_headers::{pc_map_table_t, SUCCESS}; +use crate::c_oracle_header::{pc_map_table_t, SUCCESS}; use std::mem::{size_of, size_of_val}; ///Calls the c oracle update_price, and updates the Time Machine if needed @@ -38,11 +38,12 @@ pub fn init_mapping( ) -> OracleResult { // FIXME: this is an extremely scary way to assert because if you forget the ? it doesn't do anything. pyth_assert(accounts.len() == 2 && - valid_funding_account(accounts.get(0)!) && - valid_signable_account(program_id, accounts.get(1)!, sizeof( pc_map_table_t )), + valid_funding_account(accounts.get(0).unwrap()) && + valid_signable_account(program_id, accounts.get(1).unwrap(), sizeof( pc_map_table_t )), ERROR_INVALID_ARGUMENT)?; - let data = accounts.get(1)! + let data = accounts.get(1) + .unwrap() .try_borrow_data() .map_err(|_| ERROR_INVALID_ARGUMENT)?; let mapping_account = load::(*data)?; From 17462d2834efb3b90a914860fe771e95c6fea7df Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 09:52:53 -0700 Subject: [PATCH 04/60] stuff --- program/rust/src/rust_oracle.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 3191eb41f..637161b24 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -1,11 +1,14 @@ +use std::mem::{size_of, size_of_val}; + use solana_program::program_error::ProgramError; -use super::c_entrypoint_wrapper; -use crate::error::OracleResult; +use solana_program::program_memory::sol_memset; use solana_program::pubkey::Pubkey; use solana_program::sysvar::slot_history::AccountInfo; -use solana_program::program_memory::sol_memset; -use crate::c_oracle_header::{pc_map_table_t, SUCCESS}; -use std::mem::{size_of, size_of_val}; + +use crate::c_oracle_header::pc_map_table_t; +use crate::error::OracleResult; + +use super::c_entrypoint_wrapper; ///Calls the c oracle update_price, and updates the Time Machine if needed pub fn update_price( @@ -39,17 +42,17 @@ pub fn init_mapping( // FIXME: this is an extremely scary way to assert because if you forget the ? it doesn't do anything. pyth_assert(accounts.len() == 2 && valid_funding_account(accounts.get(0).unwrap()) && - valid_signable_account(program_id, accounts.get(1).unwrap(), sizeof( pc_map_table_t )), - ERROR_INVALID_ARGUMENT)?; + valid_signable_account(program_id, accounts.get(1).unwrap(), size_of::), + ProgramError::InvalidArgument)?; let data = accounts.get(1) .unwrap() .try_borrow_data() - .map_err(|_| ERROR_INVALID_ARGUMENT)?; + .map_err(|_| ProgramError::InvalidArgument)?; let mapping_account = load::(*data)?; // Check that the account has not already been initialized - pyth_assert(mapping_account.magic_ == 0 && mapping_account.ver_ == 0, ERROR_INVALID_ARGUMENT)?; + pyth_assert(mapping_account.magic_ == 0 && mapping_account.ver_ == 0, ProgramError::InvalidArgument)?; // Initialize by setting to zero again (just in case) and setting // the version number @@ -60,7 +63,8 @@ pub fn init_mapping( mapping_account.type_ = PC_ACCTYPE_MAPPING; mapping_account.size_ = size_of:: - size_of_val( mapping_account.prod_ ); - return Result::Ok(SUCCESS); + // TODO: bind SUCCESS + return Result::Ok(0); } pub fn pyth_assert(condition: bool, error_code: ProgramError) -> Result<(), ProgramError> { From 67a3c685525bfbd8f6e86294de96046ef93f4f40 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 09:57:13 -0700 Subject: [PATCH 05/60] maybe? --- program/rust/src/bindings.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/program/rust/src/bindings.h b/program/rust/src/bindings.h index e2a2be48b..177d949e3 100644 --- a/program/rust/src/bindings.h +++ b/program/rust/src/bindings.h @@ -13,3 +13,5 @@ typedef unsigned long int uint64_t; #include "../../c/src/oracle/oracle.h" #include "price_t_offsets.h" + +const uint32_t PC_MAGIC_T = PC_MAGIC; \ No newline at end of file From 7587c7c19d280eb0e6f29950339ceee3cbcbf4d7 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 09:57:49 -0700 Subject: [PATCH 06/60] whoops --- program/rust/src/rust_oracle.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 637161b24..68903b7f7 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -58,7 +58,7 @@ pub fn init_mapping( // the version number let hdr = load::(instruction_data); sol_memset( data, 0, size_of::() ); - mapping_account.magic_ = PC_MAGIC; + mapping_account.magic_ = PC_MAGIC_T; mapping_account.ver_ = hdr.ver_; mapping_account.type_ = PC_ACCTYPE_MAPPING; mapping_account.size_ = size_of:: - size_of_val( mapping_account.prod_ ); From be542c31eb09b4d60e38b1188d21c3c14f2d6fed Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 09:59:20 -0700 Subject: [PATCH 07/60] ok --- program/rust/src/rust_oracle.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 68903b7f7..f73bb010e 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -5,7 +5,7 @@ use solana_program::program_memory::sol_memset; use solana_program::pubkey::Pubkey; use solana_program::sysvar::slot_history::AccountInfo; -use crate::c_oracle_header::pc_map_table_t; +use crate::c_oracle_header::{pc_map_table_t, PC_MAGIC_T}; use crate::error::OracleResult; use super::c_entrypoint_wrapper; @@ -42,7 +42,7 @@ pub fn init_mapping( // FIXME: this is an extremely scary way to assert because if you forget the ? it doesn't do anything. pyth_assert(accounts.len() == 2 && valid_funding_account(accounts.get(0).unwrap()) && - valid_signable_account(program_id, accounts.get(1).unwrap(), size_of::), + valid_signable_account(program_id, accounts.get(1).unwrap(), size_of::()), ProgramError::InvalidArgument)?; let data = accounts.get(1) @@ -61,7 +61,7 @@ pub fn init_mapping( mapping_account.magic_ = PC_MAGIC_T; mapping_account.ver_ = hdr.ver_; mapping_account.type_ = PC_ACCTYPE_MAPPING; - mapping_account.size_ = size_of:: - size_of_val( mapping_account.prod_ ); + mapping_account.size_ = size_of::() - size_of_val( mapping_account.prod_ ); // TODO: bind SUCCESS return Result::Ok(0); From b39bcf9c03bc46ff51bfd89400f9edda33f1b40b Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 10:00:19 -0700 Subject: [PATCH 08/60] blah --- program/rust/src/bindings.h | 2 +- program/rust/src/rust_oracle.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/program/rust/src/bindings.h b/program/rust/src/bindings.h index 177d949e3..75a118239 100644 --- a/program/rust/src/bindings.h +++ b/program/rust/src/bindings.h @@ -14,4 +14,4 @@ typedef unsigned long int uint64_t; #include "../../c/src/oracle/oracle.h" #include "price_t_offsets.h" -const uint32_t PC_MAGIC_T = PC_MAGIC; \ No newline at end of file +const uint32_t PC_MAGIC = PC_MAGIC; \ No newline at end of file diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index f73bb010e..a5a743a80 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -5,7 +5,7 @@ use solana_program::program_memory::sol_memset; use solana_program::pubkey::Pubkey; use solana_program::sysvar::slot_history::AccountInfo; -use crate::c_oracle_header::{pc_map_table_t, PC_MAGIC_T}; +use crate::c_oracle_header::{pc_map_table_t, PC_MAGIC}; use crate::error::OracleResult; use super::c_entrypoint_wrapper; From e8f3aa4722fa9cc0225becc418872242a66b7e02 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 10:05:59 -0700 Subject: [PATCH 09/60] more constants --- program/rust/src/bindings.h | 9 ++++++++- program/rust/src/rust_oracle.rs | 6 +++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/program/rust/src/bindings.h b/program/rust/src/bindings.h index 75a118239..abc7103a0 100644 --- a/program/rust/src/bindings.h +++ b/program/rust/src/bindings.h @@ -14,4 +14,11 @@ typedef unsigned long int uint64_t; #include "../../c/src/oracle/oracle.h" #include "price_t_offsets.h" -const uint32_t PC_MAGIC = PC_MAGIC; \ No newline at end of file +// Store #define constants as values so they are accessible from rust. +const uint32_t PC_MAGIC_V = PC_MAGIC; +const uint32_t PC_VERSION_V = PC_VERSION; + +const uint32_t PC_ACCTYPE_MAPPING_V = PC_ACCTYPE_MAPPING; +const uint32_t PC_ACCTYPE_PRODUCT_V = PC_ACCTYPE_PRODUCT; +const uint32_t PC_ACCTYPE_PRICE_V = PC_ACCTYPE_PRICE; +const uint32_t PC_ACCTYPE_TEST_V = PC_ACCTYPE_TEST; diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index a5a743a80..6af8ddd39 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -5,7 +5,7 @@ use solana_program::program_memory::sol_memset; use solana_program::pubkey::Pubkey; use solana_program::sysvar::slot_history::AccountInfo; -use crate::c_oracle_header::{pc_map_table_t, PC_MAGIC}; +use crate::c_oracle_header::{pc_map_table_t, PC_MAGIC_V, PC_ACCTYPE_MAPPING_V}; use crate::error::OracleResult; use super::c_entrypoint_wrapper; @@ -58,9 +58,9 @@ pub fn init_mapping( // the version number let hdr = load::(instruction_data); sol_memset( data, 0, size_of::() ); - mapping_account.magic_ = PC_MAGIC_T; + mapping_account.magic_ = PC_MAGIC_V; mapping_account.ver_ = hdr.ver_; - mapping_account.type_ = PC_ACCTYPE_MAPPING; + mapping_account.type_ = PC_ACCTYPE_MAPPING_V; mapping_account.size_ = size_of::() - size_of_val( mapping_account.prod_ ); // TODO: bind SUCCESS From b910d46a9643b0d1f84493ade630f3650c23892e Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 10:14:25 -0700 Subject: [PATCH 10/60] ok --- program/rust/src/rust_oracle.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 6af8ddd39..5354c07e7 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -57,7 +57,7 @@ pub fn init_mapping( // Initialize by setting to zero again (just in case) and setting // the version number let hdr = load::(instruction_data); - sol_memset( data, 0, size_of::() ); + sol_memset( *data, 0, size_of::() ); mapping_account.magic_ = PC_MAGIC_V; mapping_account.ver_ = hdr.ver_; mapping_account.type_ = PC_ACCTYPE_MAPPING_V; From 3c7c2705eb47cb4cdde6643172d111cc75bbbcc0 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 10:15:29 -0700 Subject: [PATCH 11/60] blah --- program/rust/src/rust_oracle.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 5354c07e7..bba3ca500 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -5,7 +5,7 @@ use solana_program::program_memory::sol_memset; use solana_program::pubkey::Pubkey; use solana_program::sysvar::slot_history::AccountInfo; -use crate::c_oracle_header::{pc_map_table_t, PC_MAGIC_V, PC_ACCTYPE_MAPPING_V}; +use crate::c_oracle_header::{cmd_hdr_t, pc_map_table_t, PC_MAGIC_V, PC_ACCTYPE_MAPPING_V}; use crate::error::OracleResult; use super::c_entrypoint_wrapper; From 7e9b3229b6e2ed654ee203fc1be487d202de08dc Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 10:35:12 -0700 Subject: [PATCH 12/60] imlement --- program/rust/src/rust_oracle.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index bba3ca500..c7afe57c5 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -1,8 +1,10 @@ use std::mem::{size_of, size_of_val}; +use solana_program::entrypoint::SUCCESS; use solana_program::program_error::ProgramError; use solana_program::program_memory::sol_memset; use solana_program::pubkey::Pubkey; +use solana_program::rent::Rent; use solana_program::sysvar::slot_history::AccountInfo; use crate::c_oracle_header::{cmd_hdr_t, pc_map_table_t, PC_MAGIC_V, PC_ACCTYPE_MAPPING_V}; @@ -30,7 +32,7 @@ pub fn update_version( instruction_data: &[u8], ) -> OracleResult { panic!("Need to merge fix to pythd in order to implement this"); - Ok(0) //SUCCESS + Ok(SUCCESS) } @@ -63,8 +65,7 @@ pub fn init_mapping( mapping_account.type_ = PC_ACCTYPE_MAPPING_V; mapping_account.size_ = size_of::() - size_of_val( mapping_account.prod_ ); - // TODO: bind SUCCESS - return Result::Ok(0); + Result::Ok(SUCCESS) } pub fn pyth_assert(condition: bool, error_code: ProgramError) -> Result<(), ProgramError> { @@ -76,9 +77,13 @@ pub fn pyth_assert(condition: bool, error_code: ProgramError) -> Result<(), Prog } pub fn valid_funding_account(account: &AccountInfo) -> bool { - true + account.is_signer && account.is_writable } -pub fn valid_signable_account(program_id: &Pubkey, account: &AccountInfo, expected_size: usize) -> bool { - true +pub fn valid_signable_account(program_id: &Pubkey, account: &AccountInfo, minimum_size: usize) -> bool { + account.is_signer && + account.is_writable && + account.owner == program_id && + account.data_len() >= minimum_size && + Rent::default().is_exempt(account.lamports(), account.data_len()) } \ No newline at end of file From c57cae00b8ac3401b3fe30a8e4c2dba8ddfacb97 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 10:43:49 -0700 Subject: [PATCH 13/60] maybe --- program/rust/build.rs | 2 +- program/rust/src/rust_oracle.rs | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/program/rust/build.rs b/program/rust/build.rs index b8aee2acb..06d1509a6 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -4,7 +4,7 @@ use bindgen::Builder; fn main() { println!("cargo:rustc-link-search=./program/c/target"); - let borsh_derives = ["BorshSerialize".to_string(), "BorshDeserialize".to_string()]; + let borsh_derives = ["BorshSerialize".to_string(), "BorshDeserialize".to_string(), "Pod".to_string()]; //make a parser and to it type, traits pairs let mut parser = build_utils::DeriveAdderParserCallback::new(); diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index c7afe57c5..5ea870c5a 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -41,7 +41,6 @@ pub fn init_mapping( accounts: &Vec, instruction_data: &[u8], ) -> OracleResult { - // FIXME: this is an extremely scary way to assert because if you forget the ? it doesn't do anything. pyth_assert(accounts.len() == 2 && valid_funding_account(accounts.get(0).unwrap()) && valid_signable_account(program_id, accounts.get(1).unwrap(), size_of::()), @@ -68,6 +67,7 @@ pub fn init_mapping( Result::Ok(SUCCESS) } +// FIXME: this is an extremely scary way to check errors because if you forget the ? after calling it, it doesn't do anything. pub fn pyth_assert(condition: bool, error_code: ProgramError) -> Result<(), ProgramError> { return if !condition { Result::Err(error_code) @@ -86,4 +86,15 @@ pub fn valid_signable_account(program_id: &Pubkey, account: &AccountInfo, minimu account.owner == program_id && account.data_len() >= minimum_size && Rent::default().is_exempt(account.lamports(), account.data_len()) +} + +fn load(data: &[u8]) -> Result<&T, PodCastError> { + let size = size_of::(); + if data.len() >= size { + Ok(from_bytes(cast_slice::(try_cast_slice( + &data[0..size], + )?))) + } else { + Err(PodCastError::SizeMismatch) + } } \ No newline at end of file From ab38504d6362281360a5fc03584c14f55ad6a904 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 10:46:14 -0700 Subject: [PATCH 14/60] ok --- program/rust/src/c_oracle_header.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/program/rust/src/c_oracle_header.rs b/program/rust/src/c_oracle_header.rs index 5f2f8399f..f73322a01 100644 --- a/program/rust/src/c_oracle_header.rs +++ b/program/rust/src/c_oracle_header.rs @@ -9,6 +9,8 @@ use borsh::{ BorshDeserialize, BorshSerialize, }; +use pod::Pod; + //bindings.rs is generated by build.rs to include //things defined in bindings.h include!("../bindings.rs"); From 71e97c74d54c1db878dca251da8ec863db835b74 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 10:48:03 -0700 Subject: [PATCH 15/60] ok --- program/rust/Cargo.toml | 2 +- program/rust/src/c_oracle_header.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/program/rust/Cargo.toml b/program/rust/Cargo.toml index c3e881ac5..7f5d4245e 100644 --- a/program/rust/Cargo.toml +++ b/program/rust/Cargo.toml @@ -13,8 +13,8 @@ bindgen = "0.60.1" [dependencies] solana-program = "=1.10.29" borsh = "0.9" +bytemuck = "1.7.2" thiserror = "1.0" - [lib] crate-type = ["cdylib", "lib"] diff --git a/program/rust/src/c_oracle_header.rs b/program/rust/src/c_oracle_header.rs index f73322a01..d8d9726b9 100644 --- a/program/rust/src/c_oracle_header.rs +++ b/program/rust/src/c_oracle_header.rs @@ -9,7 +9,7 @@ use borsh::{ BorshDeserialize, BorshSerialize, }; -use pod::Pod; +use bytemuck::Pod; //bindings.rs is generated by build.rs to include //things defined in bindings.h From 04891b0df4a8085099842f4a4cbd5a974f92012e Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 10:49:28 -0700 Subject: [PATCH 16/60] ok --- program/rust/src/rust_oracle.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 5ea870c5a..4ddb110b4 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -1,5 +1,6 @@ use std::mem::{size_of, size_of_val}; +use bytemuck::{from_bytes, try_cast_slice, cast_slice, Pod, PodCastError}; use solana_program::entrypoint::SUCCESS; use solana_program::program_error::ProgramError; use solana_program::program_memory::sol_memset; @@ -7,7 +8,7 @@ use solana_program::pubkey::Pubkey; use solana_program::rent::Rent; use solana_program::sysvar::slot_history::AccountInfo; -use crate::c_oracle_header::{cmd_hdr_t, pc_map_table_t, PC_MAGIC_V, PC_ACCTYPE_MAPPING_V}; +use crate::c_oracle_header::{cmd_hdr_t, PC_ACCTYPE_MAPPING_V, PC_MAGIC_V, pc_map_table_t}; use crate::error::OracleResult; use super::c_entrypoint_wrapper; From 71c9888144921583adf3daff085e3f236bc4a968 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 10:49:58 -0700 Subject: [PATCH 17/60] ok --- program/rust/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/rust/build.rs b/program/rust/build.rs index 06d1509a6..358122f32 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -4,7 +4,7 @@ use bindgen::Builder; fn main() { println!("cargo:rustc-link-search=./program/c/target"); - let borsh_derives = ["BorshSerialize".to_string(), "BorshDeserialize".to_string(), "Pod".to_string()]; + let borsh_derives = ["BorshSerialize".to_string(), "BorshDeserialize".to_string(), "Pod".to_string(), "Zeroable".to_string()]; //make a parser and to it type, traits pairs let mut parser = build_utils::DeriveAdderParserCallback::new(); From 9c1ca66af9045c73dac012eb73435659ee64853d Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 10:50:19 -0700 Subject: [PATCH 18/60] ok --- program/rust/src/c_oracle_header.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/rust/src/c_oracle_header.rs b/program/rust/src/c_oracle_header.rs index d8d9726b9..c2c5917cb 100644 --- a/program/rust/src/c_oracle_header.rs +++ b/program/rust/src/c_oracle_header.rs @@ -9,7 +9,7 @@ use borsh::{ BorshDeserialize, BorshSerialize, }; -use bytemuck::Pod; +use bytemuck::{Pod, Zeroable}; //bindings.rs is generated by build.rs to include //things defined in bindings.h From 3e94f78197af2779338eab9c42d5d560c7696bcf Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 10:52:15 -0700 Subject: [PATCH 19/60] ok --- program/rust/build.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/program/rust/build.rs b/program/rust/build.rs index 358122f32..8a0a72c3a 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -13,6 +13,10 @@ fn main() { parser.register_traits("pc_price_info", borsh_derives.to_vec()); parser.register_traits("cmd_upd_price", borsh_derives.to_vec()); parser.register_traits("pc_ema", borsh_derives.to_vec()); + parser.register_traits("pc_price", borsh_derives.to_vec()); + parser.register_traits("pc_prod", borsh_derives.to_vec()); + parser.register_traits("pc_map_table", borsh_derives.to_vec()); + //generate and write bindings let bindings = Builder::default() From d578aa604e5f7d4444218aaedf13dcbc71a52b88 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 11:08:02 -0700 Subject: [PATCH 20/60] ok --- program/rust/build.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/program/rust/build.rs b/program/rust/build.rs index 8a0a72c3a..ef3136bf5 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -4,7 +4,8 @@ use bindgen::Builder; fn main() { println!("cargo:rustc-link-search=./program/c/target"); - let borsh_derives = ["BorshSerialize".to_string(), "BorshDeserialize".to_string(), "Pod".to_string(), "Zeroable".to_string()]; + let borsh_derives = ["BorshSerialize".to_string(), "BorshDeserialize".to_string()]; + let pod_derives = ["Pod".to_string(), "Zeroable".to_string()]; //make a parser and to it type, traits pairs let mut parser = build_utils::DeriveAdderParserCallback::new(); @@ -13,9 +14,9 @@ fn main() { parser.register_traits("pc_price_info", borsh_derives.to_vec()); parser.register_traits("cmd_upd_price", borsh_derives.to_vec()); parser.register_traits("pc_ema", borsh_derives.to_vec()); - parser.register_traits("pc_price", borsh_derives.to_vec()); - parser.register_traits("pc_prod", borsh_derives.to_vec()); - parser.register_traits("pc_map_table", borsh_derives.to_vec()); + parser.register_traits("pc_price", pod_derives.to_vec()); + parser.register_traits("pc_prod", pod_derives.to_vec()); + parser.register_traits("pc_map_table", pod_derives.to_vec()); //generate and write bindings From 36fef92ed65b0122632448ce23033b6316bac931 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 11:15:48 -0700 Subject: [PATCH 21/60] ok --- program/rust/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/rust/build.rs b/program/rust/build.rs index ef3136bf5..7c8d4ef24 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -9,7 +9,7 @@ fn main() { //make a parser and to it type, traits pairs let mut parser = build_utils::DeriveAdderParserCallback::new(); - parser.register_traits("cmd_hdr", borsh_derives.to_vec()); + parser.register_traits("cmd_hdr", [borsh_derives, pod_derives].concat()); parser.register_traits("pc_acc", borsh_derives.to_vec()); parser.register_traits("pc_price_info", borsh_derives.to_vec()); parser.register_traits("cmd_upd_price", borsh_derives.to_vec()); From 1abc3a2b7a2f3b083603ce41d09a432db397214e Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 11:16:26 -0700 Subject: [PATCH 22/60] ok --- program/rust/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/rust/build.rs b/program/rust/build.rs index 7c8d4ef24..7326db508 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -9,7 +9,7 @@ fn main() { //make a parser and to it type, traits pairs let mut parser = build_utils::DeriveAdderParserCallback::new(); - parser.register_traits("cmd_hdr", [borsh_derives, pod_derives].concat()); + parser.register_traits("cmd_hdr", [borsh_derives.clone(), pod_derives.clone()].concat()); parser.register_traits("pc_acc", borsh_derives.to_vec()); parser.register_traits("pc_price_info", borsh_derives.to_vec()); parser.register_traits("cmd_upd_price", borsh_derives.to_vec()); From bd81625787948581fdd7c4e3ad01ee133ab0018c Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 11:19:32 -0700 Subject: [PATCH 23/60] ok --- program/rust/build.rs | 3 ++- program/rust/src/rust_oracle.rs | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/program/rust/build.rs b/program/rust/build.rs index 7326db508..6f5fe3fa5 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -13,7 +13,8 @@ fn main() { parser.register_traits("pc_acc", borsh_derives.to_vec()); parser.register_traits("pc_price_info", borsh_derives.to_vec()); parser.register_traits("cmd_upd_price", borsh_derives.to_vec()); - parser.register_traits("pc_ema", borsh_derives.to_vec()); + parser.register_traits("pc_ema", [borsh_derives.clone(), pod_derives.clone()].concat()); + parser.register_traits("pc_pub_key", pod_derives.to_vec()); parser.register_traits("pc_price", pod_derives.to_vec()); parser.register_traits("pc_prod", pod_derives.to_vec()); parser.register_traits("pc_map_table", pod_derives.to_vec()); diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 4ddb110b4..f94bfdccb 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -58,12 +58,12 @@ pub fn init_mapping( // Initialize by setting to zero again (just in case) and setting // the version number - let hdr = load::(instruction_data); + let hdr = load::(instruction_data)?; sol_memset( *data, 0, size_of::() ); mapping_account.magic_ = PC_MAGIC_V; mapping_account.ver_ = hdr.ver_; mapping_account.type_ = PC_ACCTYPE_MAPPING_V; - mapping_account.size_ = size_of::() - size_of_val( mapping_account.prod_ ); + mapping_account.size_ = (size_of::() - size_of_val( &mapping_account.prod_ )) as usize; Result::Ok(SUCCESS) } From f5f3d807e9f1877bfc8326012db2b5b8669939df Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 11:33:41 -0700 Subject: [PATCH 24/60] ok --- program/c/src/oracle/oracle.h | 3 +-- program/rust/build.rs | 1 + program/rust/src/rust_oracle.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/program/c/src/oracle/oracle.h b/program/c/src/oracle/oracle.h index a85e0632c..54b98ac3f 100644 --- a/program/c/src/oracle/oracle.h +++ b/program/c/src/oracle/oracle.h @@ -72,9 +72,8 @@ const uint64_t sysvar_clock[] = { }; // public key of symbol or publisher account -typedef union pc_pub_key +typedef struct pc_pub_key { - uint8_t k1_[PC_PUBKEY_SIZE]; uint64_t k8_[PC_PUBKEY_SIZE_64]; } pc_pub_key_t; diff --git a/program/rust/build.rs b/program/rust/build.rs index 6f5fe3fa5..7c0260b92 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -18,6 +18,7 @@ fn main() { parser.register_traits("pc_price", pod_derives.to_vec()); parser.register_traits("pc_prod", pod_derives.to_vec()); parser.register_traits("pc_map_table", pod_derives.to_vec()); + parser. //generate and write bindings diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index f94bfdccb..483bae4e3 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -63,7 +63,7 @@ pub fn init_mapping( mapping_account.magic_ = PC_MAGIC_V; mapping_account.ver_ = hdr.ver_; mapping_account.type_ = PC_ACCTYPE_MAPPING_V; - mapping_account.size_ = (size_of::() - size_of_val( &mapping_account.prod_ )) as usize; + mapping_account.size_ = (size_of::() - size_of_val( &mapping_account.prod_ )) as u32; Result::Ok(SUCCESS) } From d1f5f160d24fefe8177c74901719d9ae67f3d430 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 11:33:58 -0700 Subject: [PATCH 25/60] ok --- program/rust/build.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/program/rust/build.rs b/program/rust/build.rs index 7c0260b92..3382876b1 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -18,8 +18,6 @@ fn main() { parser.register_traits("pc_price", pod_derives.to_vec()); parser.register_traits("pc_prod", pod_derives.to_vec()); parser.register_traits("pc_map_table", pod_derives.to_vec()); - parser. - //generate and write bindings let bindings = Builder::default() From 44a53027aa77b14edcc3cefdf627d3da8e12d7ec Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 11:37:49 -0700 Subject: [PATCH 26/60] ok --- program/rust/build.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/program/rust/build.rs b/program/rust/build.rs index 3382876b1..5fb423586 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -15,6 +15,8 @@ fn main() { parser.register_traits("cmd_upd_price", borsh_derives.to_vec()); parser.register_traits("pc_ema", [borsh_derives.clone(), pod_derives.clone()].concat()); parser.register_traits("pc_pub_key", pod_derives.to_vec()); + parser.register_traits("[pc_pub_key; 640]", pod_derives.to_vec()); + parser.register_traits("pc_price", pod_derives.to_vec()); parser.register_traits("pc_prod", pod_derives.to_vec()); parser.register_traits("pc_map_table", pod_derives.to_vec()); From 3ad90a7135db944168243c7e01741184635cba3b Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 11:45:15 -0700 Subject: [PATCH 27/60] ok --- program/rust/build.rs | 5 +++-- program/rust/src/c_oracle_header.rs | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/program/rust/build.rs b/program/rust/build.rs index 5fb423586..719908bc6 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -14,12 +14,13 @@ fn main() { parser.register_traits("pc_price_info", borsh_derives.to_vec()); parser.register_traits("cmd_upd_price", borsh_derives.to_vec()); parser.register_traits("pc_ema", [borsh_derives.clone(), pod_derives.clone()].concat()); - parser.register_traits("pc_pub_key", pod_derives.to_vec()); - parser.register_traits("[pc_pub_key; 640]", pod_derives.to_vec()); + /* + parser.register_traits("pc_pub_key", pod_derives.to_vec()); parser.register_traits("pc_price", pod_derives.to_vec()); parser.register_traits("pc_prod", pod_derives.to_vec()); parser.register_traits("pc_map_table", pod_derives.to_vec()); + */ //generate and write bindings let bindings = Builder::default() diff --git a/program/rust/src/c_oracle_header.rs b/program/rust/src/c_oracle_header.rs index c2c5917cb..cac720811 100644 --- a/program/rust/src/c_oracle_header.rs +++ b/program/rust/src/c_oracle_header.rs @@ -14,3 +14,7 @@ use bytemuck::{Pod, Zeroable}; //bindings.rs is generated by build.rs to include //things defined in bindings.h include!("../bindings.rs"); + +#[cfg(target_endian = "little")] +unsafe impl Pod for pc_map_table { +} From 2529aa7b6849c13f4ed33d05ea6cc1960d6cb73b Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 11:45:39 -0700 Subject: [PATCH 28/60] ok --- program/rust/src/c_oracle_header.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/program/rust/src/c_oracle_header.rs b/program/rust/src/c_oracle_header.rs index cac720811..807d8a379 100644 --- a/program/rust/src/c_oracle_header.rs +++ b/program/rust/src/c_oracle_header.rs @@ -15,6 +15,10 @@ use bytemuck::{Pod, Zeroable}; //things defined in bindings.h include!("../bindings.rs"); +#[cfg(target_endian = "little")] +unsafe impl Zeroable for pc_map_table { +} + #[cfg(target_endian = "little")] unsafe impl Pod for pc_map_table { } From 556790967269221d5d5431ca24eb87a5062b0ac9 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 11:46:53 -0700 Subject: [PATCH 29/60] ok --- program/rust/build.rs | 12 ++---------- program/rust/src/c_oracle_header.rs | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/program/rust/build.rs b/program/rust/build.rs index 719908bc6..b8aee2acb 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -5,22 +5,14 @@ fn main() { println!("cargo:rustc-link-search=./program/c/target"); let borsh_derives = ["BorshSerialize".to_string(), "BorshDeserialize".to_string()]; - let pod_derives = ["Pod".to_string(), "Zeroable".to_string()]; //make a parser and to it type, traits pairs let mut parser = build_utils::DeriveAdderParserCallback::new(); - parser.register_traits("cmd_hdr", [borsh_derives.clone(), pod_derives.clone()].concat()); + parser.register_traits("cmd_hdr", borsh_derives.to_vec()); parser.register_traits("pc_acc", borsh_derives.to_vec()); parser.register_traits("pc_price_info", borsh_derives.to_vec()); parser.register_traits("cmd_upd_price", borsh_derives.to_vec()); - parser.register_traits("pc_ema", [borsh_derives.clone(), pod_derives.clone()].concat()); - - /* - parser.register_traits("pc_pub_key", pod_derives.to_vec()); - parser.register_traits("pc_price", pod_derives.to_vec()); - parser.register_traits("pc_prod", pod_derives.to_vec()); - parser.register_traits("pc_map_table", pod_derives.to_vec()); - */ + parser.register_traits("pc_ema", borsh_derives.to_vec()); //generate and write bindings let bindings = Builder::default() diff --git a/program/rust/src/c_oracle_header.rs b/program/rust/src/c_oracle_header.rs index 807d8a379..fa70cd5e0 100644 --- a/program/rust/src/c_oracle_header.rs +++ b/program/rust/src/c_oracle_header.rs @@ -22,3 +22,19 @@ unsafe impl Zeroable for pc_map_table { #[cfg(target_endian = "little")] unsafe impl Pod for pc_map_table { } + +#[cfg(target_endian = "little")] +unsafe impl Zeroable for pc_prod { +} + +#[cfg(target_endian = "little")] +unsafe impl Pod for pc_prod { +} + +#[cfg(target_endian = "little")] +unsafe impl Zeroable for pc_price { +} + +#[cfg(target_endian = "little")] +unsafe impl Pod for pc_price { +} From 0f2369297d9dfd6f4bb075fde39d6963e9187017 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 11:50:31 -0700 Subject: [PATCH 30/60] ok --- program/rust/src/c_oracle_header.rs | 8 ++++++++ program/rust/src/error.rs | 1 + program/rust/src/rust_oracle.rs | 4 ++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/program/rust/src/c_oracle_header.rs b/program/rust/src/c_oracle_header.rs index fa70cd5e0..215060fff 100644 --- a/program/rust/src/c_oracle_header.rs +++ b/program/rust/src/c_oracle_header.rs @@ -38,3 +38,11 @@ unsafe impl Zeroable for pc_price { #[cfg(target_endian = "little")] unsafe impl Pod for pc_price { } + +#[cfg(target_endian = "little")] +unsafe impl Zeroable for cmd_hdr { +} + +#[cfg(target_endian = "little")] +unsafe impl Pod for cmd_hdr { +} diff --git a/program/rust/src/error.rs b/program/rust/src/error.rs index 0bdc2b1ac..1d1ca61ab 100644 --- a/program/rust/src/error.rs +++ b/program/rust/src/error.rs @@ -2,6 +2,7 @@ use solana_program::program_error::ProgramError; use std::result::Result; use thiserror::Error; + // similar to ProgramResult but allows for multiple success values pub type OracleResult = Result; diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 483bae4e3..4e50881ac 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -51,14 +51,14 @@ pub fn init_mapping( .unwrap() .try_borrow_data() .map_err(|_| ProgramError::InvalidArgument)?; - let mapping_account = load::(*data)?; + let mapping_account = load::(*data).map_err(ProgramError::InvalidArgument)?; // Check that the account has not already been initialized pyth_assert(mapping_account.magic_ == 0 && mapping_account.ver_ == 0, ProgramError::InvalidArgument)?; // Initialize by setting to zero again (just in case) and setting // the version number - let hdr = load::(instruction_data)?; + let hdr = load::(instruction_data).map_err(ProgramError::InvalidArgument)?; sol_memset( *data, 0, size_of::() ); mapping_account.magic_ = PC_MAGIC_V; mapping_account.ver_ = hdr.ver_; From fb3153be74b3548d41068003c1eded1ff212204b Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 11:51:06 -0700 Subject: [PATCH 31/60] ok --- program/rust/src/rust_oracle.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 4e50881ac..42de5575e 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -51,14 +51,14 @@ pub fn init_mapping( .unwrap() .try_borrow_data() .map_err(|_| ProgramError::InvalidArgument)?; - let mapping_account = load::(*data).map_err(ProgramError::InvalidArgument)?; + let mapping_account = load::(*data).map_err(|_| ProgramError::InvalidArgument)?; // Check that the account has not already been initialized pyth_assert(mapping_account.magic_ == 0 && mapping_account.ver_ == 0, ProgramError::InvalidArgument)?; // Initialize by setting to zero again (just in case) and setting // the version number - let hdr = load::(instruction_data).map_err(ProgramError::InvalidArgument)?; + let hdr = load::(instruction_data).map_err(|_| ProgramError::InvalidArgument)?; sol_memset( *data, 0, size_of::() ); mapping_account.magic_ = PC_MAGIC_V; mapping_account.ver_ = hdr.ver_; From acd242a9c0e55601e8fe27a31e5e7bb88ac11aa9 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 11:53:49 -0700 Subject: [PATCH 32/60] ok --- program/rust/src/rust_oracle.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 42de5575e..7e2815a4e 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -49,9 +49,9 @@ pub fn init_mapping( let data = accounts.get(1) .unwrap() - .try_borrow_data() + .try_borrow_mut_data() .map_err(|_| ProgramError::InvalidArgument)?; - let mapping_account = load::(*data).map_err(|_| ProgramError::InvalidArgument)?; + let mapping_account = load_mut::(*data).map_err(|_| ProgramError::InvalidArgument)?; // Check that the account has not already been initialized pyth_assert(mapping_account.magic_ == 0 && mapping_account.ver_ == 0, ProgramError::InvalidArgument)?; @@ -98,4 +98,15 @@ fn load(data: &[u8]) -> Result<&T, PodCastError> { } else { Err(PodCastError::SizeMismatch) } +} + +fn load_mut(data: mut &[u8]) -> Result { + let size = size_of::(); + if data.len() >= size { + Ok(from_bytes_mut(cast_slice_mut::(try_cast_slice_mut( + &data[0..size], + )?))) + } else { + Err(PodCastError::SizeMismatch) + } } \ No newline at end of file From b8eb1d7134dd5f84ed792ede399c093bffd1e93d Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 11:54:29 -0700 Subject: [PATCH 33/60] ok --- program/rust/src/rust_oracle.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 7e2815a4e..6e89a9aa7 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -100,7 +100,7 @@ fn load(data: &[u8]) -> Result<&T, PodCastError> { } } -fn load_mut(data: mut &[u8]) -> Result { +fn load_mut(data: &mut[u8]) -> Result<&mut T, PodCastError> { let size = size_of::(); if data.len() >= size { Ok(from_bytes_mut(cast_slice_mut::(try_cast_slice_mut( From 97075c6e5c2ca821bb4387d5022253bf815b20ac Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 11:54:55 -0700 Subject: [PATCH 34/60] ok --- program/rust/src/rust_oracle.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 6e89a9aa7..db2d5bdfa 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -1,6 +1,6 @@ use std::mem::{size_of, size_of_val}; -use bytemuck::{from_bytes, try_cast_slice, cast_slice, Pod, PodCastError}; +use bytemuck::{from_bytes, try_cast_slice, cast_slice, from_bytes_mut, try_cast_slice_mut, cast_slice_mut, Pod, PodCastError}; use solana_program::entrypoint::SUCCESS; use solana_program::program_error::ProgramError; use solana_program::program_memory::sol_memset; From 15d013f6c1fc903da2fbd49239664ae8f2781d5b Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 11:55:11 -0700 Subject: [PATCH 35/60] ok --- program/rust/src/rust_oracle.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index db2d5bdfa..c26f69e14 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -104,7 +104,7 @@ fn load_mut(data: &mut[u8]) -> Result<&mut T, PodCastError> { let size = size_of::(); if data.len() >= size { Ok(from_bytes_mut(cast_slice_mut::(try_cast_slice_mut( - &data[0..size], + &mut data[0..size], )?))) } else { Err(PodCastError::SizeMismatch) From 2364894196419e8da347912e94ead7752af8562e Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 11:55:33 -0700 Subject: [PATCH 36/60] ok --- program/rust/src/rust_oracle.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index c26f69e14..905140aa7 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -47,7 +47,7 @@ pub fn init_mapping( valid_signable_account(program_id, accounts.get(1).unwrap(), size_of::()), ProgramError::InvalidArgument)?; - let data = accounts.get(1) + let mut data = accounts.get(1) .unwrap() .try_borrow_mut_data() .map_err(|_| ProgramError::InvalidArgument)?; From 7d12c0edfe711e25aacc80f0b8d120677b635981 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 11:59:58 -0700 Subject: [PATCH 37/60] ok --- program/rust/src/rust_oracle.rs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 905140aa7..3e26ee761 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -47,11 +47,11 @@ pub fn init_mapping( valid_signable_account(program_id, accounts.get(1).unwrap(), size_of::()), ProgramError::InvalidArgument)?; - let mut data = accounts.get(1) + let data = accounts.get(1) .unwrap() - .try_borrow_mut_data() + .try_borrow_data() .map_err(|_| ProgramError::InvalidArgument)?; - let mapping_account = load_mut::(*data).map_err(|_| ProgramError::InvalidArgument)?; + let mapping_account = load::(*data).map_err(|_| ProgramError::InvalidArgument)?; // Check that the account has not already been initialized pyth_assert(mapping_account.magic_ == 0 && mapping_account.ver_ == 0, ProgramError::InvalidArgument)?; @@ -59,7 +59,19 @@ pub fn init_mapping( // Initialize by setting to zero again (just in case) and setting // the version number let hdr = load::(instruction_data).map_err(|_| ProgramError::InvalidArgument)?; - sol_memset( *data, 0, size_of::() ); + + let mut mut_data = accounts.get(1) + .unwrap() + .try_borrow_data_mut() + .map_err(|_| ProgramError::InvalidArgument)?; + sol_memset( *mut_data, 0, size_of::() ); + + + let data2 = accounts.get(1) + .unwrap() + .try_borrow_data_mut() + .map_err(|_| ProgramError::InvalidArgument)?; + let mut mapping_account = load_mut::(*data2).map_err(|_| ProgramError::InvalidArgument)?; mapping_account.magic_ = PC_MAGIC_V; mapping_account.ver_ = hdr.ver_; mapping_account.type_ = PC_ACCTYPE_MAPPING_V; From de8dc00bab4a86175d37980fbd2391f91769e666 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 12:00:33 -0700 Subject: [PATCH 38/60] ok --- program/rust/src/rust_oracle.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 3e26ee761..8a96d52cf 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -62,14 +62,14 @@ pub fn init_mapping( let mut mut_data = accounts.get(1) .unwrap() - .try_borrow_data_mut() + .try_borrow_mut_data() .map_err(|_| ProgramError::InvalidArgument)?; sol_memset( *mut_data, 0, size_of::() ); let data2 = accounts.get(1) .unwrap() - .try_borrow_data_mut() + .try_borrow_mut_data() .map_err(|_| ProgramError::InvalidArgument)?; let mut mapping_account = load_mut::(*data2).map_err(|_| ProgramError::InvalidArgument)?; mapping_account.magic_ = PC_MAGIC_V; From 8f9ffdd7fdb1c4dbbcf03fcf3d8da04a4f2a1795 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Tue, 2 Aug 2022 12:00:49 -0700 Subject: [PATCH 39/60] ok --- program/rust/src/rust_oracle.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 8a96d52cf..57ccca792 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -67,7 +67,7 @@ pub fn init_mapping( sol_memset( *mut_data, 0, size_of::() ); - let data2 = accounts.get(1) + let mut data2 = accounts.get(1) .unwrap() .try_borrow_mut_data() .map_err(|_| ProgramError::InvalidArgument)?; From 9058353c611160cecf2f6228375ada5e73192b59 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Wed, 3 Aug 2022 06:19:06 -0700 Subject: [PATCH 40/60] ok --- program/c/src/oracle/oracle.h | 3 +- program/rust/src/processor.rs | 21 ++++++++----- program/rust/src/rust_oracle.rs | 52 +++++++++++++++++---------------- 3 files changed, 42 insertions(+), 34 deletions(-) diff --git a/program/c/src/oracle/oracle.h b/program/c/src/oracle/oracle.h index 54b98ac3f..a85e0632c 100644 --- a/program/c/src/oracle/oracle.h +++ b/program/c/src/oracle/oracle.h @@ -72,8 +72,9 @@ const uint64_t sysvar_clock[] = { }; // public key of symbol or publisher account -typedef struct pc_pub_key +typedef union pc_pub_key { + uint8_t k1_[PC_PUBKEY_SIZE]; uint64_t k8_[PC_PUBKEY_SIZE_64]; } pc_pub_key_t; diff --git a/program/rust/src/processor.rs b/program/rust/src/processor.rs index 6397674c3..81087a86d 100644 --- a/program/rust/src/processor.rs +++ b/program/rust/src/processor.rs @@ -1,7 +1,14 @@ +use ::std::mem::size_of; + +use borsh::BorshDeserialize; +use solana_program::pubkey::Pubkey; +use solana_program::sysvar::slot_history::AccountInfo; + use crate::c_entrypoint_wrapper; use crate::c_oracle_header::{ cmd_hdr, command_t_e_cmd_agg_price, + command_t_e_cmd_init_mapping, command_t_e_cmd_upd_account_version, command_t_e_cmd_upd_price, command_t_e_cmd_upd_price_no_fail_on_error, @@ -11,14 +18,8 @@ use crate::error::{ OracleError, OracleResult, }; -use crate::rust_oracle::{ - update_price, - update_version, -}; -use ::std::mem::size_of; -use borsh::BorshDeserialize; -use solana_program::pubkey::Pubkey; -use solana_program::sysvar::slot_history::AccountInfo; +use crate::rust_oracle::{init_mapping, update_price, update_version}; + ///dispatch to the right instruction in the oracle pub fn process_instruction( program_id: &Pubkey, @@ -49,6 +50,10 @@ pub fn process_instruction( command_t_e_cmd_upd_account_version => { update_version(program_id, &accounts, &instruction_data) } + command_t_e_cmd_init_mapping => { + init_mapping(program_id, &accounts, &instruction_data) + } _ => c_entrypoint_wrapper(input), } } + diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 57ccca792..22d0ec47f 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -37,6 +37,9 @@ pub fn update_version( } +/// initialize the first mapping account in a new linked-list of mapping accounts +/// accounts[0] funding account [signer writable] +/// accounts[1] new mapping account [signer writable] pub fn init_mapping( program_id: &Pubkey, accounts: &Vec, @@ -47,31 +50,19 @@ pub fn init_mapping( valid_signable_account(program_id, accounts.get(1).unwrap(), size_of::()), ProgramError::InvalidArgument)?; - let data = accounts.get(1) - .unwrap() - .try_borrow_data() - .map_err(|_| ProgramError::InvalidArgument)?; - let mapping_account = load::(*data).map_err(|_| ProgramError::InvalidArgument)?; - // Check that the account has not already been initialized + let mapping_account = load_account_as::(&accounts.get(1).unwrap()) + .map_err(|_| ProgramError::InvalidArgument)?; pyth_assert(mapping_account.magic_ == 0 && mapping_account.ver_ == 0, ProgramError::InvalidArgument)?; // Initialize by setting to zero again (just in case) and setting // the version number let hdr = load::(instruction_data).map_err(|_| ProgramError::InvalidArgument)?; + let mut data = accounts.get(1).unwrap().try_borrow_mut_data().map_err(|_| ProgramError::InvalidArgument)?; + sol_memset( *data, 0, size_of::() ); - let mut mut_data = accounts.get(1) - .unwrap() - .try_borrow_mut_data() - .map_err(|_| ProgramError::InvalidArgument)?; - sol_memset( *mut_data, 0, size_of::() ); - - - let mut data2 = accounts.get(1) - .unwrap() - .try_borrow_mut_data() + let mut mapping_account = load_account_as_mut::(&accounts.get(1).unwrap()) .map_err(|_| ProgramError::InvalidArgument)?; - let mut mapping_account = load_mut::(*data2).map_err(|_| ProgramError::InvalidArgument)?; mapping_account.magic_ = PC_MAGIC_V; mapping_account.ver_ = hdr.ver_; mapping_account.type_ = PC_ACCTYPE_MAPPING_V; @@ -89,11 +80,11 @@ pub fn pyth_assert(condition: bool, error_code: ProgramError) -> Result<(), Prog } } -pub fn valid_funding_account(account: &AccountInfo) -> bool { +fn valid_funding_account(account: &AccountInfo) -> bool { account.is_signer && account.is_writable } -pub fn valid_signable_account(program_id: &Pubkey, account: &AccountInfo, minimum_size: usize) -> bool { +fn valid_signable_account(program_id: &Pubkey, account: &AccountInfo, minimum_size: usize) -> bool { account.is_signer && account.is_writable && account.owner == program_id && @@ -101,24 +92,35 @@ pub fn valid_signable_account(program_id: &Pubkey, account: &AccountInfo, minimu Rent::default().is_exempt(account.lamports(), account.data_len()) } +/// Interpret the bytes in `data` as a value of type `T` fn load(data: &[u8]) -> Result<&T, PodCastError> { let size = size_of::(); if data.len() >= size { - Ok(from_bytes(cast_slice::(try_cast_slice( - &data[0..size], - )?))) + Ok(from_bytes(cast_slice::(try_cast_slice(&data[0..size])?))) } else { Err(PodCastError::SizeMismatch) } } +/// Interpret the bytes in `data` as a mutable value of type `T` fn load_mut(data: &mut[u8]) -> Result<&mut T, PodCastError> { let size = size_of::(); if data.len() >= size { - Ok(from_bytes_mut(cast_slice_mut::(try_cast_slice_mut( - &mut data[0..size], - )?))) + Ok(from_bytes_mut(cast_slice_mut::(try_cast_slice_mut(&mut data[0..size])?))) } else { Err(PodCastError::SizeMismatch) } +} + +/// Get the data stored in `account` as a value of type `T` +fn load_account_as(account: &AccountInfo) -> Result<&T, ProgramError> { + let data = account.unwrap().try_borrow_data().map_err(|_| ProgramError::InvalidArgument)?; + load::(*data).map_err(|_| ProgramError::InvalidArgument) +} + +/// Mutably borrow the data in `account` as a value of type `T`. +/// Any mutations to the returned value will be reflected in the account data. +fn load_account_as_mut(account: &AccountInfo) -> Result<&mut T, ProgramError> { + let mut data = account.unwrap().try_borrow_mut_data().map_err(|_| ProgramError::InvalidArgument)?; + load_mut::(*data).map_err(|_| ProgramError::InvalidArgument) } \ No newline at end of file From 0bd6e7963e4f0a9572e5c3fb34858c7ffdfd37d7 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Wed, 3 Aug 2022 06:22:28 -0700 Subject: [PATCH 41/60] delete instruction from c --- program/c/src/oracle/oracle.c | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/program/c/src/oracle/oracle.c b/program/c/src/oracle/oracle.c index e555d7d62..7dd6c31bf 100644 --- a/program/c/src/oracle/oracle.c +++ b/program/c/src/oracle/oracle.c @@ -59,33 +59,6 @@ static bool valid_writable_account( SolParameters *prm, is_rent_exempt( *ka->lamports, ka->data_len ); } -static uint64_t init_mapping( SolParameters *prm, SolAccountInfo *ka ) -{ - // Verify that the new account is signed and writable, with correct - // ownership and size - if ( prm->ka_num != 2 || - !valid_funding_account( &ka[0] ) || - !valid_signable_account( prm, &ka[1], sizeof( pc_map_table_t ) ) ) { - return ERROR_INVALID_ARGUMENT; - } - - // Check that the account has not already been initialized - pc_map_table_t *tptr = (pc_map_table_t*)ka[1].data; - if ( tptr->magic_ != 0 || tptr->ver_ != 0 ) { - return ERROR_INVALID_ARGUMENT; - } - - // Initialize by setting to zero again (just in case) and setting - // the version number - cmd_hdr_t *hdr = (cmd_hdr_t*)prm->data; - sol_memset( tptr, 0, sizeof( pc_map_table_t ) ); - tptr->magic_ = PC_MAGIC; - tptr->ver_ = hdr->ver_; - tptr->type_ = PC_ACCTYPE_MAPPING; - tptr->size_ = sizeof( pc_map_table_t ) - sizeof( tptr->prod_ ); - return SUCCESS; -} - static uint64_t add_mapping( SolParameters *prm, SolAccountInfo *ka ) { // Account (1) is the tail or last mapping account in the chain @@ -538,7 +511,7 @@ static uint64_t dispatch( SolParameters *prm, SolAccountInfo *ka ) case e_cmd_upd_price: case e_cmd_agg_price: return upd_price( prm, ka ); case e_cmd_upd_price_no_fail_on_error: return upd_price_no_fail_on_error( prm, ka ); - case e_cmd_init_mapping: return init_mapping( prm, ka ); + case e_cmd_init_mapping: return ERROR_INVALID_ARGUMENT; case e_cmd_add_mapping: return add_mapping( prm, ka ); case e_cmd_add_product: return add_product( prm, ka ); case e_cmd_upd_product: return upd_product( prm, ka ); From 20a140b2c66ddd17fe7301c3596abc4d4f841053 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Wed, 3 Aug 2022 06:38:13 -0700 Subject: [PATCH 42/60] format --- program/c/src/oracle/oracle.c | 30 ++++++++- program/rust/src/c_oracle_header.rs | 5 +- program/rust/src/processor.rs | 11 +-- program/rust/src/rust_oracle.rs | 100 ++++++++++++++++++++-------- 4 files changed, 110 insertions(+), 36 deletions(-) diff --git a/program/c/src/oracle/oracle.c b/program/c/src/oracle/oracle.c index 7dd6c31bf..fe0f837ae 100644 --- a/program/c/src/oracle/oracle.c +++ b/program/c/src/oracle/oracle.c @@ -59,6 +59,33 @@ static bool valid_writable_account( SolParameters *prm, is_rent_exempt( *ka->lamports, ka->data_len ); } +static uint64_t init_mapping( SolParameters *prm, SolAccountInfo *ka ) +{ + // Verify that the new account is signed and writable, with correct + // ownership and size + if ( prm->ka_num != 2 || + !valid_funding_account( &ka[0] ) || + !valid_signable_account( prm, &ka[1], sizeof( pc_map_table_t ) ) ) { + return ERROR_INVALID_ARGUMENT; + } + + // Check that the account has not already been initialized + pc_map_table_t *tptr = (pc_map_table_t*)ka[1].data; + if ( tptr->magic_ != 0 || tptr->ver_ != 0 ) { + return ERROR_INVALID_ARGUMENT; + } + + // Initialize by setting to zero again (just in case) and setting + // the version number + cmd_hdr_t *hdr = (cmd_hdr_t*)prm->data; + sol_memset( tptr, 0, sizeof( pc_map_table_t ) ); + tptr->magic_ = PC_MAGIC; + tptr->ver_ = hdr->ver_; + tptr->type_ = PC_ACCTYPE_MAPPING; + tptr->size_ = sizeof( pc_map_table_t ) - sizeof( tptr->prod_ ); + return SUCCESS; +} + static uint64_t add_mapping( SolParameters *prm, SolAccountInfo *ka ) { // Account (1) is the tail or last mapping account in the chain @@ -511,7 +538,8 @@ static uint64_t dispatch( SolParameters *prm, SolAccountInfo *ka ) case e_cmd_upd_price: case e_cmd_agg_price: return upd_price( prm, ka ); case e_cmd_upd_price_no_fail_on_error: return upd_price_no_fail_on_error( prm, ka ); - case e_cmd_init_mapping: return ERROR_INVALID_ARGUMENT; + // init_mapping is overridden in Rust, but still implemented here to make the C unit tests pass. + case e_cmd_init_mapping: return init_mapping( prm, ka ); case e_cmd_add_mapping: return add_mapping( prm, ka ); case e_cmd_add_product: return add_product( prm, ka ); case e_cmd_upd_product: return upd_product( prm, ka ); diff --git a/program/rust/src/c_oracle_header.rs b/program/rust/src/c_oracle_header.rs index 215060fff..bd4711219 100644 --- a/program/rust/src/c_oracle_header.rs +++ b/program/rust/src/c_oracle_header.rs @@ -9,7 +9,10 @@ use borsh::{ BorshDeserialize, BorshSerialize, }; -use bytemuck::{Pod, Zeroable}; +use bytemuck::{ + Pod, + Zeroable, +}; //bindings.rs is generated by build.rs to include //things defined in bindings.h diff --git a/program/rust/src/processor.rs b/program/rust/src/processor.rs index 81087a86d..343d78262 100644 --- a/program/rust/src/processor.rs +++ b/program/rust/src/processor.rs @@ -18,7 +18,11 @@ use crate::error::{ OracleError, OracleResult, }; -use crate::rust_oracle::{init_mapping, update_price, update_version}; +use crate::rust_oracle::{ + init_mapping, + update_price, + update_version, +}; ///dispatch to the right instruction in the oracle pub fn process_instruction( @@ -50,10 +54,7 @@ pub fn process_instruction( command_t_e_cmd_upd_account_version => { update_version(program_id, &accounts, &instruction_data) } - command_t_e_cmd_init_mapping => { - init_mapping(program_id, &accounts, &instruction_data) - } + command_t_e_cmd_init_mapping => init_mapping(program_id, &accounts, &instruction_data), _ => c_entrypoint_wrapper(input), } } - diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 22d0ec47f..ed3862ec8 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -1,6 +1,18 @@ -use std::mem::{size_of, size_of_val}; - -use bytemuck::{from_bytes, try_cast_slice, cast_slice, from_bytes_mut, try_cast_slice_mut, cast_slice_mut, Pod, PodCastError}; +use std::mem::{ + size_of, + size_of_val, +}; + +use bytemuck::{ + cast_slice, + cast_slice_mut, + from_bytes, + from_bytes_mut, + try_cast_slice, + try_cast_slice_mut, + Pod, + PodCastError, +}; use solana_program::entrypoint::SUCCESS; use solana_program::program_error::ProgramError; use solana_program::program_memory::sol_memset; @@ -8,7 +20,12 @@ use solana_program::pubkey::Pubkey; use solana_program::rent::Rent; use solana_program::sysvar::slot_history::AccountInfo; -use crate::c_oracle_header::{cmd_hdr_t, PC_ACCTYPE_MAPPING_V, PC_MAGIC_V, pc_map_table_t}; +use crate::c_oracle_header::{ + cmd_hdr_t, + pc_map_table_t, + PC_ACCTYPE_MAPPING_V, + PC_MAGIC_V, +}; use crate::error::OracleResult; use super::c_entrypoint_wrapper; @@ -45,39 +62,54 @@ pub fn init_mapping( accounts: &Vec, instruction_data: &[u8], ) -> OracleResult { - pyth_assert(accounts.len() == 2 && - valid_funding_account(accounts.get(0).unwrap()) && - valid_signable_account(program_id, accounts.get(1).unwrap(), size_of::()), - ProgramError::InvalidArgument)?; + pyth_assert( + accounts.len() == 2 + && valid_funding_account(accounts.get(0).unwrap()) + && valid_signable_account( + program_id, + accounts.get(1).unwrap(), + size_of::(), + ), + ProgramError::InvalidArgument, + )?; // Check that the account has not already been initialized let mapping_account = load_account_as::(&accounts.get(1).unwrap()) - .map_err(|_| ProgramError::InvalidArgument)?; - pyth_assert(mapping_account.magic_ == 0 && mapping_account.ver_ == 0, ProgramError::InvalidArgument)?; + .map_err(|_| ProgramError::InvalidArgument)?; + pyth_assert( + mapping_account.magic_ == 0 && mapping_account.ver_ == 0, + ProgramError::InvalidArgument, + )?; // Initialize by setting to zero again (just in case) and setting // the version number let hdr = load::(instruction_data).map_err(|_| ProgramError::InvalidArgument)?; - let mut data = accounts.get(1).unwrap().try_borrow_mut_data().map_err(|_| ProgramError::InvalidArgument)?; - sol_memset( *data, 0, size_of::() ); + let mut data = accounts + .get(1) + .unwrap() + .try_borrow_mut_data() + .map_err(|_| ProgramError::InvalidArgument)?; + sol_memset(*data, 0, size_of::()); let mut mapping_account = load_account_as_mut::(&accounts.get(1).unwrap()) - .map_err(|_| ProgramError::InvalidArgument)?; + .map_err(|_| ProgramError::InvalidArgument)?; mapping_account.magic_ = PC_MAGIC_V; - mapping_account.ver_ = hdr.ver_; - mapping_account.type_ = PC_ACCTYPE_MAPPING_V; - mapping_account.size_ = (size_of::() - size_of_val( &mapping_account.prod_ )) as u32; + mapping_account.ver_ = hdr.ver_; + mapping_account.type_ = PC_ACCTYPE_MAPPING_V; + mapping_account.size_ = + (size_of::() - size_of_val(&mapping_account.prod_)) as u32; Result::Ok(SUCCESS) } -// FIXME: this is an extremely scary way to check errors because if you forget the ? after calling it, it doesn't do anything. +// FIXME: this is an extremely scary way to check errors because if you forget the ? after calling +// it, it doesn't do anything. pub fn pyth_assert(condition: bool, error_code: ProgramError) -> Result<(), ProgramError> { return if !condition { Result::Err(error_code) } else { Result::Ok(()) - } + }; } fn valid_funding_account(account: &AccountInfo) -> bool { @@ -85,28 +117,32 @@ fn valid_funding_account(account: &AccountInfo) -> bool { } fn valid_signable_account(program_id: &Pubkey, account: &AccountInfo, minimum_size: usize) -> bool { - account.is_signer && - account.is_writable && - account.owner == program_id && - account.data_len() >= minimum_size && - Rent::default().is_exempt(account.lamports(), account.data_len()) + account.is_signer + && account.is_writable + && account.owner == program_id + && account.data_len() >= minimum_size + && Rent::default().is_exempt(account.lamports(), account.data_len()) } /// Interpret the bytes in `data` as a value of type `T` fn load(data: &[u8]) -> Result<&T, PodCastError> { let size = size_of::(); if data.len() >= size { - Ok(from_bytes(cast_slice::(try_cast_slice(&data[0..size])?))) + Ok(from_bytes(cast_slice::(try_cast_slice( + &data[0..size], + )?))) } else { Err(PodCastError::SizeMismatch) } } /// Interpret the bytes in `data` as a mutable value of type `T` -fn load_mut(data: &mut[u8]) -> Result<&mut T, PodCastError> { +fn load_mut(data: &mut [u8]) -> Result<&mut T, PodCastError> { let size = size_of::(); if data.len() >= size { - Ok(from_bytes_mut(cast_slice_mut::(try_cast_slice_mut(&mut data[0..size])?))) + Ok(from_bytes_mut(cast_slice_mut::( + try_cast_slice_mut(&mut data[0..size])?, + ))) } else { Err(PodCastError::SizeMismatch) } @@ -114,13 +150,19 @@ fn load_mut(data: &mut[u8]) -> Result<&mut T, PodCastError> { /// Get the data stored in `account` as a value of type `T` fn load_account_as(account: &AccountInfo) -> Result<&T, ProgramError> { - let data = account.unwrap().try_borrow_data().map_err(|_| ProgramError::InvalidArgument)?; + let data = account + .unwrap() + .try_borrow_data() + .map_err(|_| ProgramError::InvalidArgument)?; load::(*data).map_err(|_| ProgramError::InvalidArgument) } /// Mutably borrow the data in `account` as a value of type `T`. /// Any mutations to the returned value will be reflected in the account data. fn load_account_as_mut(account: &AccountInfo) -> Result<&mut T, ProgramError> { - let mut data = account.unwrap().try_borrow_mut_data().map_err(|_| ProgramError::InvalidArgument)?; + let mut data = account + .unwrap() + .try_borrow_mut_data() + .map_err(|_| ProgramError::InvalidArgument)?; load_mut::(*data).map_err(|_| ProgramError::InvalidArgument) -} \ No newline at end of file +} From e3b5eb6cd91ba71d25991b865fc345679ea827e5 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Wed, 3 Aug 2022 06:50:20 -0700 Subject: [PATCH 43/60] add lifetime --- program/rust/src/rust_oracle.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index ed3862ec8..cf3cee405 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -149,7 +149,7 @@ fn load_mut(data: &mut [u8]) -> Result<&mut T, PodCastError> { } /// Get the data stored in `account` as a value of type `T` -fn load_account_as(account: &AccountInfo) -> Result<&T, ProgramError> { +fn load_account_as<'a, T: Pod>(account: &'a AccountInfo) -> Result<&'a T, ProgramError> { let data = account .unwrap() .try_borrow_data() @@ -159,7 +159,7 @@ fn load_account_as(account: &AccountInfo) -> Result<&T, ProgramError> { /// Mutably borrow the data in `account` as a value of type `T`. /// Any mutations to the returned value will be reflected in the account data. -fn load_account_as_mut(account: &AccountInfo) -> Result<&mut T, ProgramError> { +fn load_account_as_mut<'a, T: Pod>(account: &'a AccountInfo) -> Result<&'a mut T, ProgramError> { let mut data = account .unwrap() .try_borrow_mut_data() From 91e6b3e27b68cd482b1be49a60f846fa711fdab5 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Wed, 3 Aug 2022 06:51:31 -0700 Subject: [PATCH 44/60] ok --- program/rust/src/rust_oracle.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index cf3cee405..355b38d2d 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -151,7 +151,6 @@ fn load_mut(data: &mut [u8]) -> Result<&mut T, PodCastError> { /// Get the data stored in `account` as a value of type `T` fn load_account_as<'a, T: Pod>(account: &'a AccountInfo) -> Result<&'a T, ProgramError> { let data = account - .unwrap() .try_borrow_data() .map_err(|_| ProgramError::InvalidArgument)?; load::(*data).map_err(|_| ProgramError::InvalidArgument) @@ -161,7 +160,6 @@ fn load_account_as<'a, T: Pod>(account: &'a AccountInfo) -> Result<&'a T, Progra /// Any mutations to the returned value will be reflected in the account data. fn load_account_as_mut<'a, T: Pod>(account: &'a AccountInfo) -> Result<&'a mut T, ProgramError> { let mut data = account - .unwrap() .try_borrow_mut_data() .map_err(|_| ProgramError::InvalidArgument)?; load_mut::(*data).map_err(|_| ProgramError::InvalidArgument) From c55f91754359e8bb602c78a0291e11c7099b1c6c Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Wed, 3 Aug 2022 06:57:23 -0700 Subject: [PATCH 45/60] does this work --- program/rust/src/rust_oracle.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 355b38d2d..015dcc1c0 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -149,7 +149,7 @@ fn load_mut(data: &mut [u8]) -> Result<&mut T, PodCastError> { } /// Get the data stored in `account` as a value of type `T` -fn load_account_as<'a, T: Pod>(account: &'a AccountInfo) -> Result<&'a T, ProgramError> { +fn load_account_as<'a, T: Pod>(account: &AccountInfo<'a>) -> Result<&'a T, ProgramError> { let data = account .try_borrow_data() .map_err(|_| ProgramError::InvalidArgument)?; @@ -158,7 +158,7 @@ fn load_account_as<'a, T: Pod>(account: &'a AccountInfo) -> Result<&'a T, Progra /// Mutably borrow the data in `account` as a value of type `T`. /// Any mutations to the returned value will be reflected in the account data. -fn load_account_as_mut<'a, T: Pod>(account: &'a AccountInfo) -> Result<&'a mut T, ProgramError> { +fn load_account_as_mut<'a, T: Pod>(account: &AccountInfo<'a>) -> Result<&'a mut T, ProgramError> { let mut data = account .try_borrow_mut_data() .map_err(|_| ProgramError::InvalidArgument)?; From 38c180ae5f834758017de9766b18a981fa84f90d Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Wed, 3 Aug 2022 09:07:10 -0700 Subject: [PATCH 46/60] reformat --- program/rust/src/rust_oracle.rs | 52 +++++++++++++++------------------ 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 015dcc1c0..a9339ea40 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -1,3 +1,7 @@ +use std::cell::{ + Ref, + RefMut, +}; use std::mem::{ size_of, size_of_val, @@ -83,7 +87,7 @@ pub fn init_mapping( // Initialize by setting to zero again (just in case) and setting // the version number - let hdr = load::(instruction_data).map_err(|_| ProgramError::InvalidArgument)?; + let hdr = load::(instruction_data); let mut data = accounts .get(1) .unwrap() @@ -125,42 +129,32 @@ fn valid_signable_account(program_id: &Pubkey, account: &AccountInfo, minimum_si } /// Interpret the bytes in `data` as a value of type `T` -fn load(data: &[u8]) -> Result<&T, PodCastError> { - let size = size_of::(); - if data.len() >= size { - Ok(from_bytes(cast_slice::(try_cast_slice( - &data[0..size], - )?))) - } else { - Err(PodCastError::SizeMismatch) - } +fn load(data: &[u8]) -> &T { + from_bytes(&data[0..size_of::()]) } /// Interpret the bytes in `data` as a mutable value of type `T` -fn load_mut(data: &mut [u8]) -> Result<&mut T, PodCastError> { - let size = size_of::(); - if data.len() >= size { - Ok(from_bytes_mut(cast_slice_mut::( - try_cast_slice_mut(&mut data[0..size])?, - ))) - } else { - Err(PodCastError::SizeMismatch) - } +fn load_mut(data: &mut [u8]) -> &mut T { + from_bytes_mut(&mut data[0..size_of::()]) } /// Get the data stored in `account` as a value of type `T` -fn load_account_as<'a, T: Pod>(account: &AccountInfo<'a>) -> Result<&'a T, ProgramError> { - let data = account - .try_borrow_data() - .map_err(|_| ProgramError::InvalidArgument)?; - load::(*data).map_err(|_| ProgramError::InvalidArgument) +fn load_account_as<'a, T: Pod>(account: &'a AccountInfo) -> Result, ProgramError> { + let data = account.try_borrow_data()?; + + Ok(Ref::map(data, |data| { + bytemuck::from_bytes(&data[0..size_of::()]) + })) } /// Mutably borrow the data in `account` as a value of type `T`. /// Any mutations to the returned value will be reflected in the account data. -fn load_account_as_mut<'a, T: Pod>(account: &AccountInfo<'a>) -> Result<&'a mut T, ProgramError> { - let mut data = account - .try_borrow_mut_data() - .map_err(|_| ProgramError::InvalidArgument)?; - load_mut::(*data).map_err(|_| ProgramError::InvalidArgument) +fn load_account_as_mut<'a, T: Pod>( + account: &'a AccountInfo, +) -> Result, ProgramError> { + let data = account.try_borrow_mut_data()?; + + Ok(RefMut::map(data, |data| { + bytemuck::from_bytes_mut(&mut data[0..size_of::()]) + })) } From f50779ede6d0a82bc1a45680022c1f59d44c0f6c Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Wed, 3 Aug 2022 09:08:53 -0700 Subject: [PATCH 47/60] test clippy --- program/rust/src/rust_oracle.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index a9339ea40..ca5df93c7 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -75,7 +75,7 @@ pub fn init_mapping( size_of::(), ), ProgramError::InvalidArgument, - )?; + ); // Check that the account has not already been initialized let mapping_account = load_account_as::(&accounts.get(1).unwrap()) From e7173d804115196de15edd582d1c0f5f00f95391 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Wed, 3 Aug 2022 09:11:18 -0700 Subject: [PATCH 48/60] hm --- program/rust/src/rust_oracle.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index ca5df93c7..a9339ea40 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -75,7 +75,7 @@ pub fn init_mapping( size_of::(), ), ProgramError::InvalidArgument, - ); + )?; // Check that the account has not already been initialized let mapping_account = load_account_as::(&accounts.get(1).unwrap()) From ee26a5f531e9797c76035cbdb81c913a28e6d04d Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Wed, 3 Aug 2022 11:23:58 -0700 Subject: [PATCH 49/60] cleanup --- program/rust/src/c_oracle_header.rs | 8 +++ program/rust/src/rust_oracle.rs | 78 +++++++++++++---------------- 2 files changed, 44 insertions(+), 42 deletions(-) diff --git a/program/rust/src/c_oracle_header.rs b/program/rust/src/c_oracle_header.rs index dbb5336c4..045642115 100644 --- a/program/rust/src/c_oracle_header.rs +++ b/program/rust/src/c_oracle_header.rs @@ -16,6 +16,14 @@ use bytemuck::{ //things defined in bindings.h include!("../bindings.rs"); +#[cfg(target_endian = "little")] +unsafe impl Zeroable for pc_acc { +} + +#[cfg(target_endian = "little")] +unsafe impl Pod for pc_acc { +} + #[cfg(target_endian = "little")] unsafe impl Zeroable for pc_map_table { } diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index affbdff4d..f9c136687 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -22,6 +22,7 @@ use solana_program::sysvar::slot_history::AccountInfo; use crate::c_oracle_header::{ cmd_hdr_t, + pc_acc, pc_map_table_t, PC_ACCTYPE_MAPPING_V, PC_MAGIC_V, @@ -62,42 +63,23 @@ pub fn init_mapping( accounts: &[AccountInfo], instruction_data: &[u8], ) -> OracleResult { - pyth_assert( - accounts.len() == 2 - && valid_funding_account(accounts.get(0).unwrap()) - && valid_signable_account( - program_id, - accounts.get(1).unwrap(), - size_of::(), - ), - ProgramError::InvalidArgument, - )?; - - // Check that the account has not already been initialized - { - let mapping_account = load_account_as::(accounts.get(1).unwrap()) - .map_err(|_| ProgramError::InvalidArgument)?; - pyth_assert( - mapping_account.magic_ == 0 && mapping_account.ver_ == 0, - ProgramError::InvalidArgument, - )?; - } + let [_funding_account, fresh_mapping_account] = match accounts { + [x, y] + if valid_funding_account(x) + && valid_signable_account(program_id, y, size_of::()) + && valid_fresh_account(y) => + { + Ok([x, y]) + } + _ => Err(ProgramError::InvalidArgument), + }?; + + // Initialize by setting to zero again (just in case) and populating the account header + clear_account(fresh_mapping_account)?; - // Initialize by setting to zero again (just in case) and setting - // the version number let hdr = load::(instruction_data); { - let mut data = accounts - .get(1) - .unwrap() - .try_borrow_mut_data() - .map_err(|_| ProgramError::InvalidArgument)?; - sol_memset(data.borrow_mut(), 0, size_of::()); - } - - { - let mut mapping_account = load_account_as_mut::(accounts.get(1).unwrap()) - .map_err(|_| ProgramError::InvalidArgument)?; + let mut mapping_account = load_account_as_mut::(fresh_mapping_account)?; mapping_account.magic_ = PC_MAGIC_V; mapping_account.ver_ = hdr.ver_; mapping_account.type_ = PC_ACCTYPE_MAPPING_V; @@ -105,15 +87,7 @@ pub fn init_mapping( (size_of::() - size_of_val(&mapping_account.prod_)) as u32; } - Result::Ok(SUCCESS) -} - -pub fn pyth_assert(condition: bool, error_code: ProgramError) -> Result<(), ProgramError> { - if !condition { - Result::Err(error_code) - } else { - Result::Ok(()) - } + Ok(SUCCESS) } fn valid_funding_account(account: &AccountInfo) -> bool { @@ -128,6 +102,26 @@ fn valid_signable_account(program_id: &Pubkey, account: &AccountInfo, minimum_si && Rent::default().is_exempt(account.lamports(), account.data_len()) } +/// Returns `true` if the `account` is fresh, i.e., its data can be overwritten. +/// Use this check to prevent accidentally overwriting accounts whose data is already populated. +fn valid_fresh_account(account: &AccountInfo) -> bool { + let pyth_acc = load_account_as::(account); + match pyth_acc { + Ok(pyth_acc) => pyth_acc.magic_ == 0 && pyth_acc.ver_ == 0, + Err(_) => false, + } +} + +/// Sets the data of account to all-zero +fn clear_account(account: &AccountInfo) -> Result<(), ProgramError> { + let mut data = account + .try_borrow_mut_data() + .map_err(|_| ProgramError::InvalidArgument)?; + let length = data.len(); + sol_memset(data.borrow_mut(), 0, length); + Ok(()) +} + /// Interpret the bytes in `data` as a value of type `T` fn load(data: &[u8]) -> &T { from_bytes(&data[0..size_of::()]) From 47e1d5b657c747f6ec98837ed43470095d2ae1af Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Wed, 3 Aug 2022 14:10:00 -0700 Subject: [PATCH 50/60] fix defines --- program/rust/src/bindings.h | 9 --------- program/rust/src/rust_oracle.rs | 8 ++++---- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/program/rust/src/bindings.h b/program/rust/src/bindings.h index abc7103a0..e2a2be48b 100644 --- a/program/rust/src/bindings.h +++ b/program/rust/src/bindings.h @@ -13,12 +13,3 @@ typedef unsigned long int uint64_t; #include "../../c/src/oracle/oracle.h" #include "price_t_offsets.h" - -// Store #define constants as values so they are accessible from rust. -const uint32_t PC_MAGIC_V = PC_MAGIC; -const uint32_t PC_VERSION_V = PC_VERSION; - -const uint32_t PC_ACCTYPE_MAPPING_V = PC_ACCTYPE_MAPPING; -const uint32_t PC_ACCTYPE_PRODUCT_V = PC_ACCTYPE_PRODUCT; -const uint32_t PC_ACCTYPE_PRICE_V = PC_ACCTYPE_PRICE; -const uint32_t PC_ACCTYPE_TEST_V = PC_ACCTYPE_TEST; diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index f9c136687..e3b30c6fa 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -24,8 +24,8 @@ use crate::c_oracle_header::{ cmd_hdr_t, pc_acc, pc_map_table_t, - PC_ACCTYPE_MAPPING_V, - PC_MAGIC_V, + PC_ACCTYPE_MAPPING, + PC_MAGIC, }; use crate::error::OracleResult; @@ -80,9 +80,9 @@ pub fn init_mapping( let hdr = load::(instruction_data); { let mut mapping_account = load_account_as_mut::(fresh_mapping_account)?; - mapping_account.magic_ = PC_MAGIC_V; + mapping_account.magic_ = PC_MAGIC; mapping_account.ver_ = hdr.ver_; - mapping_account.type_ = PC_ACCTYPE_MAPPING_V; + mapping_account.type_ = PC_ACCTYPE_MAPPING; mapping_account.size_ = (size_of::() - size_of_val(&mapping_account.prod_)) as u32; } From cc869aac2ed04b930f6f68cf94a462ac1cd91c28 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Wed, 3 Aug 2022 21:41:59 +0000 Subject: [PATCH 51/60] Fix version of bytemuck and clean import --- program/rust/Cargo.toml | 2 +- program/rust/src/processor.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/program/rust/Cargo.toml b/program/rust/Cargo.toml index 25e8e163d..3e5a584b0 100644 --- a/program/rust/Cargo.toml +++ b/program/rust/Cargo.toml @@ -11,7 +11,7 @@ bindgen = "0.60.1" [dependencies] solana-program = "=1.10.29" borsh = "0.9" -bytemuck = "1.7.2" +bytemuck = "1.11.0" thiserror = "1.0" [lib] diff --git a/program/rust/src/processor.rs b/program/rust/src/processor.rs index bd942a937..b753b208e 100644 --- a/program/rust/src/processor.rs +++ b/program/rust/src/processor.rs @@ -1,4 +1,4 @@ -use ::std::mem::size_of; +use std::mem::size_of; use borsh::BorshDeserialize; use solana_program::pubkey::Pubkey; From 63742152f59cb7c7afdf6744760bf3e8e1574f62 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Wed, 3 Aug 2022 22:51:34 +0000 Subject: [PATCH 52/60] Rust oracle --- program/rust/build.rs | 2 + program/rust/src/processor.rs | 3 ++ program/rust/src/rust_oracle.rs | 65 +++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/program/rust/build.rs b/program/rust/build.rs index b8aee2acb..3c4e3cb8a 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -5,6 +5,7 @@ fn main() { println!("cargo:rustc-link-search=./program/c/target"); let borsh_derives = ["BorshSerialize".to_string(), "BorshDeserialize".to_string()]; + let pod_derive = ["Pod".to_string(), "Zeroable".to_string()]; //make a parser and to it type, traits pairs let mut parser = build_utils::DeriveAdderParserCallback::new(); @@ -13,6 +14,7 @@ fn main() { parser.register_traits("pc_price_info", borsh_derives.to_vec()); parser.register_traits("cmd_upd_price", borsh_derives.to_vec()); parser.register_traits("pc_ema", borsh_derives.to_vec()); + parser.register_traits("cmd_add_price", pod_derive.to_vec()); //generate and write bindings let bindings = Builder::default() diff --git a/program/rust/src/processor.rs b/program/rust/src/processor.rs index b753b208e..70dad6255 100644 --- a/program/rust/src/processor.rs +++ b/program/rust/src/processor.rs @@ -7,6 +7,7 @@ use solana_program::sysvar::slot_history::AccountInfo; use crate::c_entrypoint_wrapper; use crate::c_oracle_header::{ cmd_hdr, + command_t_e_cmd_add_price, command_t_e_cmd_agg_price, command_t_e_cmd_init_mapping, command_t_e_cmd_upd_account_version, @@ -19,6 +20,7 @@ use crate::error::{ OracleResult, }; use crate::rust_oracle::{ + add_price, init_mapping, update_price, update_version, @@ -52,6 +54,7 @@ pub fn process_instruction( command_t_e_cmd_upd_account_version => { update_version(program_id, accounts, instruction_data) } + command_t_e_cmd_add_price => add_price(program_id, accounts, instruction_data), command_t_e_cmd_init_mapping => init_mapping(program_id, accounts, instruction_data), _ => c_entrypoint_wrapper(input), } diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index e3b30c6fa..16fd60b64 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -21,11 +21,19 @@ use solana_program::rent::Rent; use solana_program::sysvar::slot_history::AccountInfo; use crate::c_oracle_header::{ + cmd_add_price_t, cmd_hdr_t, pc_acc, pc_map_table_t, + pc_price_t, + pc_prod_t, PC_ACCTYPE_MAPPING, + PC_ACCTYPE_PRICE, + PC_ACCTYPE_PRODUCT, PC_MAGIC, + PC_MAX_NUM_DECIMALS, + PC_PROD_ACC_SIZE, + PC_PTYPE_UNKNOWN, }; use crate::error::OracleResult; @@ -90,6 +98,63 @@ pub fn init_mapping( Ok(SUCCESS) } +/// add a price account to a product account +/// accounts[0] funding account [signer writable] +/// accounts[1] product account to add the price account to [signer writable] +/// accounts[2] newly created price account [signer writable] +pub fn add_price( + program_id: &Pubkey, + accounts: &[AccountInfo], + instruction_data: &[u8], +) -> OracleResult { + if instruction_data.len() < size_of::() { + return Err(ProgramError::InvalidArgument); + } + let cmd_args = load::(instruction_data); + + if cmd_args.expo_ > PC_MAX_NUM_DECIMALS as i32 + || cmd_args.expo_ < -(PC_MAX_NUM_DECIMALS as i32) + || cmd_args.ptype_ == PC_PTYPE_UNKNOWN + { + return Err(ProgramError::InvalidArgument); + } + + let [_funding_account, product_account, price_account] = match accounts { + [x, y, z] + if valid_funding_account(x) + && valid_signable_account(program_id, y, PC_PROD_ACC_SIZE as usize) + && valid_signable_account(program_id, z, size_of::()) => + { + Ok([x, y, z]) + } + _ => Err(ProgramError::InvalidArgument), + }?; + + let mut product_data = load_account_as_mut::(product_account)?; + let mut price_data = load_account_as_mut::(price_account)?; + + if product_data.magic_ != PC_MAGIC + || product_data.ver_ != cmd_args.ver_ + || product_data.type_ != PC_ACCTYPE_PRODUCT + || price_data.magic_ != 0 + { + return Err(ProgramError::InvalidArgument); + } + + clear_account(price_account)?; + price_data.magic_ = PC_MAGIC; + price_data.ver_ = cmd_args.ver_; + price_data.type_ = PC_ACCTYPE_PRICE; + price_data.size_ = (size_of::() - size_of_val(&price_data.comp_)) as u32; + price_data.expo_ = cmd_args.expo_; + price_data.ptype_ = cmd_args.ptype_; + price_data.prod_.k1_ = product_account.key.to_bytes(); + price_data.next_ = product_data.px_acc_; + product_data.px_acc_.k1_ = price_account.key.to_bytes(); + + Ok(SUCCESS) +} + fn valid_funding_account(account: &AccountInfo) -> bool { account.is_signer && account.is_writable } From 27466d39437d71ec33da963f43b12b082b8ac6dd Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Wed, 3 Aug 2022 23:46:58 +0000 Subject: [PATCH 53/60] Fix double borrow --- program/rust/src/rust_oracle.rs | 48 ++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 16fd60b64..68b2c3f27 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -14,6 +14,7 @@ use bytemuck::{ Pod, }; use solana_program::entrypoint::SUCCESS; +use solana_program::msg; use solana_program::program_error::ProgramError; use solana_program::program_memory::sol_memset; use solana_program::pubkey::Pubkey; @@ -112,6 +113,8 @@ pub fn add_price( } let cmd_args = load::(instruction_data); + msg!("1"); + if cmd_args.expo_ > PC_MAX_NUM_DECIMALS as i32 || cmd_args.expo_ < -(PC_MAX_NUM_DECIMALS as i32) || cmd_args.ptype_ == PC_PTYPE_UNKNOWN @@ -119,6 +122,9 @@ pub fn add_price( return Err(ProgramError::InvalidArgument); } + + msg!("2"); + let [_funding_account, product_account, price_account] = match accounts { [x, y, z] if valid_funding_account(x) @@ -130,28 +136,38 @@ pub fn add_price( _ => Err(ProgramError::InvalidArgument), }?; - let mut product_data = load_account_as_mut::(product_account)?; - let mut price_data = load_account_as_mut::(price_account)?; + msg!("3"); - if product_data.magic_ != PC_MAGIC - || product_data.ver_ != cmd_args.ver_ - || product_data.type_ != PC_ACCTYPE_PRODUCT - || price_data.magic_ != 0 + let mut product_data = load_account_as_mut::(product_account)?; { - return Err(ProgramError::InvalidArgument); + let price_data = load_account_as::(price_account)?; + + if product_data.magic_ != PC_MAGIC + || product_data.ver_ != cmd_args.ver_ + || product_data.type_ != PC_ACCTYPE_PRODUCT + || price_data.magic_ != 0 + { + return Err(ProgramError::InvalidArgument); + } } + msg!("4"); + clear_account(price_account)?; - price_data.magic_ = PC_MAGIC; - price_data.ver_ = cmd_args.ver_; - price_data.type_ = PC_ACCTYPE_PRICE; - price_data.size_ = (size_of::() - size_of_val(&price_data.comp_)) as u32; - price_data.expo_ = cmd_args.expo_; - price_data.ptype_ = cmd_args.ptype_; - price_data.prod_.k1_ = product_account.key.to_bytes(); - price_data.next_ = product_data.px_acc_; - product_data.px_acc_.k1_ = price_account.key.to_bytes(); + msg!("5"); + { + let mut price_data = load_account_as_mut::(price_account)?; + price_data.magic_ = PC_MAGIC; + price_data.ver_ = cmd_args.ver_; + price_data.type_ = PC_ACCTYPE_PRICE; + price_data.size_ = (size_of::() - size_of_val(&price_data.comp_)) as u32; + price_data.expo_ = cmd_args.expo_; + price_data.ptype_ = cmd_args.ptype_; + price_data.prod_.k1_ = product_account.key.to_bytes(); + price_data.next_ = product_data.px_acc_; + product_data.px_acc_.k1_ = price_account.key.to_bytes(); + } Ok(SUCCESS) } From c8f6b236bbca61e91b0465753f00c7024689d684 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Fri, 5 Aug 2022 03:16:45 +0000 Subject: [PATCH 54/60] Finalize merge --- program/rust/src/rust_oracle.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index ab83b4b4a..d73a95b29 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -86,14 +86,11 @@ pub fn init_mapping( clear_account(fresh_mapping_account)?; let hdr = load::(instruction_data)?; - { - let mut mapping_account = load_account_as_mut::(fresh_mapping_account)?; - mapping_account.magic_ = PC_MAGIC; - mapping_account.ver_ = hdr.ver_; - mapping_account.type_ = PC_ACCTYPE_MAPPING; - mapping_account.size_ = - (size_of::() - size_of_val(&mapping_account.prod_)) as u32; - } + let mut mapping_data = load_account_as_mut::(fresh_mapping_account)?; + mapping_data.magic_ = PC_MAGIC; + mapping_data.ver_ = hdr.ver_; + mapping_data.type_ = PC_ACCTYPE_MAPPING; + mapping_data.size_ = (size_of::() - size_of_val(&mapping_data.prod_)) as u32; Ok(SUCCESS) } From ed6c7d892678882d04996a76fe976d1b20395180 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Fri, 5 Aug 2022 15:52:02 +0000 Subject: [PATCH 55/60] Refactor derivs --- program/rust/build.rs | 2 -- program/rust/src/c_oracle_header.rs | 8 ++++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/program/rust/build.rs b/program/rust/build.rs index 3c4e3cb8a..b8aee2acb 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -5,7 +5,6 @@ fn main() { println!("cargo:rustc-link-search=./program/c/target"); let borsh_derives = ["BorshSerialize".to_string(), "BorshDeserialize".to_string()]; - let pod_derive = ["Pod".to_string(), "Zeroable".to_string()]; //make a parser and to it type, traits pairs let mut parser = build_utils::DeriveAdderParserCallback::new(); @@ -14,7 +13,6 @@ fn main() { parser.register_traits("pc_price_info", borsh_derives.to_vec()); parser.register_traits("cmd_upd_price", borsh_derives.to_vec()); parser.register_traits("pc_ema", borsh_derives.to_vec()); - parser.register_traits("cmd_add_price", pod_derive.to_vec()); //generate and write bindings let bindings = Builder::default() diff --git a/program/rust/src/c_oracle_header.rs b/program/rust/src/c_oracle_header.rs index 045642115..44b80b790 100644 --- a/program/rust/src/c_oracle_header.rs +++ b/program/rust/src/c_oracle_header.rs @@ -55,3 +55,11 @@ unsafe impl Zeroable for cmd_hdr { #[cfg(target_endian = "little")] unsafe impl Pod for cmd_hdr { } + +#[cfg(target_endian = "little")] +unsafe impl Zeroable for cmd_add_price_t { +} + +#[cfg(target_endian = "little")] +unsafe impl Pod for cmd_add_price_t { +} From 460e125d0fb34f35d3a093969011dc0ac2cc578e Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Fri, 5 Aug 2022 15:58:51 +0000 Subject: [PATCH 56/60] Load checks length --- program/rust/src/rust_oracle.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 9d0c0a56a..55c012df9 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -224,7 +224,11 @@ pub fn clear_account(account: &AccountInfo) -> Result<(), ProgramError> { /// Interpret the bytes in `data` as a value of type `T` fn load(data: &[u8]) -> Result<&T, ProgramError> { - try_from_bytes(&data[0..size_of::()]).map_err(|_| ProgramError::InvalidArgument) + try_from_bytes( + data.get(0..size_of::()) + .ok_or(ProgramError::InvalidArgument)?, + ) + .map_err(|_| ProgramError::InvalidArgument) } /// Interpret the bytes in `data` as a mutable value of type `T` From 81142a1bdef69e91d32fee0c20f83f6917ff1471 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Fri, 5 Aug 2022 16:19:02 +0000 Subject: [PATCH 57/60] Refactor load product --- program/rust/src/rust_oracle.rs | 69 +++++++++++++++++---------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 55c012df9..b29177008 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -137,9 +137,6 @@ pub fn add_price( accounts: &[AccountInfo], instruction_data: &[u8], ) -> OracleResult { - if instruction_data.len() < size_of::() { - return Err(ProgramError::InvalidArgument); - } let cmd_args = load::(instruction_data)?; if cmd_args.expo_ > PC_MAX_NUM_DECIMALS as i32 @@ -153,40 +150,29 @@ pub fn add_price( [x, y, z] if valid_funding_account(x) && valid_signable_account(program_id, y, PC_PROD_ACC_SIZE as usize) - && valid_signable_account(program_id, z, size_of::()) => + && valid_signable_account(program_id, z, size_of::()) + && valid_fresh_account(z) => { Ok([x, y, z]) } _ => Err(ProgramError::InvalidArgument), }?; - let mut product_data = load_account_as_mut::(product_account)?; - { - let price_data = load_account_as::(price_account)?; - - if product_data.magic_ != PC_MAGIC - || product_data.ver_ != cmd_args.ver_ - || product_data.type_ != PC_ACCTYPE_PRODUCT - || price_data.magic_ != 0 - { - return Err(ProgramError::InvalidArgument); - } - } + let mut product_data = load_product_account_mut(product_account, cmd_args.ver_)?; clear_account(price_account)?; - { - let mut price_data = load_account_as_mut::(price_account)?; - price_data.magic_ = PC_MAGIC; - price_data.ver_ = cmd_args.ver_; - price_data.type_ = PC_ACCTYPE_PRICE; - price_data.size_ = (size_of::() - size_of_val(&price_data.comp_)) as u32; - price_data.expo_ = cmd_args.expo_; - price_data.ptype_ = cmd_args.ptype_; - price_data.prod_.k1_ = product_account.key.to_bytes(); - price_data.next_ = product_data.px_acc_; - product_data.px_acc_.k1_ = price_account.key.to_bytes(); - } + let mut price_data = load_account_as_mut::(price_account)?; + price_data.magic_ = PC_MAGIC; + price_data.ver_ = cmd_args.ver_; + price_data.type_ = PC_ACCTYPE_PRICE; + price_data.size_ = (size_of::() - size_of_val(&price_data.comp_)) as u32; + price_data.expo_ = cmd_args.expo_; + price_data.ptype_ = cmd_args.ptype_; + price_data.prod_.k1_ = product_account.key.to_bytes(); + price_data.next_ = product_data.px_acc_; + product_data.px_acc_.k1_ = price_account.key.to_bytes(); + Ok(SUCCESS) } @@ -265,17 +251,16 @@ fn load_mapping_account_mut<'a>( account: &'a AccountInfo, expected_version: u32, ) -> Result, ProgramError> { - let mapping_account_ref = load_account_as_mut::(account)?; - let mapping_account = *mapping_account_ref; + let mapping_data = load_account_as_mut::(account)?; pyth_assert( - mapping_account.magic_ == PC_MAGIC - && mapping_account.ver_ == expected_version - && mapping_account.type_ == PC_ACCTYPE_MAPPING, + mapping_data.magic_ == PC_MAGIC + && mapping_data.ver_ == expected_version + && mapping_data.type_ == PC_ACCTYPE_MAPPING, ProgramError::InvalidArgument, )?; - Ok(mapping_account_ref) + Ok(mapping_data) } /// Initialize account as a new mapping account. This function will zero out any existing data in @@ -292,3 +277,19 @@ fn initialize_mapping_account(account: &AccountInfo, version: u32) -> Result<(), Ok(()) } + +fn load_product_account_mut<'a>( + account: &'a AccountInfo, + expected_version: u32, +) -> Result, ProgramError> { + let product_data = load_account_as_mut::(account)?; + + pyth_assert( + product_data.magic_ == PC_MAGIC + && product_data.ver_ == expected_version + && product_data.type_ == PC_ACCTYPE_PRODUCT, + ProgramError::InvalidArgument, + )?; + + Ok(product_data) +} From bacc9f054eab58d0e5325b2b3f54aa2aeed6145a Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Fri, 5 Aug 2022 16:41:45 +0000 Subject: [PATCH 58/60] Pubkey assign --- program/rust/src/c_oracle_header.rs | 8 ++++++++ program/rust/src/rust_oracle.rs | 23 ++++++++++++----------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/program/rust/src/c_oracle_header.rs b/program/rust/src/c_oracle_header.rs index 44b80b790..13648bbd7 100644 --- a/program/rust/src/c_oracle_header.rs +++ b/program/rust/src/c_oracle_header.rs @@ -63,3 +63,11 @@ unsafe impl Zeroable for cmd_add_price_t { #[cfg(target_endian = "little")] unsafe impl Pod for cmd_add_price_t { } + +#[cfg(target_endian = "little")] +unsafe impl Zeroable for pc_pub_key_t { +} + +#[cfg(target_endian = "little")] +unsafe impl Pod for pc_pub_key_t { +} diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index b29177008..15dc7fb76 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -9,6 +9,7 @@ use std::mem::{ }; use bytemuck::{ + bytes_of, try_from_bytes, try_from_bytes_mut, Pod, @@ -27,6 +28,7 @@ use crate::c_oracle_header::{ pc_map_table_t, pc_price_t, pc_prod_t, + pc_pub_key_t, PC_ACCTYPE_MAPPING, PC_ACCTYPE_PRICE, PC_ACCTYPE_PRODUCT, @@ -110,7 +112,7 @@ pub fn add_mapping( }?; let hdr = load::(instruction_data)?; - let mut cur_mapping = load_mapping_account_mut(cur_mapping, hdr.ver_)?; + let cur_mapping = load_mapping_account_mut(cur_mapping, hdr.ver_)?; pyth_assert( cur_mapping.num_ == PC_MAP_TABLE_SIZE && unsafe { cur_mapping.next_.k8_.iter().all(|x| *x == 0) }, @@ -118,12 +120,7 @@ pub fn add_mapping( )?; initialize_mapping_account(next_mapping, hdr.ver_)?; - unsafe { - cur_mapping - .next_ - .k1_ - .copy_from_slice(&next_mapping.key.to_bytes()); - } + pubkey_assign(cur_mapping.next_, &next_mapping.key.to_bytes()); Ok(SUCCESS) } @@ -158,7 +155,7 @@ pub fn add_price( _ => Err(ProgramError::InvalidArgument), }?; - let mut product_data = load_product_account_mut(product_account, cmd_args.ver_)?; + let product_data = load_product_account_mut(product_account, cmd_args.ver_)?; clear_account(price_account)?; @@ -169,9 +166,9 @@ pub fn add_price( price_data.size_ = (size_of::() - size_of_val(&price_data.comp_)) as u32; price_data.expo_ = cmd_args.expo_; price_data.ptype_ = cmd_args.ptype_; - price_data.prod_.k1_ = product_account.key.to_bytes(); - price_data.next_ = product_data.px_acc_; - product_data.px_acc_.k1_ = price_account.key.to_bytes(); + pubkey_assign(price_data.prod_, &product_account.key.to_bytes()); + pubkey_assign(price_data.next_, bytes_of(&product_data.px_acc_)); + pubkey_assign(product_data.px_acc_, &price_account.key.to_bytes()); Ok(SUCCESS) } @@ -293,3 +290,7 @@ fn load_product_account_mut<'a>( Ok(product_data) } + +fn pubkey_assign(mut target: pc_pub_key_t, source: &[u8]) { + unsafe { target.k1_.copy_from_slice(source) } +} From 48ccf9db6fa690535e99856ca59b3729ef3697ff Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Fri, 5 Aug 2022 16:44:46 +0000 Subject: [PATCH 59/60] Comments --- program/rust/src/rust_oracle.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 15dc7fb76..915e34d74 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -275,6 +275,9 @@ fn initialize_mapping_account(account: &AccountInfo, version: u32) -> Result<(), Ok(()) } +/// Mutably borrow the data in `account` as a product account, validating that the account +/// is properly formatted. Any mutations to the returned value will be reflected in the +/// account data. Use this to read already-initialized accounts. fn load_product_account_mut<'a>( account: &'a AccountInfo, expected_version: u32, @@ -291,6 +294,7 @@ fn load_product_account_mut<'a>( Ok(product_data) } +// Assign pubkey bytes from source to target, fails if source is not 32 bytes fn pubkey_assign(mut target: pc_pub_key_t, source: &[u8]) { unsafe { target.k1_.copy_from_slice(source) } } From cc7ea351b07d5b26ab6a8d09a796d01c93ea9d0e Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Fri, 5 Aug 2022 18:35:13 +0000 Subject: [PATCH 60/60] Fix pubkey assign --- program/rust/src/rust_oracle.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 915e34d74..71bcaf9d9 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -112,7 +112,7 @@ pub fn add_mapping( }?; let hdr = load::(instruction_data)?; - let cur_mapping = load_mapping_account_mut(cur_mapping, hdr.ver_)?; + let mut cur_mapping = load_mapping_account_mut(cur_mapping, hdr.ver_)?; pyth_assert( cur_mapping.num_ == PC_MAP_TABLE_SIZE && unsafe { cur_mapping.next_.k8_.iter().all(|x| *x == 0) }, @@ -120,7 +120,7 @@ pub fn add_mapping( )?; initialize_mapping_account(next_mapping, hdr.ver_)?; - pubkey_assign(cur_mapping.next_, &next_mapping.key.to_bytes()); + pubkey_assign(&mut cur_mapping.next_, &next_mapping.key.to_bytes()); Ok(SUCCESS) } @@ -155,7 +155,7 @@ pub fn add_price( _ => Err(ProgramError::InvalidArgument), }?; - let product_data = load_product_account_mut(product_account, cmd_args.ver_)?; + let mut product_data = load_product_account_mut(product_account, cmd_args.ver_)?; clear_account(price_account)?; @@ -166,9 +166,9 @@ pub fn add_price( price_data.size_ = (size_of::() - size_of_val(&price_data.comp_)) as u32; price_data.expo_ = cmd_args.expo_; price_data.ptype_ = cmd_args.ptype_; - pubkey_assign(price_data.prod_, &product_account.key.to_bytes()); - pubkey_assign(price_data.next_, bytes_of(&product_data.px_acc_)); - pubkey_assign(product_data.px_acc_, &price_account.key.to_bytes()); + pubkey_assign(&mut price_data.prod_, &product_account.key.to_bytes()); + pubkey_assign(&mut price_data.next_, bytes_of(&product_data.px_acc_)); + pubkey_assign(&mut product_data.px_acc_, &price_account.key.to_bytes()); Ok(SUCCESS) } @@ -295,6 +295,6 @@ fn load_product_account_mut<'a>( } // Assign pubkey bytes from source to target, fails if source is not 32 bytes -fn pubkey_assign(mut target: pc_pub_key_t, source: &[u8]) { +fn pubkey_assign(target: &mut pc_pub_key_t, source: &[u8]) { unsafe { target.k1_.copy_from_slice(source) } }