From 8e36ac03766f0374dcbdfe9005c96ce86f71618d Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Alapont Date: Mon, 22 Aug 2022 12:36:15 -0500 Subject: [PATCH 1/8] OracleCommand struct --- program/rust/Cargo.toml | 2 + program/rust/output.rs | 3039 +++++++++++++++++++ program/rust/output.rscargo | 0 program/rust/src/deserialize.rs | 3 + program/rust/src/instruction.rs | 73 + program/rust/src/lib.rs | 1 + program/rust/src/processor.rs | 59 +- program/rust/src/tests/test_add_mapping.rs | 15 +- program/rust/src/tests/test_init_mapping.rs | 22 +- 9 files changed, 3157 insertions(+), 57 deletions(-) create mode 100644 program/rust/output.rs create mode 100644 program/rust/output.rscargo create mode 100644 program/rust/src/instruction.rs diff --git a/program/rust/Cargo.toml b/program/rust/Cargo.toml index a368063ac..8681d5b54 100644 --- a/program/rust/Cargo.toml +++ b/program/rust/Cargo.toml @@ -12,6 +12,8 @@ bindgen = "0.60.1" solana-program = "=1.10.29" bytemuck = "1.11.0" thiserror = "1.0" +num-derive = "0.3" +num-traits = "0.2" [dev-dependencies] solana-program-test = "=1.10.29" diff --git a/program/rust/output.rs b/program/rust/output.rs new file mode 100644 index 000000000..7eb8cd259 --- /dev/null +++ b/program/rust/output.rs @@ -0,0 +1,3039 @@ +#![feature(prelude_import)] +#![allow(non_upper_case_globals)] +#![allow(clippy::not_unsafe_ptr_arg_deref)] +#[prelude_import] +use std::prelude::rust_2021::*; +#[macro_use] +extern crate std; +mod c_oracle_header { + #![allow(non_camel_case_types)] + #![allow(non_snake_case)] + #![allow(dead_code)] + use bytemuck::{Pod, Zeroable}; + use solana_program::pubkey::Pubkey; + use std::mem::size_of; + #[repr(C)] + pub struct __IncompleteArrayField(::std::marker::PhantomData, [T; 0]); + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::default::Default for __IncompleteArrayField { + #[inline] + fn default() -> __IncompleteArrayField { + __IncompleteArrayField( + ::core::default::Default::default(), + ::core::default::Default::default(), + ) + } + } + impl __IncompleteArrayField { + #[inline] + pub const fn new() -> Self { + __IncompleteArrayField(::std::marker::PhantomData, []) + } + #[inline] + pub fn as_ptr(&self) -> *const T { + self as *const _ as *const T + } + #[inline] + pub fn as_mut_ptr(&mut self) -> *mut T { + self as *mut _ as *mut T + } + #[inline] + pub unsafe fn as_slice(&self, len: usize) -> &[T] { + ::std::slice::from_raw_parts(self.as_ptr(), len) + } + #[inline] + pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { + ::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len) + } + } + impl ::std::fmt::Debug for __IncompleteArrayField { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + fmt.write_str("__IncompleteArrayField") + } + } + pub const true_: u32 = 1; + pub const false_: u32 = 0; + pub const __bool_true_false_are_defined: u32 = 1; + pub const PYTH_ORACLE_UTIL_COMPAT_STDINT_STYLE: u32 = 0; + pub const __WORDSIZE: u32 = 64; + pub const __DARWIN_ONLY_64_BIT_INO_T: u32 = 1; + pub const __DARWIN_ONLY_UNIX_CONFORMANCE: u32 = 1; + pub const __DARWIN_ONLY_VERS_1050: u32 = 1; + pub const __DARWIN_UNIX03: u32 = 1; + pub const __DARWIN_64_BIT_INO_T: u32 = 1; + pub const __DARWIN_VERS_1050: u32 = 1; + pub const __DARWIN_NON_CANCELABLE: u32 = 0; + pub const __DARWIN_SUF_EXTSN: &[u8; 14usize] = b"$DARWIN_EXTSN\0"; + pub const __DARWIN_C_ANSI: u32 = 4096; + pub const __DARWIN_C_FULL: u32 = 900000; + pub const __DARWIN_C_LEVEL: u32 = 900000; + pub const __STDC_WANT_LIB_EXT1__: u32 = 1; + pub const __DARWIN_NO_LONG_LONG: u32 = 0; + pub const _DARWIN_FEATURE_64_BIT_INODE: u32 = 1; + pub const _DARWIN_FEATURE_ONLY_64_BIT_INODE: u32 = 1; + pub const _DARWIN_FEATURE_ONLY_VERS_1050: u32 = 1; + pub const _DARWIN_FEATURE_ONLY_UNIX_CONFORMANCE: u32 = 1; + pub const _DARWIN_FEATURE_UNIX_CONFORMANCE: u32 = 3; + pub const __has_ptrcheck: u32 = 0; + pub const __PTHREAD_SIZE__: u32 = 8176; + pub const __PTHREAD_ATTR_SIZE__: u32 = 56; + pub const __PTHREAD_MUTEXATTR_SIZE__: u32 = 8; + pub const __PTHREAD_MUTEX_SIZE__: u32 = 56; + pub const __PTHREAD_CONDATTR_SIZE__: u32 = 8; + pub const __PTHREAD_COND_SIZE__: u32 = 40; + pub const __PTHREAD_ONCE_SIZE__: u32 = 8; + pub const __PTHREAD_RWLOCK_SIZE__: u32 = 192; + pub const __PTHREAD_RWLOCKATTR_SIZE__: u32 = 16; + pub const INT8_MAX: u32 = 127; + pub const INT16_MAX: u32 = 32767; + pub const INT32_MAX: u32 = 2147483647; + pub const INT64_MAX: u64 = 9223372036854775807; + pub const INT8_MIN: i32 = -128; + pub const INT16_MIN: i32 = -32768; + pub const INT32_MIN: i32 = -2147483648; + pub const INT64_MIN: i64 = -9223372036854775808; + pub const UINT8_MAX: u32 = 255; + pub const UINT16_MAX: u32 = 65535; + pub const UINT32_MAX: u32 = 4294967295; + pub const UINT64_MAX: i32 = -1; + pub const INT_LEAST8_MIN: i32 = -128; + pub const INT_LEAST16_MIN: i32 = -32768; + pub const INT_LEAST32_MIN: i32 = -2147483648; + pub const INT_LEAST64_MIN: i64 = -9223372036854775808; + pub const INT_LEAST8_MAX: u32 = 127; + pub const INT_LEAST16_MAX: u32 = 32767; + pub const INT_LEAST32_MAX: u32 = 2147483647; + pub const INT_LEAST64_MAX: u64 = 9223372036854775807; + pub const UINT_LEAST8_MAX: u32 = 255; + pub const UINT_LEAST16_MAX: u32 = 65535; + pub const UINT_LEAST32_MAX: u32 = 4294967295; + pub const UINT_LEAST64_MAX: i32 = -1; + pub const INT_FAST8_MIN: i32 = -128; + pub const INT_FAST16_MIN: i32 = -32768; + pub const INT_FAST32_MIN: i32 = -2147483648; + pub const INT_FAST64_MIN: i64 = -9223372036854775808; + pub const INT_FAST8_MAX: u32 = 127; + pub const INT_FAST16_MAX: u32 = 32767; + pub const INT_FAST32_MAX: u32 = 2147483647; + pub const INT_FAST64_MAX: u64 = 9223372036854775807; + pub const UINT_FAST8_MAX: u32 = 255; + pub const UINT_FAST16_MAX: u32 = 65535; + pub const UINT_FAST32_MAX: u32 = 4294967295; + pub const UINT_FAST64_MAX: i32 = -1; + pub const INTPTR_MAX: u64 = 9223372036854775807; + pub const INTPTR_MIN: i64 = -9223372036854775808; + pub const UINTPTR_MAX: i32 = -1; + pub const SIZE_MAX: i32 = -1; + pub const RSIZE_MAX: i32 = -1; + pub const WINT_MIN: i32 = -2147483648; + pub const WINT_MAX: u32 = 2147483647; + pub const SIG_ATOMIC_MIN: i32 = -2147483648; + pub const SIG_ATOMIC_MAX: u32 = 2147483647; + pub const PC_MAGIC: u32 = 2712847316; + pub const PC_VERSION: u32 = 2; + pub const PC_MAX_SEND_LATENCY: u32 = 25; + pub const PC_PUBKEY_SIZE: u32 = 32; + pub const PC_MAP_TABLE_SIZE: u32 = 640; + pub const PC_COMP_SIZE: u32 = 32; + pub const PC_MAX_NUM_DECIMALS: u32 = 8; + pub const PC_PROD_ACC_SIZE: u32 = 512; + pub const PC_EXP_DECAY: i32 = -9; + pub const PC_MAX_CI_DIVISOR: u32 = 20; + pub const PC_HEAP_START: u64 = 12884901888; + pub const PC_PTYPE_UNKNOWN: u32 = 0; + pub const PC_PTYPE_PRICE: u32 = 1; + pub const PC_STATUS_UNKNOWN: u32 = 0; + pub const PC_STATUS_TRADING: u32 = 1; + pub const PC_STATUS_HALTED: u32 = 2; + pub const PC_STATUS_AUCTION: u32 = 3; + pub const PC_ACCTYPE_MAPPING: u32 = 1; + pub const PC_ACCTYPE_PRODUCT: u32 = 2; + pub const PC_ACCTYPE_PRICE: u32 = 3; + pub const PC_ACCTYPE_TEST: u32 = 4; + pub type size_t = ::std::os::raw::c_ulong; + pub type wchar_t = ::std::os::raw::c_int; + pub type max_align_t = f64; + pub type int_least8_t = i8; + pub type int_least16_t = i16; + pub type int_least32_t = i32; + pub type int_least64_t = i64; + pub type uint_least8_t = u8; + pub type uint_least16_t = u16; + pub type uint_least32_t = u32; + pub type uint_least64_t = u64; + pub type int_fast8_t = i8; + pub type int_fast16_t = i16; + pub type int_fast32_t = i32; + pub type int_fast64_t = i64; + pub type uint_fast8_t = u8; + pub type uint_fast16_t = u16; + pub type uint_fast32_t = u32; + pub type uint_fast64_t = u64; + pub type __int8_t = ::std::os::raw::c_schar; + pub type __uint8_t = ::std::os::raw::c_uchar; + pub type __int16_t = ::std::os::raw::c_short; + pub type __uint16_t = ::std::os::raw::c_ushort; + pub type __int32_t = ::std::os::raw::c_int; + pub type __uint32_t = ::std::os::raw::c_uint; + pub type __int64_t = ::std::os::raw::c_longlong; + pub type __uint64_t = ::std::os::raw::c_ulonglong; + pub type __darwin_intptr_t = ::std::os::raw::c_long; + pub type __darwin_natural_t = ::std::os::raw::c_uint; + pub type __darwin_ct_rune_t = ::std::os::raw::c_int; + #[repr(C)] + pub union __mbstate_t { + pub __mbstate8: [::std::os::raw::c_char; 128usize], + pub _mbstateL: ::std::os::raw::c_longlong, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for __mbstate_t {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for __mbstate_t { + #[inline] + fn clone(&self) -> __mbstate_t { + { + let _: ::core::clone::AssertParamIsCopy; + *self + } + } + } + pub type __darwin_mbstate_t = __mbstate_t; + pub type __darwin_ptrdiff_t = ::std::os::raw::c_long; + pub type __darwin_size_t = ::std::os::raw::c_ulong; + pub type __darwin_va_list = __builtin_va_list; + pub type __darwin_wchar_t = ::std::os::raw::c_int; + pub type __darwin_rune_t = __darwin_wchar_t; + pub type __darwin_wint_t = ::std::os::raw::c_int; + pub type __darwin_clock_t = ::std::os::raw::c_ulong; + pub type __darwin_socklen_t = __uint32_t; + pub type __darwin_ssize_t = ::std::os::raw::c_long; + pub type __darwin_time_t = ::std::os::raw::c_long; + pub type __darwin_blkcnt_t = __int64_t; + pub type __darwin_blksize_t = __int32_t; + pub type __darwin_dev_t = __int32_t; + pub type __darwin_fsblkcnt_t = ::std::os::raw::c_uint; + pub type __darwin_fsfilcnt_t = ::std::os::raw::c_uint; + pub type __darwin_gid_t = __uint32_t; + pub type __darwin_id_t = __uint32_t; + pub type __darwin_ino64_t = __uint64_t; + pub type __darwin_ino_t = __darwin_ino64_t; + pub type __darwin_mach_port_name_t = __darwin_natural_t; + pub type __darwin_mach_port_t = __darwin_mach_port_name_t; + pub type __darwin_mode_t = __uint16_t; + pub type __darwin_off_t = __int64_t; + pub type __darwin_pid_t = __int32_t; + pub type __darwin_sigset_t = __uint32_t; + pub type __darwin_suseconds_t = __int32_t; + pub type __darwin_uid_t = __uint32_t; + pub type __darwin_useconds_t = __uint32_t; + pub type __darwin_uuid_t = [::std::os::raw::c_uchar; 16usize]; + pub type __darwin_uuid_string_t = [::std::os::raw::c_char; 37usize]; + #[repr(C)] + pub struct __darwin_pthread_handler_rec { + pub __routine: + ::std::option::Option, + pub __arg: *mut ::std::os::raw::c_void, + pub __next: *mut __darwin_pthread_handler_rec, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for __darwin_pthread_handler_rec { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + __routine: ref __self_0_0, + __arg: ref __self_0_1, + __next: ref __self_0_2, + } => { + let debug_trait_builder = &mut ::core::fmt::Formatter::debug_struct( + f, + "__darwin_pthread_handler_rec", + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__routine", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__arg", + &&(*__self_0_1), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__next", + &&(*__self_0_2), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for __darwin_pthread_handler_rec {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for __darwin_pthread_handler_rec { + #[inline] + fn clone(&self) -> __darwin_pthread_handler_rec { + { + let _: ::core::clone::AssertParamIsClone< + ::std::option::Option, + >; + let _: ::core::clone::AssertParamIsClone<*mut ::std::os::raw::c_void>; + let _: ::core::clone::AssertParamIsClone<*mut __darwin_pthread_handler_rec>; + *self + } + } + } + #[repr(C)] + pub struct _opaque_pthread_attr_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 56usize], + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for _opaque_pthread_attr_t { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + __sig: ref __self_0_0, + __opaque: ref __self_0_1, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "_opaque_pthread_attr_t"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__sig", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__opaque", + &&(*__self_0_1), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for _opaque_pthread_attr_t {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for _opaque_pthread_attr_t { + #[inline] + fn clone(&self) -> _opaque_pthread_attr_t { + { + let _: ::core::clone::AssertParamIsClone<::std::os::raw::c_long>; + let _: ::core::clone::AssertParamIsClone<[::std::os::raw::c_char; 56usize]>; + *self + } + } + } + #[repr(C)] + pub struct _opaque_pthread_cond_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 40usize], + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for _opaque_pthread_cond_t { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + __sig: ref __self_0_0, + __opaque: ref __self_0_1, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "_opaque_pthread_cond_t"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__sig", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__opaque", + &&(*__self_0_1), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for _opaque_pthread_cond_t {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for _opaque_pthread_cond_t { + #[inline] + fn clone(&self) -> _opaque_pthread_cond_t { + { + let _: ::core::clone::AssertParamIsClone<::std::os::raw::c_long>; + let _: ::core::clone::AssertParamIsClone<[::std::os::raw::c_char; 40usize]>; + *self + } + } + } + #[repr(C)] + pub struct _opaque_pthread_condattr_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 8usize], + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for _opaque_pthread_condattr_t { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + __sig: ref __self_0_0, + __opaque: ref __self_0_1, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "_opaque_pthread_condattr_t"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__sig", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__opaque", + &&(*__self_0_1), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for _opaque_pthread_condattr_t {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for _opaque_pthread_condattr_t { + #[inline] + fn clone(&self) -> _opaque_pthread_condattr_t { + { + let _: ::core::clone::AssertParamIsClone<::std::os::raw::c_long>; + let _: ::core::clone::AssertParamIsClone<[::std::os::raw::c_char; 8usize]>; + *self + } + } + } + #[repr(C)] + pub struct _opaque_pthread_mutex_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 56usize], + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for _opaque_pthread_mutex_t { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + __sig: ref __self_0_0, + __opaque: ref __self_0_1, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "_opaque_pthread_mutex_t"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__sig", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__opaque", + &&(*__self_0_1), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for _opaque_pthread_mutex_t {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for _opaque_pthread_mutex_t { + #[inline] + fn clone(&self) -> _opaque_pthread_mutex_t { + { + let _: ::core::clone::AssertParamIsClone<::std::os::raw::c_long>; + let _: ::core::clone::AssertParamIsClone<[::std::os::raw::c_char; 56usize]>; + *self + } + } + } + #[repr(C)] + pub struct _opaque_pthread_mutexattr_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 8usize], + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for _opaque_pthread_mutexattr_t { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + __sig: ref __self_0_0, + __opaque: ref __self_0_1, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "_opaque_pthread_mutexattr_t"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__sig", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__opaque", + &&(*__self_0_1), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for _opaque_pthread_mutexattr_t {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for _opaque_pthread_mutexattr_t { + #[inline] + fn clone(&self) -> _opaque_pthread_mutexattr_t { + { + let _: ::core::clone::AssertParamIsClone<::std::os::raw::c_long>; + let _: ::core::clone::AssertParamIsClone<[::std::os::raw::c_char; 8usize]>; + *self + } + } + } + #[repr(C)] + pub struct _opaque_pthread_once_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 8usize], + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for _opaque_pthread_once_t { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + __sig: ref __self_0_0, + __opaque: ref __self_0_1, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "_opaque_pthread_once_t"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__sig", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__opaque", + &&(*__self_0_1), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for _opaque_pthread_once_t {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for _opaque_pthread_once_t { + #[inline] + fn clone(&self) -> _opaque_pthread_once_t { + { + let _: ::core::clone::AssertParamIsClone<::std::os::raw::c_long>; + let _: ::core::clone::AssertParamIsClone<[::std::os::raw::c_char; 8usize]>; + *self + } + } + } + #[repr(C)] + pub struct _opaque_pthread_rwlock_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 192usize], + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for _opaque_pthread_rwlock_t { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + __sig: ref __self_0_0, + __opaque: ref __self_0_1, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "_opaque_pthread_rwlock_t"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__sig", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__opaque", + &&(*__self_0_1), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for _opaque_pthread_rwlock_t {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for _opaque_pthread_rwlock_t { + #[inline] + fn clone(&self) -> _opaque_pthread_rwlock_t { + { + let _: ::core::clone::AssertParamIsClone<::std::os::raw::c_long>; + let _: ::core::clone::AssertParamIsClone<[::std::os::raw::c_char; 192usize]>; + *self + } + } + } + #[repr(C)] + pub struct _opaque_pthread_rwlockattr_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 16usize], + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for _opaque_pthread_rwlockattr_t { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + __sig: ref __self_0_0, + __opaque: ref __self_0_1, + } => { + let debug_trait_builder = &mut ::core::fmt::Formatter::debug_struct( + f, + "_opaque_pthread_rwlockattr_t", + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__sig", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__opaque", + &&(*__self_0_1), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for _opaque_pthread_rwlockattr_t {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for _opaque_pthread_rwlockattr_t { + #[inline] + fn clone(&self) -> _opaque_pthread_rwlockattr_t { + { + let _: ::core::clone::AssertParamIsClone<::std::os::raw::c_long>; + let _: ::core::clone::AssertParamIsClone<[::std::os::raw::c_char; 16usize]>; + *self + } + } + } + #[repr(C)] + pub struct _opaque_pthread_t { + pub __sig: ::std::os::raw::c_long, + pub __cleanup_stack: *mut __darwin_pthread_handler_rec, + pub __opaque: [::std::os::raw::c_char; 8176usize], + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for _opaque_pthread_t { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + __sig: ref __self_0_0, + __cleanup_stack: ref __self_0_1, + __opaque: ref __self_0_2, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "_opaque_pthread_t"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__sig", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__cleanup_stack", + &&(*__self_0_1), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "__opaque", + &&(*__self_0_2), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for _opaque_pthread_t {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for _opaque_pthread_t { + #[inline] + fn clone(&self) -> _opaque_pthread_t { + { + let _: ::core::clone::AssertParamIsClone<::std::os::raw::c_long>; + let _: ::core::clone::AssertParamIsClone<*mut __darwin_pthread_handler_rec>; + let _: ::core::clone::AssertParamIsClone<[::std::os::raw::c_char; 8176usize]>; + *self + } + } + } + pub type __darwin_pthread_attr_t = _opaque_pthread_attr_t; + pub type __darwin_pthread_cond_t = _opaque_pthread_cond_t; + pub type __darwin_pthread_condattr_t = _opaque_pthread_condattr_t; + pub type __darwin_pthread_key_t = ::std::os::raw::c_ulong; + pub type __darwin_pthread_mutex_t = _opaque_pthread_mutex_t; + pub type __darwin_pthread_mutexattr_t = _opaque_pthread_mutexattr_t; + pub type __darwin_pthread_once_t = _opaque_pthread_once_t; + pub type __darwin_pthread_rwlock_t = _opaque_pthread_rwlock_t; + pub type __darwin_pthread_rwlockattr_t = _opaque_pthread_rwlockattr_t; + pub type __darwin_pthread_t = *mut _opaque_pthread_t; + pub type u_int8_t = ::std::os::raw::c_uchar; + pub type u_int16_t = ::std::os::raw::c_ushort; + pub type u_int32_t = ::std::os::raw::c_uint; + pub type u_int64_t = ::std::os::raw::c_ulonglong; + pub type register_t = i64; + pub type user_addr_t = u_int64_t; + pub type user_size_t = u_int64_t; + pub type user_ssize_t = i64; + pub type user_long_t = i64; + pub type user_ulong_t = u_int64_t; + pub type user_time_t = i64; + pub type user_off_t = i64; + pub type syscall_arg_t = u_int64_t; + pub type intmax_t = ::std::os::raw::c_long; + pub type uintmax_t = ::std::os::raw::c_ulong; + pub const TIME_MACHINE_STRUCT_SIZE: u64 = 1864; + pub const EXTRA_PUBLISHER_SPACE: u64 = 1000; + extern "C" { + pub static sysvar_clock: [u64; 4usize]; + } + #[repr(C)] + pub union pc_pub_key { + pub k1_: [u8; 32usize], + pub k8_: [u64; 4usize], + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for pc_pub_key {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for pc_pub_key { + #[inline] + fn clone(&self) -> pc_pub_key { + { + let _: ::core::clone::AssertParamIsCopy; + *self + } + } + } + pub type pc_pub_key_t = pc_pub_key; + #[repr(C)] + pub struct pc_acc { + pub magic_: u32, + pub ver_: u32, + pub type_: u32, + pub size_: u32, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for pc_acc { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + magic_: ref __self_0_0, + ver_: ref __self_0_1, + type_: ref __self_0_2, + size_: ref __self_0_3, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "pc_acc"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "magic_", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "ver_", + &&(*__self_0_1), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "type_", + &&(*__self_0_2), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "size_", + &&(*__self_0_3), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for pc_acc {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for pc_acc { + #[inline] + fn clone(&self) -> pc_acc { + { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + *self + } + } + } + pub type pc_acc_t = pc_acc; + #[repr(C)] + pub struct pc_map_table { + pub magic_: u32, + pub ver_: u32, + pub type_: u32, + pub size_: u32, + pub num_: u32, + pub unused_: u32, + pub next_: pc_pub_key_t, + pub prod_: [pc_pub_key_t; 640usize], + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for pc_map_table {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for pc_map_table { + #[inline] + fn clone(&self) -> pc_map_table { + { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone<[pc_pub_key_t; 640usize]>; + *self + } + } + } + pub type pc_map_table_t = pc_map_table; + #[repr(C)] + pub struct pc_str { + pub len_: u8, + pub data_: __IncompleteArrayField<::std::os::raw::c_char>, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for pc_str { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + len_: ref __self_0_0, + data_: ref __self_0_1, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "pc_str"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "len_", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "data_", + &&(*__self_0_1), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + pub type pc_str_t = pc_str; + #[repr(C)] + pub struct pc_prod { + pub magic_: u32, + pub ver_: u32, + pub type_: u32, + pub size_: u32, + pub px_acc_: pc_pub_key_t, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for pc_prod {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for pc_prod { + #[inline] + fn clone(&self) -> pc_prod { + { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + *self + } + } + } + pub type pc_prod_t = pc_prod; + #[repr(C)] + pub struct pc_price_info { + pub price_: i64, + pub conf_: u64, + pub status_: u32, + pub corp_act_status_: u32, + pub pub_slot_: u64, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for pc_price_info { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + price_: ref __self_0_0, + conf_: ref __self_0_1, + status_: ref __self_0_2, + corp_act_status_: ref __self_0_3, + pub_slot_: ref __self_0_4, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "pc_price_info"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "price_", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "conf_", + &&(*__self_0_1), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "status_", + &&(*__self_0_2), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "corp_act_status_", + &&(*__self_0_3), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "pub_slot_", + &&(*__self_0_4), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for pc_price_info {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for pc_price_info { + #[inline] + fn clone(&self) -> pc_price_info { + { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + *self + } + } + } + pub type pc_price_info_t = pc_price_info; + #[repr(C)] + pub struct pc_price_comp { + pub pub_: pc_pub_key_t, + pub agg_: pc_price_info_t, + pub latest_: pc_price_info_t, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for pc_price_comp {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for pc_price_comp { + #[inline] + fn clone(&self) -> pc_price_comp { + { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + *self + } + } + } + pub type pc_price_comp_t = pc_price_comp; + #[repr(C)] + pub struct pc_ema { + pub val_: i64, + pub numer_: i64, + pub denom_: i64, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for pc_ema { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + val_: ref __self_0_0, + numer_: ref __self_0_1, + denom_: ref __self_0_2, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "pc_ema"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "val_", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "numer_", + &&(*__self_0_1), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "denom_", + &&(*__self_0_2), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for pc_ema {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for pc_ema { + #[inline] + fn clone(&self) -> pc_ema { + { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + *self + } + } + } + pub type pc_ema_t = pc_ema; + #[repr(C)] + pub struct pc_price { + pub magic_: u32, + pub ver_: u32, + pub type_: u32, + pub size_: u32, + pub ptype_: u32, + pub expo_: i32, + pub num_: u32, + pub num_qt_: u32, + pub last_slot_: u64, + pub valid_slot_: u64, + pub twap_: pc_ema_t, + pub twac_: pc_ema_t, + pub timestamp_: i64, + pub min_pub_: u8, + pub drv2_: i8, + pub drv3_: i16, + pub drv4_: i32, + pub prod_: pc_pub_key_t, + pub next_: pc_pub_key_t, + pub prev_slot_: u64, + pub prev_price_: i64, + pub prev_conf_: u64, + pub prev_timestamp_: i64, + pub agg_: pc_price_info_t, + pub comp_: [pc_price_comp_t; 32usize], + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for pc_price {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for pc_price { + #[inline] + fn clone(&self) -> pc_price { + { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone<[pc_price_comp_t; 32usize]>; + *self + } + } + } + pub type pc_price_t = pc_price; + pub const PRICE_ACCOUNT_SIZE: u64 = 6176; + pub const command_t_e_cmd_init_mapping: command_t = 0; + pub const command_t_e_cmd_add_mapping: command_t = 1; + pub const command_t_e_cmd_add_product: command_t = 2; + pub const command_t_e_cmd_upd_product: command_t = 3; + pub const command_t_e_cmd_add_price: command_t = 4; + pub const command_t_e_cmd_add_publisher: command_t = 5; + pub const command_t_e_cmd_del_publisher: command_t = 6; + pub const command_t_e_cmd_upd_price: command_t = 7; + pub const command_t_e_cmd_agg_price: command_t = 8; + pub const command_t_e_cmd_init_price: command_t = 9; + pub const command_t_e_cmd_init_test: command_t = 10; + pub const command_t_e_cmd_upd_test: command_t = 11; + pub const command_t_e_cmd_set_min_pub: command_t = 12; + pub const command_t_e_cmd_upd_price_no_fail_on_error: command_t = 13; + pub const command_t_e_cmd_resize_price_account: command_t = 14; + pub const command_t_e_cmd_del_price: command_t = 15; + pub type command_t = ::std::os::raw::c_uint; + #[repr(C)] + pub struct cmd_hdr { + pub ver_: u32, + pub cmd_: i32, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for cmd_hdr { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + ver_: ref __self_0_0, + cmd_: ref __self_0_1, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "cmd_hdr"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "ver_", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "cmd_", + &&(*__self_0_1), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for cmd_hdr {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for cmd_hdr { + #[inline] + fn clone(&self) -> cmd_hdr { + { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + *self + } + } + } + pub type cmd_hdr_t = cmd_hdr; + #[repr(C)] + pub struct cmd_add_product { + pub ver_: u32, + pub cmd_: i32, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for cmd_add_product { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + ver_: ref __self_0_0, + cmd_: ref __self_0_1, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "cmd_add_product"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "ver_", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "cmd_", + &&(*__self_0_1), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for cmd_add_product {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for cmd_add_product { + #[inline] + fn clone(&self) -> cmd_add_product { + { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + *self + } + } + } + pub type cmd_add_product_t = cmd_add_product; + #[repr(C)] + pub struct cmd_upd_product { + pub ver_: u32, + pub cmd_: i32, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for cmd_upd_product { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + ver_: ref __self_0_0, + cmd_: ref __self_0_1, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "cmd_upd_product"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "ver_", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "cmd_", + &&(*__self_0_1), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for cmd_upd_product {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for cmd_upd_product { + #[inline] + fn clone(&self) -> cmd_upd_product { + { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + *self + } + } + } + pub type cmd_upd_product_t = cmd_upd_product; + #[repr(C)] + pub struct cmd_add_price { + pub ver_: u32, + pub cmd_: i32, + pub expo_: i32, + pub ptype_: u32, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for cmd_add_price { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + ver_: ref __self_0_0, + cmd_: ref __self_0_1, + expo_: ref __self_0_2, + ptype_: ref __self_0_3, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "cmd_add_price"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "ver_", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "cmd_", + &&(*__self_0_1), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "expo_", + &&(*__self_0_2), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "ptype_", + &&(*__self_0_3), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for cmd_add_price {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for cmd_add_price { + #[inline] + fn clone(&self) -> cmd_add_price { + { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + *self + } + } + } + pub type cmd_add_price_t = cmd_add_price; + #[repr(C)] + pub struct cmd_init_price { + pub ver_: u32, + pub cmd_: i32, + pub expo_: i32, + pub ptype_: u32, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for cmd_init_price { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + ver_: ref __self_0_0, + cmd_: ref __self_0_1, + expo_: ref __self_0_2, + ptype_: ref __self_0_3, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "cmd_init_price"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "ver_", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "cmd_", + &&(*__self_0_1), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "expo_", + &&(*__self_0_2), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "ptype_", + &&(*__self_0_3), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for cmd_init_price {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for cmd_init_price { + #[inline] + fn clone(&self) -> cmd_init_price { + { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + *self + } + } + } + pub type cmd_init_price_t = cmd_init_price; + #[repr(C)] + pub struct cmd_set_min_pub { + pub ver_: u32, + pub cmd_: i32, + pub min_pub_: u8, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for cmd_set_min_pub { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + ver_: ref __self_0_0, + cmd_: ref __self_0_1, + min_pub_: ref __self_0_2, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "cmd_set_min_pub"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "ver_", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "cmd_", + &&(*__self_0_1), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "min_pub_", + &&(*__self_0_2), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for cmd_set_min_pub {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for cmd_set_min_pub { + #[inline] + fn clone(&self) -> cmd_set_min_pub { + { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + *self + } + } + } + pub type cmd_set_min_pub_t = cmd_set_min_pub; + #[repr(C)] + pub struct cmd_add_publisher { + pub ver_: u32, + pub cmd_: i32, + pub pub_: pc_pub_key_t, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for cmd_add_publisher {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for cmd_add_publisher { + #[inline] + fn clone(&self) -> cmd_add_publisher { + { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + *self + } + } + } + pub type cmd_add_publisher_t = cmd_add_publisher; + #[repr(C)] + pub struct cmd_del_publisher { + pub ver_: u32, + pub cmd_: i32, + pub pub_: pc_pub_key_t, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for cmd_del_publisher {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for cmd_del_publisher { + #[inline] + fn clone(&self) -> cmd_del_publisher { + { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + *self + } + } + } + pub type cmd_del_publisher_t = cmd_del_publisher; + #[repr(C)] + pub struct cmd_upd_price { + pub ver_: u32, + pub cmd_: i32, + pub status_: u32, + pub unused_: u32, + pub price_: i64, + pub conf_: u64, + pub pub_slot_: u64, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for cmd_upd_price { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + ver_: ref __self_0_0, + cmd_: ref __self_0_1, + status_: ref __self_0_2, + unused_: ref __self_0_3, + price_: ref __self_0_4, + conf_: ref __self_0_5, + pub_slot_: ref __self_0_6, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "cmd_upd_price"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "ver_", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "cmd_", + &&(*__self_0_1), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "status_", + &&(*__self_0_2), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "unused_", + &&(*__self_0_3), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "price_", + &&(*__self_0_4), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "conf_", + &&(*__self_0_5), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "pub_slot_", + &&(*__self_0_6), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for cmd_upd_price {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for cmd_upd_price { + #[inline] + fn clone(&self) -> cmd_upd_price { + { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + *self + } + } + } + pub type cmd_upd_price_t = cmd_upd_price; + #[repr(C)] + pub struct cmd_upd_test { + pub ver_: u32, + pub cmd_: i32, + pub num_: u32, + pub expo_: i32, + pub slot_diff_: [i8; 32usize], + pub price_: [i64; 32usize], + pub conf_: [u64; 32usize], + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for cmd_upd_test { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + ver_: ref __self_0_0, + cmd_: ref __self_0_1, + num_: ref __self_0_2, + expo_: ref __self_0_3, + slot_diff_: ref __self_0_4, + price_: ref __self_0_5, + conf_: ref __self_0_6, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "cmd_upd_test"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "ver_", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "cmd_", + &&(*__self_0_1), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "num_", + &&(*__self_0_2), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "expo_", + &&(*__self_0_3), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "slot_diff_", + &&(*__self_0_4), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "price_", + &&(*__self_0_5), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "conf_", + &&(*__self_0_6), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for cmd_upd_test {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for cmd_upd_test { + #[inline] + fn clone(&self) -> cmd_upd_test { + { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone<[i8; 32usize]>; + let _: ::core::clone::AssertParamIsClone<[i64; 32usize]>; + let _: ::core::clone::AssertParamIsClone<[u64; 32usize]>; + *self + } + } + } + pub type cmd_upd_test_t = cmd_upd_test; + #[repr(C)] + pub struct sysvar_clock { + pub slot_: u64, + pub epoch_start_timestamp_: i64, + pub epoch_: u64, + pub leader_schedule_epoch_: u64, + pub unix_timestamp_: i64, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for sysvar_clock { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + slot_: ref __self_0_0, + epoch_start_timestamp_: ref __self_0_1, + epoch_: ref __self_0_2, + leader_schedule_epoch_: ref __self_0_3, + unix_timestamp_: ref __self_0_4, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "sysvar_clock"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "slot_", + &&(*__self_0_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "epoch_start_timestamp_", + &&(*__self_0_1), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "epoch_", + &&(*__self_0_2), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "leader_schedule_epoch_", + &&(*__self_0_3), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "unix_timestamp_", + &&(*__self_0_4), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for sysvar_clock {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for sysvar_clock { + #[inline] + fn clone(&self) -> sysvar_clock { + { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + *self + } + } + } + pub type sysvar_clock_t = sysvar_clock; + pub const PC_PRICE_T_COMP_OFFSET: size_t = 240; + pub const PC_MAP_TABLE_T_PROD_OFFSET: size_t = 56; + pub type __builtin_va_list = *mut ::std::os::raw::c_char; + /// The PythAccount trait's purpose is to attach constants to the 3 types of accounts that Pyth has + /// (mapping, price, product). This allows less duplicated code, because now we can create generic + /// functions to perform common checks on the accounts and to load and initialize the accounts. + pub trait PythAccount: Pod { + /// `ACCOUNT_TYPE` is just the account discriminator, it is different for mapping, product and + /// price + const ACCOUNT_TYPE: u32; + /// `INITIAL_SIZE` is the value that the field `size_` will take when the account is first + /// initialized this one is slightly tricky because for mapping (resp. price) `size_` won't + /// include the unpopulated entries of `prod_` (resp. `comp_`). At the beginning there are 0 + /// products (resp. 0 components) therefore `INITIAL_SIZE` will be equal to the offset of + /// `prod_` (resp. `comp_`) Similarly the product account `INITIAL_SIZE` won't include any + /// key values. + const INITIAL_SIZE: u32; + /// `minimum_size()` is the minimum size that the solana account holding the struct needs to + /// have. `INITIAL_SIZE` <= `minimum_size()` + fn minimum_size() -> usize { + size_of::() + } + } + impl PythAccount for pc_map_table_t { + const ACCOUNT_TYPE: u32 = PC_ACCTYPE_MAPPING; + const INITIAL_SIZE: u32 = PC_MAP_TABLE_T_PROD_OFFSET as u32; + } + impl PythAccount for pc_prod_t { + const ACCOUNT_TYPE: u32 = PC_ACCTYPE_PRODUCT; + const INITIAL_SIZE: u32 = size_of::() as u32; + fn minimum_size() -> usize { + PC_PROD_ACC_SIZE as usize + } + } + impl PythAccount for pc_price_t { + const ACCOUNT_TYPE: u32 = PC_ACCTYPE_PRICE; + const INITIAL_SIZE: u32 = PC_PRICE_T_COMP_OFFSET as u32; + } + #[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 {} + #[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 {} + #[cfg(target_endian = "little")] + unsafe impl Zeroable for cmd_hdr {} + #[cfg(target_endian = "little")] + unsafe impl Pod for cmd_hdr {} + #[cfg(target_endian = "little")] + unsafe impl Zeroable for pc_price_info {} + #[cfg(target_endian = "little")] + unsafe impl Pod for pc_price_info {} + #[cfg(target_endian = "little")] + unsafe impl Zeroable for cmd_upd_price {} + #[cfg(target_endian = "little")] + unsafe impl Pod for cmd_upd_price {} + #[cfg(target_endian = "little")] + unsafe impl Zeroable for pc_ema {} + #[cfg(target_endian = "little")] + unsafe impl Pod for pc_ema {} + #[cfg(target_endian = "little")] + 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 cmd_init_price_t {} + #[cfg(target_endian = "little")] + unsafe impl Pod for cmd_init_price_t {} + #[cfg(target_endian = "little")] + unsafe impl Zeroable for cmd_add_publisher_t {} + #[cfg(target_endian = "little")] + unsafe impl Pod for cmd_add_publisher_t {} + #[cfg(target_endian = "little")] + unsafe impl Zeroable for cmd_del_publisher_t {} + #[cfg(target_endian = "little")] + unsafe impl Pod for cmd_del_publisher_t {} + unsafe impl Zeroable for cmd_set_min_pub_t {} + #[cfg(target_endian = "little")] + unsafe impl Pod for cmd_set_min_pub_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 {} + #[cfg(target_endian = "little")] + unsafe impl Zeroable for pc_price_comp_t {} + #[cfg(target_endian = "little")] + unsafe impl Pod for pc_price_comp_t {} + impl pc_pub_key_t { + pub fn new_unique() -> pc_pub_key_t { + let solana_unique = Pubkey::new_unique(); + pc_pub_key_t { + k1_: solana_unique.to_bytes(), + } + } + } +} +mod deserialize { + use std::mem::size_of; + use bytemuck::{try_from_bytes, try_from_bytes_mut, Pod}; + use crate::c_oracle_header::{pc_acc, PythAccount, PC_MAGIC}; + use crate::utils::{clear_account, pyth_assert}; + use solana_program::account_info::AccountInfo; + use solana_program::program_error::ProgramError; + use std::cell::{Ref, RefMut}; + /// Interpret the bytes in `data` as a value of type `T` + pub fn load(data: &[u8]) -> Result<&T, ProgramError> { + 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` + #[allow(unused)] + pub fn load_mut(data: &mut [u8]) -> Result<&mut T, ProgramError> { + try_from_bytes_mut( + data.get_mut(0..size_of::()) + .ok_or(ProgramError::InvalidArgument)?, + ) + .map_err(|_| ProgramError::InvalidArgument) + } + /// Get the data stored in `account` as a value of type `T` + pub 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. + pub 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::()]) + })) + } + pub fn load_checked<'a, T: PythAccount>( + account: &'a AccountInfo, + version: u32, + ) -> Result, ProgramError> { + { + let account_header = load_account_as::(account)?; + pyth_assert( + account_header.magic_ == PC_MAGIC + && account_header.ver_ == version + && account_header.type_ == T::ACCOUNT_TYPE, + ProgramError::InvalidArgument, + )?; + } + load_account_as_mut::(account) + } + pub fn initialize_pyth_account_checked<'a, T: PythAccount>( + account: &'a AccountInfo, + version: u32, + ) -> Result, ProgramError> { + clear_account(account)?; + { + let mut account_header = load_account_as_mut::(account)?; + account_header.magic_ = PC_MAGIC; + account_header.ver_ = version; + account_header.type_ = T::ACCOUNT_TYPE; + account_header.size_ = T::INITIAL_SIZE; + } + load_account_as_mut::(account) + } +} +mod error { + //! Error types + use solana_program::program_error::ProgramError; + use thiserror::Error; + /// Errors that may be returned by the oracle program + pub enum OracleError { + /// Generic catch all error + #[error("Generic")] + Generic = 600, + /// integer casting error + #[error("IntegerCastingError")] + IntegerCastingError = 601, + /// c_entrypoint returned an unexpected value + #[error("UnknownCError")] + UnknownCError = 602, + #[error("UnrecognizedInstruction")] + UnrecognizedInstruction = 603, + #[error("InvalidFundingAccount")] + InvalidFundingAccount = 604, + #[error("InvalidSignableAccount")] + InvalidSignableAccount = 605, + #[error("InvalidSystemAccount")] + InvalidSystemAccount = 606, + #[error("InvalidWritableAccount")] + InvalidWritableAccount = 607, + #[error("InvalidFreshAccount")] + InvalidFreshAccount = 608, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for OracleError { + #[inline] + fn clone(&self) -> OracleError { + match (&*self,) { + (&OracleError::Generic,) => OracleError::Generic, + (&OracleError::IntegerCastingError,) => OracleError::IntegerCastingError, + (&OracleError::UnknownCError,) => OracleError::UnknownCError, + (&OracleError::UnrecognizedInstruction,) => OracleError::UnrecognizedInstruction, + (&OracleError::InvalidFundingAccount,) => OracleError::InvalidFundingAccount, + (&OracleError::InvalidSignableAccount,) => OracleError::InvalidSignableAccount, + (&OracleError::InvalidSystemAccount,) => OracleError::InvalidSystemAccount, + (&OracleError::InvalidWritableAccount,) => OracleError::InvalidWritableAccount, + (&OracleError::InvalidFreshAccount,) => OracleError::InvalidFreshAccount, + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for OracleError { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match (&*self,) { + (&OracleError::Generic,) => ::core::fmt::Formatter::write_str(f, "Generic"), + (&OracleError::IntegerCastingError,) => { + ::core::fmt::Formatter::write_str(f, "IntegerCastingError") + } + (&OracleError::UnknownCError,) => { + ::core::fmt::Formatter::write_str(f, "UnknownCError") + } + (&OracleError::UnrecognizedInstruction,) => { + ::core::fmt::Formatter::write_str(f, "UnrecognizedInstruction") + } + (&OracleError::InvalidFundingAccount,) => { + ::core::fmt::Formatter::write_str(f, "InvalidFundingAccount") + } + (&OracleError::InvalidSignableAccount,) => { + ::core::fmt::Formatter::write_str(f, "InvalidSignableAccount") + } + (&OracleError::InvalidSystemAccount,) => { + ::core::fmt::Formatter::write_str(f, "InvalidSystemAccount") + } + (&OracleError::InvalidWritableAccount,) => { + ::core::fmt::Formatter::write_str(f, "InvalidWritableAccount") + } + (&OracleError::InvalidFreshAccount,) => { + ::core::fmt::Formatter::write_str(f, "InvalidFreshAccount") + } + } + } + } + impl ::core::marker::StructuralEq for OracleError {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::cmp::Eq for OracleError { + #[inline] + #[doc(hidden)] + #[no_coverage] + fn assert_receiver_is_total_eq(&self) -> () { + {} + } + } + #[allow(unused_qualifications)] + impl std::error::Error for OracleError {} + #[allow(unused_qualifications)] + impl std::fmt::Display for OracleError { + fn fmt(&self, __formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + OracleError::Generic {} => { + let result = + __formatter.write_fmt(::core::fmt::Arguments::new_v1(&["Generic"], &[])); + result + } + OracleError::IntegerCastingError {} => { + let result = __formatter.write_fmt(::core::fmt::Arguments::new_v1( + &["IntegerCastingError"], + &[], + )); + result + } + OracleError::UnknownCError {} => { + let result = __formatter + .write_fmt(::core::fmt::Arguments::new_v1(&["UnknownCError"], &[])); + result + } + OracleError::UnrecognizedInstruction {} => { + let result = __formatter.write_fmt(::core::fmt::Arguments::new_v1( + &["UnrecognizedInstruction"], + &[], + )); + result + } + OracleError::InvalidFundingAccount {} => { + let result = __formatter.write_fmt(::core::fmt::Arguments::new_v1( + &["InvalidFundingAccount"], + &[], + )); + result + } + OracleError::InvalidSignableAccount {} => { + let result = __formatter.write_fmt(::core::fmt::Arguments::new_v1( + &["InvalidSignableAccount"], + &[], + )); + result + } + OracleError::InvalidSystemAccount {} => { + let result = __formatter.write_fmt(::core::fmt::Arguments::new_v1( + &["InvalidSystemAccount"], + &[], + )); + result + } + OracleError::InvalidWritableAccount {} => { + let result = __formatter.write_fmt(::core::fmt::Arguments::new_v1( + &["InvalidWritableAccount"], + &[], + )); + result + } + OracleError::InvalidFreshAccount {} => { + let result = __formatter.write_fmt(::core::fmt::Arguments::new_v1( + &["InvalidFreshAccount"], + &[], + )); + result + } + } + } + } + impl ::core::marker::StructuralPartialEq for OracleError {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::cmp::PartialEq for OracleError { + #[inline] + fn eq(&self, other: &OracleError) -> bool { + { + let __self_vi = ::core::intrinsics::discriminant_value(&*self); + let __arg_1_vi = ::core::intrinsics::discriminant_value(&*other); + if true && __self_vi == __arg_1_vi { + match (&*self, &*other) { + _ => true, + } + } else { + false + } + } + } + } + impl From for ProgramError { + fn from(e: OracleError) -> Self { + ProgramError::Custom(e as u32) + } + } +} +mod processor { + use crate::c_oracle_header::{ + cmd_hdr, command_t_e_cmd_add_mapping, command_t_e_cmd_add_price, + command_t_e_cmd_add_product, command_t_e_cmd_add_publisher, command_t_e_cmd_agg_price, + command_t_e_cmd_del_price, command_t_e_cmd_del_publisher, command_t_e_cmd_init_mapping, + command_t_e_cmd_init_price, command_t_e_cmd_resize_price_account, + command_t_e_cmd_set_min_pub, command_t_e_cmd_upd_price, + command_t_e_cmd_upd_price_no_fail_on_error, command_t_e_cmd_upd_product, PC_VERSION, + }; + use crate::instruction::OracleCommand; + use crate::deserialize::load; + use crate::error::OracleError; + use solana_program::entrypoint::ProgramResult; + use solana_program::program_error::ProgramError; + use solana_program::pubkey::Pubkey; + use solana_program::sysvar::slot_history::AccountInfo; + use crate::rust_oracle::{ + add_mapping, add_price, add_product, add_publisher, del_price, del_publisher, init_mapping, + init_price, resize_price_account, set_min_pub, upd_price, upd_price_no_fail_on_error, + upd_product, + }; + ///dispatch to the right instruction in the oracle + pub fn process_instruction( + program_id: &Pubkey, + accounts: &[AccountInfo], + instruction_data: &[u8], + ) -> ProgramResult { + let cmd_data = load::(instruction_data)?; + if cmd_data.ver_ != PC_VERSION { + return Err(ProgramError::InvalidArgument); + } + match OracleCommand::try_from(cmd_data.cmd_) { + OracleCommand::InitMapping => ::core::panicking::panic("not yet implemented"), + OracleCommand::AddMapping => ::core::panicking::panic("not yet implemented"), + OracleCommand::AddProduct => ::core::panicking::panic("not yet implemented"), + OracleCommand::UpdProduct => ::core::panicking::panic("not yet implemented"), + OracleCommand::AddPrice => ::core::panicking::panic("not yet implemented"), + OracleCommand::AddPublisher => ::core::panicking::panic("not yet implemented"), + OracleCommand::DelPublisher => ::core::panicking::panic("not yet implemented"), + OracleCommand::UpdPrice => ::core::panicking::panic("not yet implemented"), + OracleCommand::AggPrice => ::core::panicking::panic("not yet implemented"), + OracleCommand::InitPrice => ::core::panicking::panic("not yet implemented"), + OracleCommand::InitTest => ::core::panicking::panic("not yet implemented"), + OracleCommand::UpdTest => ::core::panicking::panic("not yet implemented"), + OracleCommand::SetMinPub => ::core::panicking::panic("not yet implemented"), + OracleCommand::UpdPriceNoFailOnError => ::core::panicking::panic("not yet implemented"), + OracleCommand::ResizePriceAccount => ::core::panicking::panic("not yet implemented"), + OracleCommand::DelPrice => ::core::panicking::panic("not yet implemented"), + } + } +} +mod rust_oracle { + use std::mem::{size_of, size_of_val}; + use bytemuck::{bytes_of, bytes_of_mut}; + use solana_program::account_info::AccountInfo; + use solana_program::clock::Clock; + use solana_program::entrypoint::ProgramResult; + use solana_program::program::invoke; + use solana_program::program_error::ProgramError; + use solana_program::program_memory::{sol_memcpy, sol_memset}; + use solana_program::pubkey::Pubkey; + use solana_program::rent::Rent; + use solana_program::system_instruction::transfer; + use solana_program::system_program::check_id; + use solana_program::sysvar::Sysvar; + use crate::c_oracle_header::{ + cmd_add_price_t, cmd_add_publisher_t, cmd_del_publisher_t, cmd_hdr_t, cmd_init_price_t, + cmd_set_min_pub_t, cmd_upd_price_t, cmd_upd_product_t, pc_ema_t, pc_map_table_t, + pc_price_comp, pc_price_info_t, pc_price_t, pc_prod_t, pc_pub_key_t, PC_COMP_SIZE, + PC_MAP_TABLE_SIZE, PC_MAX_CI_DIVISOR, PC_PROD_ACC_SIZE, PC_PTYPE_UNKNOWN, + PC_STATUS_UNKNOWN, PC_VERSION, + }; + use crate::deserialize::{initialize_pyth_account_checked, load, load_account_as_mut, load_checked}; + use crate::time_machine_types::PriceAccountWrapper; + use crate::utils::{ + check_exponent_range, check_valid_fresh_account, check_valid_funding_account, + check_valid_signable_account, check_valid_writable_account, is_component_update, + pubkey_assign, pubkey_equal, pubkey_is_zero, pyth_assert, read_pc_str_t, try_convert, + }; + use crate::OracleError; + const PRICE_T_SIZE: usize = size_of::(); + const PRICE_ACCOUNT_SIZE: usize = size_of::(); + #[cfg(not(target_arch = "bpf"))] + #[link(name = "cpyth-native")] + extern "C" { + pub fn c_upd_aggregate(_input: *mut u8, clock_slot: u64, clock_timestamp: i64) -> bool; + } + fn send_lamports<'a>( + from: &AccountInfo<'a>, + to: &AccountInfo<'a>, + system_program: &AccountInfo<'a>, + amount: u64, + ) -> Result<(), ProgramError> { + let transfer_instruction = transfer(from.key, to.key, amount); + invoke( + &transfer_instruction, + &[from.clone(), to.clone(), system_program.clone()], + )?; + Ok(()) + } + /// resizes a price account so that it fits the Time Machine + /// key[0] funding account [signer writable] + /// key[1] price account [Signer writable] + /// key[2] system program [readable] + pub fn resize_price_account( + program_id: &Pubkey, + accounts: &[AccountInfo], + _instruction_data: &[u8], + ) -> ProgramResult { + let [funding_account_info, price_account_info, system_program] = match accounts { + [x, y, z] => Ok([x, y, z]), + _ => Err(ProgramError::InvalidArgument), + }?; + check_valid_funding_account(funding_account_info)?; + check_valid_signable_account(program_id, price_account_info, size_of::())?; + pyth_assert( + check_id(system_program.key), + OracleError::InvalidSystemAccount.into(), + )?; + { + load_checked::(price_account_info, PC_VERSION)?; + } + let account_len = price_account_info.try_data_len()?; + match account_len { + PRICE_T_SIZE => { + let rent: Rent = Default::default(); + let lamports_needed: u64 = rent + .minimum_balance(size_of::()) + .saturating_sub(price_account_info.lamports()); + if lamports_needed > 0 { + send_lamports( + funding_account_info, + price_account_info, + system_program, + lamports_needed, + )?; + } + price_account_info.realloc(size_of::(), false)?; + let mut price_account = + load_checked::(price_account_info, PC_VERSION)?; + price_account.initialize_time_machine()?; + Ok(()) + } + PRICE_ACCOUNT_SIZE => Ok(()), + _ => Err(ProgramError::InvalidArgument), + } + } + /// 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: &[AccountInfo], + instruction_data: &[u8], + ) -> ProgramResult { + let [funding_account, fresh_mapping_account] = match accounts { + [x, y] => Ok([x, y]), + _ => Err(ProgramError::InvalidArgument), + }?; + check_valid_funding_account(funding_account)?; + check_valid_signable_account( + program_id, + fresh_mapping_account, + size_of::(), + )?; + check_valid_fresh_account(fresh_mapping_account)?; + let hdr = load::(instruction_data)?; + initialize_pyth_account_checked::(fresh_mapping_account, hdr.ver_)?; + Ok(()) + } + pub fn add_mapping( + program_id: &Pubkey, + accounts: &[AccountInfo], + instruction_data: &[u8], + ) -> ProgramResult { + let [funding_account, cur_mapping, next_mapping] = match accounts { + [x, y, z] => Ok([x, y, z]), + _ => Err(ProgramError::InvalidArgument), + }?; + check_valid_funding_account(funding_account)?; + check_valid_signable_account(program_id, cur_mapping, size_of::())?; + check_valid_signable_account(program_id, next_mapping, size_of::())?; + check_valid_fresh_account(next_mapping)?; + let hdr = load::(instruction_data)?; + let mut cur_mapping = load_checked::(cur_mapping, hdr.ver_)?; + pyth_assert( + cur_mapping.num_ == PC_MAP_TABLE_SIZE && pubkey_is_zero(&cur_mapping.next_), + ProgramError::InvalidArgument, + )?; + initialize_pyth_account_checked::(next_mapping, hdr.ver_)?; + pubkey_assign(&mut cur_mapping.next_, &next_mapping.key.to_bytes()); + Ok(()) + } + /// a publisher updates a price + /// accounts[0] publisher account [signer writable] + /// accounts[1] price account to update [writable] + /// accounts[2] sysvar clock [] + pub fn upd_price( + program_id: &Pubkey, + accounts: &[AccountInfo], + instruction_data: &[u8], + ) -> ProgramResult { + let cmd_args = load::(instruction_data)?; + let [funding_account, price_account, clock_account] = match accounts { + [x, y, z] => Ok([x, y, z]), + [x, y, _, z] => Ok([x, y, z]), + _ => Err(ProgramError::InvalidArgument), + }?; + check_valid_funding_account(funding_account)?; + check_valid_writable_account(program_id, price_account, size_of::())?; + let clock = Clock::from_account_info(clock_account)?; + let mut publisher_index: usize = 0; + let latest_aggregate_price: pc_price_info_t; + { + let price_data = load_checked::(price_account, cmd_args.ver_)?; + while publisher_index < price_data.num_ as usize { + if pubkey_equal( + &price_data.comp_[publisher_index].pub_, + &funding_account.key.to_bytes(), + ) { + break; + } + publisher_index += 1; + } + pyth_assert( + publisher_index < price_data.num_ as usize, + ProgramError::InvalidArgument, + )?; + latest_aggregate_price = price_data.agg_; + let latest_publisher_price = price_data.comp_[publisher_index].latest_; + pyth_assert( + !is_component_update(cmd_args)? + || cmd_args.pub_slot_ > latest_publisher_price.pub_slot_, + ProgramError::InvalidArgument, + )?; + } + let mut aggregate_updated = false; + if clock.slot > latest_aggregate_price.pub_slot_ { + unsafe { + aggregate_updated = c_upd_aggregate( + price_account.try_borrow_mut_data()?.as_mut_ptr(), + clock.slot, + clock.unix_timestamp, + ); + } + } + let account_len = price_account.try_data_len()?; + if aggregate_updated && account_len == PRICE_ACCOUNT_SIZE { + let mut price_account = load_account_as_mut::(price_account)?; + price_account.add_price_to_time_machine()?; + } + if is_component_update(cmd_args)? { + let mut status: u32 = cmd_args.status_; + let mut threshold_conf = cmd_args.price_ / PC_MAX_CI_DIVISOR as i64; + if threshold_conf < 0 { + threshold_conf = -threshold_conf; + } + if cmd_args.conf_ > try_convert::<_, u64>(threshold_conf)? { + status = PC_STATUS_UNKNOWN + } + { + let mut price_data = load_checked::(price_account, cmd_args.ver_)?; + let publisher_price = &mut price_data.comp_[publisher_index].latest_; + publisher_price.price_ = cmd_args.price_; + publisher_price.conf_ = cmd_args.conf_; + publisher_price.status_ = status; + publisher_price.pub_slot_ = cmd_args.pub_slot_; + } + } + Ok(()) + } + pub fn upd_price_no_fail_on_error( + program_id: &Pubkey, + accounts: &[AccountInfo], + instruction_data: &[u8], + ) -> ProgramResult { + match upd_price(program_id, accounts, instruction_data) { + Err(_) => Ok(()), + Ok(value) => Ok(value), + } + } + /// 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], + ) -> ProgramResult { + let cmd_args = load::(instruction_data)?; + check_exponent_range(cmd_args.expo_)?; + pyth_assert( + cmd_args.ptype_ != PC_PTYPE_UNKNOWN, + ProgramError::InvalidArgument, + )?; + let [funding_account, product_account, price_account] = match accounts { + [x, y, z] => Ok([x, y, z]), + _ => Err(ProgramError::InvalidArgument), + }?; + check_valid_funding_account(funding_account)?; + check_valid_signable_account(program_id, product_account, PC_PROD_ACC_SIZE as usize)?; + check_valid_signable_account(program_id, price_account, size_of::())?; + check_valid_fresh_account(price_account)?; + let mut product_data = load_checked::(product_account, cmd_args.ver_)?; + let mut price_data = + initialize_pyth_account_checked::(price_account, cmd_args.ver_)?; + price_data.expo_ = cmd_args.expo_; + price_data.ptype_ = cmd_args.ptype_; + 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(()) + } + /// Delete a price account. This function will remove the link between the price account and its + /// corresponding product account, then transfer any SOL in the price account to the funding + /// account. This function can only delete the first price account in the linked list of + /// price accounts for the given product. + /// + /// Warning: This function is dangerous and will break any programs that depend on the deleted + /// price account! + pub fn del_price( + program_id: &Pubkey, + accounts: &[AccountInfo], + instruction_data: &[u8], + ) -> ProgramResult { + let [funding_account, product_account, price_account] = match accounts { + [w, x, y] => Ok([w, x, y]), + _ => Err(ProgramError::InvalidArgument), + }?; + check_valid_funding_account(funding_account)?; + check_valid_signable_account(program_id, product_account, PC_PROD_ACC_SIZE as usize)?; + check_valid_signable_account(program_id, price_account, size_of::())?; + { + let cmd_args = load::(instruction_data)?; + let mut product_data = load_checked::(product_account, cmd_args.ver_)?; + let price_data = load_checked::(price_account, cmd_args.ver_)?; + pyth_assert( + pubkey_equal(&product_data.px_acc_, &price_account.key.to_bytes()), + ProgramError::InvalidArgument, + )?; + pyth_assert( + pubkey_equal(&price_data.prod_, &product_account.key.to_bytes()), + ProgramError::InvalidArgument, + )?; + pubkey_assign(&mut product_data.px_acc_, bytes_of(&price_data.next_)); + } + let lamports = price_account.lamports(); + **price_account.lamports.borrow_mut() = 0; + **funding_account.lamports.borrow_mut() += lamports; + Ok(()) + } + pub fn init_price( + program_id: &Pubkey, + accounts: &[AccountInfo], + instruction_data: &[u8], + ) -> ProgramResult { + let cmd_args = load::(instruction_data)?; + check_exponent_range(cmd_args.expo_)?; + let [funding_account, price_account] = match accounts { + [x, y] => Ok([x, y]), + _ => Err(ProgramError::InvalidArgument), + }?; + check_valid_funding_account(funding_account)?; + check_valid_signable_account(program_id, price_account, size_of::())?; + let mut price_data = load_checked::(price_account, cmd_args.ver_)?; + pyth_assert( + price_data.ptype_ == cmd_args.ptype_, + ProgramError::InvalidArgument, + )?; + price_data.expo_ = cmd_args.expo_; + price_data.last_slot_ = 0; + price_data.valid_slot_ = 0; + price_data.agg_.pub_slot_ = 0; + price_data.prev_slot_ = 0; + price_data.prev_price_ = 0; + price_data.prev_conf_ = 0; + price_data.prev_timestamp_ = 0; + sol_memset( + bytes_of_mut(&mut price_data.twap_), + 0, + size_of::(), + ); + sol_memset( + bytes_of_mut(&mut price_data.twac_), + 0, + size_of::(), + ); + sol_memset( + bytes_of_mut(&mut price_data.agg_), + 0, + size_of::(), + ); + for i in 0..(price_data.comp_.len() as usize) { + sol_memset( + bytes_of_mut(&mut price_data.comp_[i].agg_), + 0, + size_of::(), + ); + sol_memset( + bytes_of_mut(&mut price_data.comp_[i].latest_), + 0, + size_of::(), + ); + } + Ok(()) + } + /// add a publisher to a price account + /// accounts[0] funding account [signer writable] + /// accounts[1] price account to add the publisher to [signer writable] + pub fn add_publisher( + program_id: &Pubkey, + accounts: &[AccountInfo], + instruction_data: &[u8], + ) -> ProgramResult { + let cmd_args = load::(instruction_data)?; + pyth_assert( + instruction_data.len() == size_of::() + && !pubkey_is_zero(&cmd_args.pub_), + ProgramError::InvalidArgument, + )?; + let [funding_account, price_account] = match accounts { + [x, y] => Ok([x, y]), + _ => Err(ProgramError::InvalidArgument), + }?; + check_valid_funding_account(funding_account)?; + check_valid_signable_account(program_id, price_account, size_of::())?; + let mut price_data = load_checked::(price_account, cmd_args.ver_)?; + if price_data.num_ >= PC_COMP_SIZE { + return Err(ProgramError::InvalidArgument); + } + for i in 0..(price_data.num_ as usize) { + if pubkey_equal(&cmd_args.pub_, bytes_of(&price_data.comp_[i].pub_)) { + return Err(ProgramError::InvalidArgument); + } + } + let current_index: usize = try_convert(price_data.num_)?; + sol_memset( + bytes_of_mut(&mut price_data.comp_[current_index]), + 0, + size_of::(), + ); + pubkey_assign( + &mut price_data.comp_[current_index].pub_, + bytes_of(&cmd_args.pub_), + ); + price_data.num_ += 1; + price_data.size_ = + try_convert::<_, u32>(size_of::() - size_of_val(&price_data.comp_))? + + price_data.num_ * try_convert::<_, u32>(size_of::())?; + Ok(()) + } + /// add a publisher to a price account + /// accounts[0] funding account [signer writable] + /// accounts[1] price account to delete the publisher from [signer writable] + pub fn del_publisher( + program_id: &Pubkey, + accounts: &[AccountInfo], + instruction_data: &[u8], + ) -> ProgramResult { + let cmd_args = load::(instruction_data)?; + pyth_assert( + instruction_data.len() == size_of::() + && !pubkey_is_zero(&cmd_args.pub_), + ProgramError::InvalidArgument, + )?; + let [funding_account, price_account] = match accounts { + [x, y] => Ok([x, y]), + _ => Err(ProgramError::InvalidArgument), + }?; + check_valid_funding_account(funding_account)?; + check_valid_signable_account(program_id, price_account, size_of::())?; + let mut price_data = load_checked::(price_account, cmd_args.ver_)?; + for i in 0..(price_data.num_ as usize) { + if pubkey_equal(&cmd_args.pub_, bytes_of(&price_data.comp_[i].pub_)) { + for j in i + 1..(price_data.num_ as usize) { + price_data.comp_[j - 1] = price_data.comp_[j]; + } + price_data.num_ -= 1; + let current_index: usize = try_convert(price_data.num_)?; + sol_memset( + bytes_of_mut(&mut price_data.comp_[current_index]), + 0, + size_of::(), + ); + price_data.size_ = try_convert::<_, u32>( + size_of::() - size_of_val(&price_data.comp_), + )? + price_data.num_ + * try_convert::<_, u32>(size_of::())?; + return Ok(()); + } + } + Err(ProgramError::InvalidArgument) + } + pub fn add_product( + program_id: &Pubkey, + accounts: &[AccountInfo], + instruction_data: &[u8], + ) -> ProgramResult { + let [funding_account, tail_mapping_account, new_product_account] = match accounts { + [x, y, z] => Ok([x, y, z]), + _ => Err(ProgramError::InvalidArgument), + }?; + check_valid_funding_account(funding_account)?; + check_valid_signable_account( + program_id, + tail_mapping_account, + size_of::(), + )?; + check_valid_signable_account(program_id, new_product_account, PC_PROD_ACC_SIZE as usize)?; + check_valid_fresh_account(new_product_account)?; + let hdr = load::(instruction_data)?; + let mut mapping_data = load_checked::(tail_mapping_account, hdr.ver_)?; + pyth_assert( + mapping_data.num_ < PC_MAP_TABLE_SIZE, + ProgramError::InvalidArgument, + )?; + initialize_pyth_account_checked::(new_product_account, hdr.ver_)?; + let current_index: usize = try_convert(mapping_data.num_)?; + pubkey_assign( + &mut mapping_data.prod_[current_index], + bytes_of(&new_product_account.key.to_bytes()), + ); + mapping_data.num_ += 1; + mapping_data.size_ = + try_convert::<_, u32>(size_of::() - size_of_val(&mapping_data.prod_))? + + mapping_data.num_ * try_convert::<_, u32>(size_of::())?; + Ok(()) + } + /// Update the metadata associated with a product, overwriting any existing metadata. + /// The metadata is provided as a list of key-value pairs at the end of the `instruction_data`. + pub fn upd_product( + program_id: &Pubkey, + accounts: &[AccountInfo], + instruction_data: &[u8], + ) -> ProgramResult { + let [funding_account, product_account] = match accounts { + [x, y] => Ok([x, y]), + _ => Err(ProgramError::InvalidArgument), + }?; + check_valid_funding_account(funding_account)?; + check_valid_signable_account(program_id, product_account, try_convert(PC_PROD_ACC_SIZE)?)?; + let hdr = load::(instruction_data)?; + { + let mut _product_data = load_checked::(product_account, hdr.ver_)?; + } + pyth_assert( + instruction_data.len() >= size_of::(), + ProgramError::InvalidInstructionData, + )?; + let new_data_len = instruction_data.len() - size_of::(); + let max_data_len = try_convert::<_, usize>(PC_PROD_ACC_SIZE)? - size_of::(); + pyth_assert(new_data_len <= max_data_len, ProgramError::InvalidArgument)?; + let new_data = &instruction_data[size_of::()..instruction_data.len()]; + let mut idx = 0; + while idx < new_data.len() { + let key = read_pc_str_t(&new_data[idx..])?; + idx += key.len(); + let value = read_pc_str_t(&new_data[idx..])?; + idx += value.len(); + } + pyth_assert(idx == new_data.len(), ProgramError::InvalidArgument)?; + { + let mut data = product_account.try_borrow_mut_data()?; + sol_memcpy( + &mut data[size_of::()..], + new_data, + new_data.len(), + ); + } + let mut product_data = load_checked::(product_account, hdr.ver_)?; + product_data.size_ = try_convert(size_of::() + new_data.len())?; + Ok(()) + } + pub fn set_min_pub( + program_id: &Pubkey, + accounts: &[AccountInfo], + instruction_data: &[u8], + ) -> ProgramResult { + let cmd = load::(instruction_data)?; + pyth_assert( + instruction_data.len() == size_of::(), + ProgramError::InvalidArgument, + )?; + let [funding_account, price_account] = match accounts { + [x, y] => Ok([x, y]), + _ => Err(ProgramError::InvalidArgument), + }?; + check_valid_funding_account(funding_account)?; + check_valid_signable_account(program_id, price_account, size_of::())?; + let mut price_account_data = load_checked::(price_account, cmd.ver_)?; + price_account_data.min_pub_ = cmd.min_pub_; + Ok(()) + } +} +mod time_machine_types { + use crate::c_oracle_header::{ + pc_price_t, PythAccount, EXTRA_PUBLISHER_SPACE, PC_ACCTYPE_PRICE, PC_PRICE_T_COMP_OFFSET, + }; + use crate::error::OracleError; + use bytemuck::{Pod, Zeroable}; + use solana_program::msg; + #[repr(C)] + /// this wraps multiple SMA and tick trackers, and includes all the state + /// used by the time machine + pub struct TimeMachineWrapper { + place_holder: [u8; 1864], + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for TimeMachineWrapper { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self { + Self { + place_holder: ref __self_0_0, + } => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "TimeMachineWrapper"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "place_holder", + &&(*__self_0_0), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for TimeMachineWrapper { + #[inline] + fn clone(&self) -> TimeMachineWrapper { + { + let _: ::core::clone::AssertParamIsClone<[u8; 1864]>; + *self + } + } + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for TimeMachineWrapper {} + #[repr(C)] + /// wraps everything stored in a price account + pub struct PriceAccountWrapper { + pub price_data: pc_price_t, + pub extra_publisher_space: [u8; EXTRA_PUBLISHER_SPACE as usize], + pub time_machine: TimeMachineWrapper, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::marker::Copy for PriceAccountWrapper {} + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::clone::Clone for PriceAccountWrapper { + #[inline] + fn clone(&self) -> PriceAccountWrapper { + { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone<[u8; EXTRA_PUBLISHER_SPACE as usize]>; + let _: ::core::clone::AssertParamIsClone; + *self + } + } + } + impl PriceAccountWrapper { + pub fn initialize_time_machine(&mut self) -> Result<(), OracleError> { + ::solana_program::log::sol_log("implement me"); + Ok(()) + } + pub fn add_price_to_time_machine(&mut self) -> Result<(), OracleError> { + ::solana_program::log::sol_log("implement me"); + Ok(()) + } + } + #[cfg(target_endian = "little")] + unsafe impl Zeroable for PriceAccountWrapper {} + #[cfg(target_endian = "little")] + unsafe impl Pod for PriceAccountWrapper {} + impl PythAccount for PriceAccountWrapper { + const ACCOUNT_TYPE: u32 = PC_ACCTYPE_PRICE; + const INITIAL_SIZE: u32 = PC_PRICE_T_COMP_OFFSET as u32; + } +} +mod instruction { + use num_derive::FromPrimitive; + #[repr(i32)] + pub enum OracleCommand { + InitMapping, + AddMapping, + AddProduct, + UpdProduct, + AddPrice, + AddPublisher, + DelPublisher, + UpdPrice, + AggPrice, + InitPrice, + InitTest, + UpdTest, + SetMinPub, + UpdPriceNoFailOnError, + ResizePriceAccount, + DelPrice, + } + #[allow(non_upper_case_globals, unused_qualifications)] + const _IMPL_NUM_FromPrimitive_FOR_OracleCommand: () = { + #[allow(clippy::useless_attribute)] + #[allow(rust_2018_idioms)] + extern crate num_traits as _num_traits; + impl _num_traits::FromPrimitive for OracleCommand { + #[allow(trivial_numeric_casts)] + #[inline] + fn from_i64(n: i64) -> Option { + if n == OracleCommand::InitMapping as i64 { + Some(OracleCommand::InitMapping) + } else if n == OracleCommand::AddMapping as i64 { + Some(OracleCommand::AddMapping) + } else if n == OracleCommand::AddProduct as i64 { + Some(OracleCommand::AddProduct) + } else if n == OracleCommand::UpdProduct as i64 { + Some(OracleCommand::UpdProduct) + } else if n == OracleCommand::AddPrice as i64 { + Some(OracleCommand::AddPrice) + } else if n == OracleCommand::AddPublisher as i64 { + Some(OracleCommand::AddPublisher) + } else if n == OracleCommand::DelPublisher as i64 { + Some(OracleCommand::DelPublisher) + } else if n == OracleCommand::UpdPrice as i64 { + Some(OracleCommand::UpdPrice) + } else if n == OracleCommand::AggPrice as i64 { + Some(OracleCommand::AggPrice) + } else if n == OracleCommand::InitPrice as i64 { + Some(OracleCommand::InitPrice) + } else if n == OracleCommand::InitTest as i64 { + Some(OracleCommand::InitTest) + } else if n == OracleCommand::UpdTest as i64 { + Some(OracleCommand::UpdTest) + } else if n == OracleCommand::SetMinPub as i64 { + Some(OracleCommand::SetMinPub) + } else if n == OracleCommand::UpdPriceNoFailOnError as i64 { + Some(OracleCommand::UpdPriceNoFailOnError) + } else if n == OracleCommand::ResizePriceAccount as i64 { + Some(OracleCommand::ResizePriceAccount) + } else if n == OracleCommand::DelPrice as i64 { + Some(OracleCommand::DelPrice) + } else { + None + } + } + #[inline] + fn from_u64(n: u64) -> Option { + Self::from_i64(n as i64) + } + } + }; +} +mod utils { + use crate::c_oracle_header::{ + cmd_upd_price_t, command_t_e_cmd_upd_price, command_t_e_cmd_upd_price_no_fail_on_error, + pc_acc, pc_pub_key_t, PC_MAX_NUM_DECIMALS, + }; + use crate::deserialize::load_account_as; + use crate::OracleError; + use solana_program::account_info::AccountInfo; + use solana_program::program_error::ProgramError; + use solana_program::program_memory::sol_memset; + use solana_program::pubkey::Pubkey; + use solana_program::sysvar::rent::Rent; + use std::borrow::BorrowMut; + pub fn pyth_assert(condition: bool, error_code: ProgramError) -> Result<(), ProgramError> { + if !condition { + Result::Err(error_code) + } else { + Result::Ok(()) + } + } + /// Sets the data of account to all-zero + pub 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(()) + } + pub fn valid_funding_account(account: &AccountInfo) -> bool { + account.is_signer && account.is_writable + } + pub fn check_valid_funding_account(account: &AccountInfo) -> Result<(), ProgramError> { + pyth_assert( + valid_funding_account(account), + OracleError::InvalidFundingAccount.into(), + ) + } + 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()) + } + pub fn check_valid_signable_account( + program_id: &Pubkey, + account: &AccountInfo, + minimum_size: usize, + ) -> Result<(), ProgramError> { + pyth_assert( + valid_signable_account(program_id, account, minimum_size), + OracleError::InvalidSignableAccount.into(), + ) + } + /// 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. + pub 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, + } + } + pub fn check_valid_fresh_account(account: &AccountInfo) -> Result<(), ProgramError> { + pyth_assert( + valid_fresh_account(account), + OracleError::InvalidFreshAccount.into(), + ) + } + pub fn check_exponent_range(expo: i32) -> Result<(), ProgramError> { + pyth_assert( + expo >= -(PC_MAX_NUM_DECIMALS as i32) && expo <= PC_MAX_NUM_DECIMALS as i32, + ProgramError::InvalidArgument, + ) + } + pub fn pubkey_assign(target: &mut pc_pub_key_t, source: &[u8]) { + unsafe { target.k1_.copy_from_slice(source) } + } + pub fn pubkey_is_zero(key: &pc_pub_key_t) -> bool { + return unsafe { key.k8_.iter().all(|x| *x == 0) }; + } + pub fn pubkey_equal(target: &pc_pub_key_t, source: &[u8]) -> bool { + unsafe { target.k1_ == *source } + } + /// Convert `x: T` into a `U`, returning the appropriate `OracleError` if the conversion fails. + pub fn try_convert>(x: T) -> Result { + U::try_from(x).map_err(|_| OracleError::IntegerCastingError) + } + /// Read a `pc_str_t` from the beginning of `source`. Returns a slice of `source` containing + /// the bytes of the `pc_str_t`. + pub fn read_pc_str_t(source: &[u8]) -> Result<&[u8], ProgramError> { + if source.is_empty() { + Err(ProgramError::InvalidArgument) + } else { + let tag_len: usize = try_convert(source[0])?; + if tag_len + 1 > source.len() { + Err(ProgramError::InvalidArgument) + } else { + Ok(&source[..(1 + tag_len)]) + } + } + } + fn valid_writable_account( + program_id: &Pubkey, + account: &AccountInfo, + minimum_size: usize, + ) -> bool { + account.is_writable + && account.owner == program_id + && account.data_len() >= minimum_size + && Rent::default().is_exempt(account.lamports(), account.data_len()) + } + pub fn check_valid_writable_account( + program_id: &Pubkey, + account: &AccountInfo, + minimum_size: usize, + ) -> Result<(), ProgramError> { + pyth_assert( + valid_writable_account(program_id, account, minimum_size), + OracleError::InvalidWritableAccount.into(), + ) + } + /// Checks whether this instruction is trying to update an individual publisher's price (`true`) or + /// is only trying to refresh the aggregate (`false`) + pub fn is_component_update(cmd_args: &cmd_upd_price_t) -> Result { + Ok( + try_convert::<_, u32>(cmd_args.cmd_)? == command_t_e_cmd_upd_price + || try_convert::<_, u32>(cmd_args.cmd_)? + == command_t_e_cmd_upd_price_no_fail_on_error, + ) + } +} +use crate::error::OracleError; +use processor::process_instruction; +use solana_program::entrypoint; +/// # Safety +#[no_mangle] +pub unsafe extern "C" fn entrypoint(input: *mut u8) -> u64 { + let (program_id, accounts, instruction_data) = + unsafe { ::solana_program::entrypoint::deserialize(input) }; + match process_instruction(&program_id, &accounts, &instruction_data) { + Ok(()) => ::solana_program::entrypoint::SUCCESS, + Err(error) => error.into(), + } +} diff --git a/program/rust/output.rscargo b/program/rust/output.rscargo new file mode 100644 index 000000000..e69de29bb diff --git a/program/rust/src/deserialize.rs b/program/rust/src/deserialize.rs index 142529d04..706f6ee5d 100644 --- a/program/rust/src/deserialize.rs +++ b/program/rust/src/deserialize.rs @@ -23,6 +23,9 @@ use std::cell::{ }; /// Interpret the bytes in `data` as a value of type `T` +/// This will fail if : +/// - `data` is too short +/// - `data` is not aligned for T pub fn load(data: &[u8]) -> Result<&T, ProgramError> { try_from_bytes( data.get(0..size_of::()) diff --git a/program/rust/src/instruction.rs b/program/rust/src/instruction.rs new file mode 100644 index 000000000..79d93b791 --- /dev/null +++ b/program/rust/src/instruction.rs @@ -0,0 +1,73 @@ +use num_derive::FromPrimitive; +#[repr(i32)] +#[derive(FromPrimitive)] +pub enum OracleCommand { + // initialize first mapping list account + // account[0] funding account [signer writable] + // account[1] mapping account [signer writable] + InitMapping, + // initialize and add new mapping account + // account[0] funding account [signer writable] + // account[1] tail mapping account [signer writable] + // account[2] new mapping account [signer writable] + AddMapping, + // initialize and add new product reference data account + // account[0] funding account [signer writable] + // account[1] mapping account [signer writable] + // account[2] new product account [signer writable] + AddProduct, + // update product account + // account[0] funding account [signer writable] + // account[1] product account [signer writable] + UpdProduct, + // add new price account to a product account + // account[0] funding account [signer writable] + // account[1] product account [signer writable] + // account[2] new price account [signer writable] + AddPrice, + // add publisher to symbol account + // account[0] funding account [signer writable] + // account[1] price account [signer writable] + AddPublisher, + // delete publisher from symbol account + // account[0] funding account [signer writable] + // account[1] price account [signer writable] + DelPublisher, + // publish component price + // account[0] funding account [signer writable] + // account[1] price account [writable] + // account[2] sysvar_clock account [] + UpdPrice, + // compute aggregate price + // account[0] funding account [signer writable] + // account[1] price account [writable] + // account[2] sysvar_clock account [] + AggPrice, + // (re)initialize price account + // account[0] funding account [signer writable] + // account[1] new price account [signer writable] + InitPrice, + // deprecated + InitTest, + // deprecated + UpdTest, + // set min publishers + // account[0] funding account [signer writable] + // account[1] price account [signer writable] + SetMinPub, + // publish component price, never returning an error even if the update failed + // account[0] funding account [signer writable] + // account[1] price account [writable] + // account[2] sysvar_clock account [] + UpdPriceNoFailOnError, + // resizes a price account so that it fits the Time Machine + // account[0] funding account [signer writable] + // account[1] price account [signer writable] + // account[2] system program [] + ResizePriceAccount, + // deletes a price account + // account[0] funding account [signer writable] + // account[1] product account [signer writable] + // account[2] price account [signer writable] + DelPrice +} \ No newline at end of file diff --git a/program/rust/src/lib.rs b/program/rust/src/lib.rs index 424d00eee..135faecf8 100644 --- a/program/rust/src/lib.rs +++ b/program/rust/src/lib.rs @@ -10,6 +10,7 @@ mod error; mod processor; mod rust_oracle; mod time_machine_types; +mod instruction; mod utils; #[cfg(test)] diff --git a/program/rust/src/processor.rs b/program/rust/src/processor.rs index 595f1e915..16362af71 100644 --- a/program/rust/src/processor.rs +++ b/program/rust/src/processor.rs @@ -1,21 +1,9 @@ use crate::c_oracle_header::{ cmd_hdr, - command_t_e_cmd_add_mapping, - command_t_e_cmd_add_price, - command_t_e_cmd_add_product, - command_t_e_cmd_add_publisher, - command_t_e_cmd_agg_price, - command_t_e_cmd_del_price, - command_t_e_cmd_del_publisher, - command_t_e_cmd_init_mapping, - command_t_e_cmd_init_price, - command_t_e_cmd_resize_price_account, - command_t_e_cmd_set_min_pub, - command_t_e_cmd_upd_price, - command_t_e_cmd_upd_price_no_fail_on_error, - command_t_e_cmd_upd_product, PC_VERSION, }; + +use crate::instruction::OracleCommand; use crate::deserialize::load; use crate::error::OracleError; use solana_program::entrypoint::ProgramResult; @@ -38,6 +26,7 @@ use crate::rust_oracle::{ upd_price_no_fail_on_error, upd_product, }; +use num_traits::FromPrimitive; ///dispatch to the right instruction in the oracle pub fn process_instruction( @@ -51,30 +40,24 @@ pub fn process_instruction( return Err(ProgramError::InvalidArgument); } - match cmd_data - .cmd_ - .try_into() - .map_err(|_| OracleError::IntegerCastingError)? + match OracleCommand::from_i32(cmd_data.cmd_).ok_or(OracleError::UnrecognizedInstruction)? { - command_t_e_cmd_upd_price | command_t_e_cmd_agg_price => { - upd_price(program_id, accounts, instruction_data) - } - command_t_e_cmd_upd_price_no_fail_on_error => { - upd_price_no_fail_on_error(program_id, accounts, instruction_data) - } - command_t_e_cmd_resize_price_account => { - resize_price_account(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), - command_t_e_cmd_init_price => init_price(program_id, accounts, instruction_data), - command_t_e_cmd_add_mapping => add_mapping(program_id, accounts, instruction_data), - command_t_e_cmd_add_publisher => add_publisher(program_id, accounts, instruction_data), - command_t_e_cmd_del_publisher => del_publisher(program_id, accounts, instruction_data), - command_t_e_cmd_add_product => add_product(program_id, accounts, instruction_data), - command_t_e_cmd_upd_product => upd_product(program_id, accounts, instruction_data), - command_t_e_cmd_set_min_pub => set_min_pub(program_id, accounts, instruction_data), - command_t_e_cmd_del_price => del_price(program_id, accounts, instruction_data), - _ => Err(OracleError::UnrecognizedInstruction.into()), + OracleCommand::InitMapping => init_mapping(program_id, accounts, instruction_data), + OracleCommand::AddMapping => add_mapping(program_id, accounts, instruction_data), + OracleCommand::AddProduct => add_product(program_id, accounts, instruction_data), + OracleCommand::UpdProduct => upd_product(program_id, accounts, instruction_data), + OracleCommand::AddPrice => add_price(program_id, accounts, instruction_data), + OracleCommand::AddPublisher => add_publisher(program_id, accounts, instruction_data), + OracleCommand::DelPublisher => del_publisher(program_id, accounts, instruction_data), + OracleCommand::UpdPrice => upd_price(program_id, accounts, instruction_data), + OracleCommand::AggPrice => upd_price(program_id, accounts, instruction_data), + OracleCommand::InitPrice => init_price(program_id, accounts, instruction_data), + OracleCommand::InitTest => Err(OracleError::UnrecognizedInstruction.into()), + OracleCommand::UpdTest => Err(OracleError::UnrecognizedInstruction.into()), + OracleCommand::SetMinPub => set_min_pub(program_id, accounts, instruction_data), + OracleCommand::UpdPriceNoFailOnError => upd_price_no_fail_on_error(program_id, accounts, instruction_data), + OracleCommand::ResizePriceAccount => resize_price_account(program_id, accounts, instruction_data), + OracleCommand::DelPrice => del_price(program_id, accounts, instruction_data) + } } diff --git a/program/rust/src/tests/test_add_mapping.rs b/program/rust/src/tests/test_add_mapping.rs index fae1407b7..867510f57 100644 --- a/program/rust/src/tests/test_add_mapping.rs +++ b/program/rust/src/tests/test_add_mapping.rs @@ -1,6 +1,5 @@ use crate::c_oracle_header::{ cmd_hdr_t, - command_t_e_cmd_add_mapping, pc_map_table_t, PC_MAGIC, PC_MAP_TABLE_SIZE, @@ -11,8 +10,7 @@ use crate::deserialize::{ load_account_as_mut, load_checked, }; - -use crate::rust_oracle::add_mapping; +use crate::processor::process_instruction; use crate::tests::test_utils::AccountSetup; use crate::utils::{ clear_account, @@ -20,6 +18,7 @@ use crate::utils::{ pubkey_equal, pubkey_is_zero, }; +use crate::instruction::OracleCommand; use bytemuck::bytes_of; use solana_program::program_error::ProgramError; use solana_program::pubkey::Pubkey; @@ -28,7 +27,7 @@ use solana_program::pubkey::Pubkey; fn test_add_mapping() { let hdr: cmd_hdr_t = cmd_hdr_t { ver_: PC_VERSION, - cmd_: command_t_e_cmd_add_mapping as i32, + cmd_: OracleCommand::AddMapping as i32, }; let instruction_data = bytes_of::(&hdr); @@ -50,7 +49,7 @@ fn test_add_mapping() { cur_mapping_data.num_ = PC_MAP_TABLE_SIZE; } - assert!(add_mapping( + assert!(process_instruction( &program_id, &[ funding_account.clone(), @@ -78,7 +77,7 @@ fn test_add_mapping() { clear_account(&next_mapping).unwrap(); assert_eq!( - add_mapping( + process_instruction( &program_id, &[ funding_account.clone(), @@ -99,7 +98,7 @@ fn test_add_mapping() { } assert_eq!( - add_mapping( + process_instruction( &program_id, &[ funding_account.clone(), @@ -116,7 +115,7 @@ fn test_add_mapping() { cur_mapping_data.magic_ = PC_MAGIC; } - assert!(add_mapping( + assert!(process_instruction( &program_id, &[ funding_account.clone(), diff --git a/program/rust/src/tests/test_init_mapping.rs b/program/rust/src/tests/test_init_mapping.rs index 88497921b..3b3e0743f 100644 --- a/program/rust/src/tests/test_init_mapping.rs +++ b/program/rust/src/tests/test_init_mapping.rs @@ -6,9 +6,9 @@ use crate::c_oracle_header::{ PC_MAGIC, PC_VERSION, }; +use crate::processor::process_instruction; use crate::deserialize::load_account_as; use crate::error::OracleError; -use crate::rust_oracle::init_mapping; use crate::tests::test_utils::AccountSetup; use crate::utils::clear_account; use bytemuck::bytes_of; @@ -34,7 +34,7 @@ fn test_init_mapping() { let mut mapping_setup = AccountSetup::new::(&program_id); let mut mapping_account = mapping_setup.to_account_info(); - assert!(init_mapping( + assert!(process_instruction( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data @@ -51,7 +51,7 @@ fn test_init_mapping() { } assert_eq!( - init_mapping( + process_instruction( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data @@ -62,14 +62,14 @@ fn test_init_mapping() { clear_account(&mapping_account).unwrap(); assert_eq!( - init_mapping(&program_id, &[funding_account.clone()], instruction_data), + process_instruction(&program_id, &[funding_account.clone()], instruction_data), Err(ProgramError::InvalidArgument) ); funding_account.is_signer = false; assert_eq!( - init_mapping( + process_instruction( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data @@ -81,7 +81,7 @@ fn test_init_mapping() { mapping_account.is_signer = false; assert_eq!( - init_mapping( + process_instruction( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data @@ -93,7 +93,7 @@ fn test_init_mapping() { funding_account.is_writable = false; assert_eq!( - init_mapping( + process_instruction( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data @@ -105,7 +105,7 @@ fn test_init_mapping() { mapping_account.is_writable = false; assert_eq!( - init_mapping( + process_instruction( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data @@ -117,7 +117,7 @@ fn test_init_mapping() { mapping_account.owner = &program_id_2; assert_eq!( - init_mapping( + process_instruction( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data @@ -130,7 +130,7 @@ fn test_init_mapping() { mapping_account.data = Rc::new(RefCell::new(&mut [])); assert_eq!( - init_mapping( + process_instruction( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data @@ -140,7 +140,7 @@ fn test_init_mapping() { mapping_account.data = prev_data; - assert!(init_mapping( + assert!(process_instruction( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data From 355bca06d9f5dbec61574815a4d3855f5cd089db Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Alapont Date: Mon, 22 Aug 2022 13:53:56 -0500 Subject: [PATCH 2/8] Cleanup entrypoint: --- program/rust/src/deserialize.rs | 13 +++++++------ program/rust/src/error.rs | 6 ++++++ program/rust/src/instruction.rs | 25 +++++++++++++++++++++++-- program/rust/src/lib.rs | 2 +- program/rust/src/processor.rs | 9 ++------- program/rust/src/tests/test_utils.rs | 13 ++++++++++++- 6 files changed, 51 insertions(+), 17 deletions(-) diff --git a/program/rust/src/deserialize.rs b/program/rust/src/deserialize.rs index 706f6ee5d..7517f72e2 100644 --- a/program/rust/src/deserialize.rs +++ b/program/rust/src/deserialize.rs @@ -11,6 +11,7 @@ use crate::c_oracle_header::{ PythAccount, PC_MAGIC, }; +use crate::error::OracleError; use crate::utils::{ clear_account, pyth_assert, @@ -26,22 +27,22 @@ use std::cell::{ /// This will fail if : /// - `data` is too short /// - `data` is not aligned for T -pub fn load(data: &[u8]) -> Result<&T, ProgramError> { +pub fn load(data: &[u8]) -> Result<&T, OracleError> { try_from_bytes( data.get(0..size_of::()) - .ok_or(ProgramError::InvalidArgument)?, + .ok_or(OracleError::InstructionDataTooShort)?, ) - .map_err(|_| ProgramError::InvalidArgument) + .map_err(|_| OracleError::InstructionDataSliceMisaligned) } /// Interpret the bytes in `data` as a mutable value of type `T` #[allow(unused)] -pub fn load_mut(data: &mut [u8]) -> Result<&mut T, ProgramError> { +pub fn load_mut(data: &mut [u8]) -> Result<&mut T, OracleError> { try_from_bytes_mut( data.get_mut(0..size_of::()) - .ok_or(ProgramError::InvalidArgument)?, + .ok_or(OracleError::InstructionDataTooShort)?, ) - .map_err(|_| ProgramError::InvalidArgument) + .map_err(|_| OracleError::InstructionDataSliceMisaligned) } /// Get the data stored in `account` as a value of type `T` diff --git a/program/rust/src/error.rs b/program/rust/src/error.rs index 91d9f9b71..ad7331a08 100644 --- a/program/rust/src/error.rs +++ b/program/rust/src/error.rs @@ -26,6 +26,12 @@ pub enum OracleError { InvalidWritableAccount = 607, #[error("InvalidFreshAccount")] InvalidFreshAccount = 608, + #[error("InvalidInstructionVersion")] + InvalidInstructionVersion = 609, + #[error("InstructionDataTooShort")] + InstructionDataTooShort = 610, + #[error("InstructionDataSliceMisaligned")] + InstructionDataSliceMisaligned = 611, } impl From for ProgramError { diff --git a/program/rust/src/instruction.rs b/program/rust/src/instruction.rs index 79d93b791..0b52d1359 100644 --- a/program/rust/src/instruction.rs +++ b/program/rust/src/instruction.rs @@ -1,6 +1,11 @@ -use num_derive::FromPrimitive; +use bytemuck::{Zeroable, Pod}; +use crate::{deserialize::load, error::OracleError}; +use num_derive::{FromPrimitive, ToPrimitive}; +use crate::c_oracle_header::PC_VERSION; +use num_traits::FromPrimitive; + #[repr(i32)] -#[derive(FromPrimitive)] +#[derive(FromPrimitive, ToPrimitive)] pub enum OracleCommand { // initialize first mapping list account // account[0] funding account [signer writable] @@ -70,4 +75,20 @@ pub enum OracleCommand { // account[1] product account [signer writable] // account[2] price account [signer writable] DelPrice +} + +#[repr(C)] +#[derive(Zeroable, Pod, Copy, Clone)] +pub struct CommandHeader{ + pub version : u32, + pub command : i32 +} + +pub fn load_command_header_checked(data : &[u8]) -> Result{ + let command_header = load::(data)?; + + if command_header.version != PC_VERSION { + return Err(OracleError::InvalidInstructionVersion); + } + OracleCommand::from_i32(command_header.command).ok_or(OracleError::UnrecognizedInstruction) } \ No newline at end of file diff --git a/program/rust/src/lib.rs b/program/rust/src/lib.rs index 135faecf8..665800427 100644 --- a/program/rust/src/lib.rs +++ b/program/rust/src/lib.rs @@ -1,4 +1,4 @@ -#![deny(warnings)] +// #![deny(warnings)] // Allow non upper case globals from C #![allow(non_upper_case_globals)] // Allow using the solana_program::entrypoint::deserialize function diff --git a/program/rust/src/processor.rs b/program/rust/src/processor.rs index 16362af71..dc5c0046c 100644 --- a/program/rust/src/processor.rs +++ b/program/rust/src/processor.rs @@ -3,7 +3,7 @@ use crate::c_oracle_header::{ PC_VERSION, }; -use crate::instruction::OracleCommand; +use crate::instruction::{OracleCommand, load_command_header_checked}; use crate::deserialize::load; use crate::error::OracleError; use solana_program::entrypoint::ProgramResult; @@ -34,13 +34,8 @@ pub fn process_instruction( accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { - let cmd_data = load::(instruction_data)?; - if cmd_data.ver_ != PC_VERSION { - return Err(ProgramError::InvalidArgument); - } - - match OracleCommand::from_i32(cmd_data.cmd_).ok_or(OracleError::UnrecognizedInstruction)? + match load_command_header_checked(instruction_data)? { OracleCommand::InitMapping => init_mapping(program_id, accounts, instruction_data), OracleCommand::AddMapping => add_mapping(program_id, accounts, instruction_data), diff --git a/program/rust/src/tests/test_utils.rs b/program/rust/src/tests/test_utils.rs index ed04fc90a..88552e89b 100644 --- a/program/rust/src/tests/test_utils.rs +++ b/program/rust/src/tests/test_utils.rs @@ -8,12 +8,14 @@ use solana_program::sysvar::{ Sysvar, SysvarId, }; +use crate::c_oracle_header::PC_VERSION; use solana_program::{ clock, system_program, sysvar, }; - +use crate::instruction::{OracleCommand, CommandHeader}; +use num_traits::ToPrimitive; const UPPER_BOUND_OF_ALL_ACCOUNT_SIZES: usize = 20536; /// The goal of this struct is to easily instantiate fresh solana accounts @@ -97,3 +99,12 @@ pub fn update_clock_slot(clock_account: &mut AccountInfo, slot: u64) { clock_data.slot = slot; clock_data.to_account_info(clock_account); } + +impl Into for OracleCommand { + fn into(self) -> CommandHeader{ + return CommandHeader { + version : PC_VERSION, + command : self.to_i32().unwrap(), // This can never fail + } + } +} \ No newline at end of file From e9ff9ebc5f135a36a4bca5b6156accdde133acda Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Alapont Date: Mon, 22 Aug 2022 14:01:18 -0500 Subject: [PATCH 3/8] Format --- program/rust/src/error.rs | 24 +++++++++--------- program/rust/src/instruction.rs | 25 +++++++++++------- program/rust/src/lib.rs | 4 +-- program/rust/src/processor.rs | 28 +++++++++------------ program/rust/src/rust_oracle.rs | 3 +-- program/rust/src/tests/test_add_mapping.rs | 2 +- program/rust/src/tests/test_init_mapping.rs | 2 +- program/rust/src/tests/test_utils.rs | 23 ++++++++++------- 8 files changed, 59 insertions(+), 52 deletions(-) diff --git a/program/rust/src/error.rs b/program/rust/src/error.rs index ad7331a08..890b90285 100644 --- a/program/rust/src/error.rs +++ b/program/rust/src/error.rs @@ -7,31 +7,31 @@ use thiserror::Error; pub enum OracleError { /// Generic catch all error #[error("Generic")] - Generic = 600, + Generic = 600, /// integer casting error #[error("IntegerCastingError")] - IntegerCastingError = 601, + IntegerCastingError = 601, /// c_entrypoint returned an unexpected value #[error("UnknownCError")] - UnknownCError = 602, + UnknownCError = 602, #[error("UnrecognizedInstruction")] - UnrecognizedInstruction = 603, + UnrecognizedInstruction = 603, #[error("InvalidFundingAccount")] - InvalidFundingAccount = 604, + InvalidFundingAccount = 604, #[error("InvalidSignableAccount")] - InvalidSignableAccount = 605, + InvalidSignableAccount = 605, #[error("InvalidSystemAccount")] - InvalidSystemAccount = 606, + InvalidSystemAccount = 606, #[error("InvalidWritableAccount")] - InvalidWritableAccount = 607, + InvalidWritableAccount = 607, #[error("InvalidFreshAccount")] - InvalidFreshAccount = 608, + InvalidFreshAccount = 608, #[error("InvalidInstructionVersion")] - InvalidInstructionVersion = 609, + InvalidInstructionVersion = 609, #[error("InstructionDataTooShort")] - InstructionDataTooShort = 610, + InstructionDataTooShort = 610, #[error("InstructionDataSliceMisaligned")] - InstructionDataSliceMisaligned = 611, + InstructionDataSliceMisaligned = 611, } impl From for ProgramError { diff --git a/program/rust/src/instruction.rs b/program/rust/src/instruction.rs index 0b52d1359..f5ea4cca1 100644 --- a/program/rust/src/instruction.rs +++ b/program/rust/src/instruction.rs @@ -1,7 +1,14 @@ -use bytemuck::{Zeroable, Pod}; -use crate::{deserialize::load, error::OracleError}; -use num_derive::{FromPrimitive, ToPrimitive}; use crate::c_oracle_header::PC_VERSION; +use crate::deserialize::load; +use crate::error::OracleError; +use bytemuck::{ + Pod, + Zeroable, +}; +use num_derive::{ + FromPrimitive, + ToPrimitive, +}; use num_traits::FromPrimitive; #[repr(i32)] @@ -74,21 +81,21 @@ pub enum OracleCommand { // account[0] funding account [signer writable] // account[1] product account [signer writable] // account[2] price account [signer writable] - DelPrice + DelPrice, } #[repr(C)] #[derive(Zeroable, Pod, Copy, Clone)] -pub struct CommandHeader{ - pub version : u32, - pub command : i32 +pub struct CommandHeader { + pub version: u32, + pub command: i32, } -pub fn load_command_header_checked(data : &[u8]) -> Result{ +pub fn load_command_header_checked(data: &[u8]) -> Result { let command_header = load::(data)?; if command_header.version != PC_VERSION { return Err(OracleError::InvalidInstructionVersion); } OracleCommand::from_i32(command_header.command).ok_or(OracleError::UnrecognizedInstruction) -} \ No newline at end of file +} diff --git a/program/rust/src/lib.rs b/program/rust/src/lib.rs index 665800427..544457554 100644 --- a/program/rust/src/lib.rs +++ b/program/rust/src/lib.rs @@ -1,4 +1,4 @@ -// #![deny(warnings)] +#![deny(warnings)] // Allow non upper case globals from C #![allow(non_upper_case_globals)] // Allow using the solana_program::entrypoint::deserialize function @@ -7,10 +7,10 @@ mod c_oracle_header; mod deserialize; mod error; +mod instruction; mod processor; mod rust_oracle; mod time_machine_types; -mod instruction; mod utils; #[cfg(test)] diff --git a/program/rust/src/processor.rs b/program/rust/src/processor.rs index dc5c0046c..65cc0c77f 100644 --- a/program/rust/src/processor.rs +++ b/program/rust/src/processor.rs @@ -1,13 +1,9 @@ -use crate::c_oracle_header::{ - cmd_hdr, - PC_VERSION, -}; - -use crate::instruction::{OracleCommand, load_command_header_checked}; -use crate::deserialize::load; use crate::error::OracleError; +use crate::instruction::{ + load_command_header_checked, + OracleCommand, +}; use solana_program::entrypoint::ProgramResult; -use solana_program::program_error::ProgramError; use solana_program::pubkey::Pubkey; use solana_program::sysvar::slot_history::AccountInfo; @@ -26,7 +22,6 @@ use crate::rust_oracle::{ upd_price_no_fail_on_error, upd_product, }; -use num_traits::FromPrimitive; ///dispatch to the right instruction in the oracle pub fn process_instruction( @@ -34,9 +29,7 @@ pub fn process_instruction( accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { - - match load_command_header_checked(instruction_data)? - { + match load_command_header_checked(instruction_data)? { OracleCommand::InitMapping => init_mapping(program_id, accounts, instruction_data), OracleCommand::AddMapping => add_mapping(program_id, accounts, instruction_data), OracleCommand::AddProduct => add_product(program_id, accounts, instruction_data), @@ -50,9 +43,12 @@ pub fn process_instruction( OracleCommand::InitTest => Err(OracleError::UnrecognizedInstruction.into()), OracleCommand::UpdTest => Err(OracleError::UnrecognizedInstruction.into()), OracleCommand::SetMinPub => set_min_pub(program_id, accounts, instruction_data), - OracleCommand::UpdPriceNoFailOnError => upd_price_no_fail_on_error(program_id, accounts, instruction_data), - OracleCommand::ResizePriceAccount => resize_price_account(program_id, accounts, instruction_data), - OracleCommand::DelPrice => del_price(program_id, accounts, instruction_data) - + OracleCommand::UpdPriceNoFailOnError => { + upd_price_no_fail_on_error(program_id, accounts, instruction_data) + } + OracleCommand::ResizePriceAccount => { + resize_price_account(program_id, accounts, instruction_data) + } + OracleCommand::DelPrice => del_price(program_id, accounts, instruction_data), } } diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 3bf306b1e..18c8ec3d0 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -47,8 +47,7 @@ use crate::c_oracle_header::{ PC_VERSION, }; use crate::deserialize::{ - initialize_pyth_account_checked, /* TODO: This has a confusingly similar name to a Solana - * sdk function */ + initialize_pyth_account_checked, load, load_account_as_mut, load_checked, diff --git a/program/rust/src/tests/test_add_mapping.rs b/program/rust/src/tests/test_add_mapping.rs index 867510f57..b5213db2c 100644 --- a/program/rust/src/tests/test_add_mapping.rs +++ b/program/rust/src/tests/test_add_mapping.rs @@ -10,6 +10,7 @@ use crate::deserialize::{ load_account_as_mut, load_checked, }; +use crate::instruction::OracleCommand; use crate::processor::process_instruction; use crate::tests::test_utils::AccountSetup; use crate::utils::{ @@ -18,7 +19,6 @@ use crate::utils::{ pubkey_equal, pubkey_is_zero, }; -use crate::instruction::OracleCommand; use bytemuck::bytes_of; use solana_program::program_error::ProgramError; use solana_program::pubkey::Pubkey; diff --git a/program/rust/src/tests/test_init_mapping.rs b/program/rust/src/tests/test_init_mapping.rs index 3b3e0743f..31077f40c 100644 --- a/program/rust/src/tests/test_init_mapping.rs +++ b/program/rust/src/tests/test_init_mapping.rs @@ -6,9 +6,9 @@ use crate::c_oracle_header::{ PC_MAGIC, PC_VERSION, }; -use crate::processor::process_instruction; use crate::deserialize::load_account_as; use crate::error::OracleError; +use crate::processor::process_instruction; use crate::tests::test_utils::AccountSetup; use crate::utils::clear_account; use bytemuck::bytes_of; diff --git a/program/rust/src/tests/test_utils.rs b/program/rust/src/tests/test_utils.rs index 88552e89b..707f0c0a1 100644 --- a/program/rust/src/tests/test_utils.rs +++ b/program/rust/src/tests/test_utils.rs @@ -1,4 +1,12 @@ -use crate::c_oracle_header::PythAccount; +use crate::c_oracle_header::{ + PythAccount, + PC_VERSION, +}; +use crate::instruction::{ + CommandHeader, + OracleCommand, +}; +use num_traits::ToPrimitive; use solana_program::account_info::AccountInfo; use solana_program::clock::Epoch; use solana_program::native_token::LAMPORTS_PER_SOL; @@ -8,14 +16,11 @@ use solana_program::sysvar::{ Sysvar, SysvarId, }; -use crate::c_oracle_header::PC_VERSION; use solana_program::{ clock, system_program, sysvar, }; -use crate::instruction::{OracleCommand, CommandHeader}; -use num_traits::ToPrimitive; const UPPER_BOUND_OF_ALL_ACCOUNT_SIZES: usize = 20536; /// The goal of this struct is to easily instantiate fresh solana accounts @@ -101,10 +106,10 @@ pub fn update_clock_slot(clock_account: &mut AccountInfo, slot: u64) { } impl Into for OracleCommand { - fn into(self) -> CommandHeader{ + fn into(self) -> CommandHeader { return CommandHeader { - version : PC_VERSION, - command : self.to_i32().unwrap(), // This can never fail - } + version: PC_VERSION, + command: self.to_i32().unwrap(), // This can never fail + }; } -} \ No newline at end of file +} From be189b454325e3d213d69fea338b06554328f039 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Alapont Date: Mon, 22 Aug 2022 14:05:06 -0500 Subject: [PATCH 4/8] Cleanup --- program/rust/src/tests/test_add_mapping.rs | 15 +++++++------- program/rust/src/tests/test_init_mapping.rs | 22 ++++++++++----------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/program/rust/src/tests/test_add_mapping.rs b/program/rust/src/tests/test_add_mapping.rs index b5213db2c..fae1407b7 100644 --- a/program/rust/src/tests/test_add_mapping.rs +++ b/program/rust/src/tests/test_add_mapping.rs @@ -1,5 +1,6 @@ use crate::c_oracle_header::{ cmd_hdr_t, + command_t_e_cmd_add_mapping, pc_map_table_t, PC_MAGIC, PC_MAP_TABLE_SIZE, @@ -10,8 +11,8 @@ use crate::deserialize::{ load_account_as_mut, load_checked, }; -use crate::instruction::OracleCommand; -use crate::processor::process_instruction; + +use crate::rust_oracle::add_mapping; use crate::tests::test_utils::AccountSetup; use crate::utils::{ clear_account, @@ -27,7 +28,7 @@ use solana_program::pubkey::Pubkey; fn test_add_mapping() { let hdr: cmd_hdr_t = cmd_hdr_t { ver_: PC_VERSION, - cmd_: OracleCommand::AddMapping as i32, + cmd_: command_t_e_cmd_add_mapping as i32, }; let instruction_data = bytes_of::(&hdr); @@ -49,7 +50,7 @@ fn test_add_mapping() { cur_mapping_data.num_ = PC_MAP_TABLE_SIZE; } - assert!(process_instruction( + assert!(add_mapping( &program_id, &[ funding_account.clone(), @@ -77,7 +78,7 @@ fn test_add_mapping() { clear_account(&next_mapping).unwrap(); assert_eq!( - process_instruction( + add_mapping( &program_id, &[ funding_account.clone(), @@ -98,7 +99,7 @@ fn test_add_mapping() { } assert_eq!( - process_instruction( + add_mapping( &program_id, &[ funding_account.clone(), @@ -115,7 +116,7 @@ fn test_add_mapping() { cur_mapping_data.magic_ = PC_MAGIC; } - assert!(process_instruction( + assert!(add_mapping( &program_id, &[ funding_account.clone(), diff --git a/program/rust/src/tests/test_init_mapping.rs b/program/rust/src/tests/test_init_mapping.rs index 31077f40c..88497921b 100644 --- a/program/rust/src/tests/test_init_mapping.rs +++ b/program/rust/src/tests/test_init_mapping.rs @@ -8,7 +8,7 @@ use crate::c_oracle_header::{ }; use crate::deserialize::load_account_as; use crate::error::OracleError; -use crate::processor::process_instruction; +use crate::rust_oracle::init_mapping; use crate::tests::test_utils::AccountSetup; use crate::utils::clear_account; use bytemuck::bytes_of; @@ -34,7 +34,7 @@ fn test_init_mapping() { let mut mapping_setup = AccountSetup::new::(&program_id); let mut mapping_account = mapping_setup.to_account_info(); - assert!(process_instruction( + assert!(init_mapping( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data @@ -51,7 +51,7 @@ fn test_init_mapping() { } assert_eq!( - process_instruction( + init_mapping( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data @@ -62,14 +62,14 @@ fn test_init_mapping() { clear_account(&mapping_account).unwrap(); assert_eq!( - process_instruction(&program_id, &[funding_account.clone()], instruction_data), + init_mapping(&program_id, &[funding_account.clone()], instruction_data), Err(ProgramError::InvalidArgument) ); funding_account.is_signer = false; assert_eq!( - process_instruction( + init_mapping( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data @@ -81,7 +81,7 @@ fn test_init_mapping() { mapping_account.is_signer = false; assert_eq!( - process_instruction( + init_mapping( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data @@ -93,7 +93,7 @@ fn test_init_mapping() { funding_account.is_writable = false; assert_eq!( - process_instruction( + init_mapping( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data @@ -105,7 +105,7 @@ fn test_init_mapping() { mapping_account.is_writable = false; assert_eq!( - process_instruction( + init_mapping( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data @@ -117,7 +117,7 @@ fn test_init_mapping() { mapping_account.owner = &program_id_2; assert_eq!( - process_instruction( + init_mapping( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data @@ -130,7 +130,7 @@ fn test_init_mapping() { mapping_account.data = Rc::new(RefCell::new(&mut [])); assert_eq!( - process_instruction( + init_mapping( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data @@ -140,7 +140,7 @@ fn test_init_mapping() { mapping_account.data = prev_data; - assert!(process_instruction( + assert!(init_mapping( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data From d9abc74f34bd83e1f9a5cb037f5f965ebd956dcc Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Alapont Date: Mon, 22 Aug 2022 14:11:36 -0500 Subject: [PATCH 5/8] Additional comment --- program/rust/src/tests/test_utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/rust/src/tests/test_utils.rs b/program/rust/src/tests/test_utils.rs index 707f0c0a1..4dfc9afd5 100644 --- a/program/rust/src/tests/test_utils.rs +++ b/program/rust/src/tests/test_utils.rs @@ -109,7 +109,7 @@ impl Into for OracleCommand { fn into(self) -> CommandHeader { return CommandHeader { version: PC_VERSION, - command: self.to_i32().unwrap(), // This can never fail + command: self.to_i32().unwrap(), // This can never fail and is only used in tests }; } } From 2681acf45dbc399086b8466863cd1b9d2c763b9e Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Alapont Date: Mon, 22 Aug 2022 14:15:40 -0500 Subject: [PATCH 6/8] Delete accidental files --- program/rust/output.rs | 3039 ----------------------------------- program/rust/output.rscargo | 0 2 files changed, 3039 deletions(-) delete mode 100644 program/rust/output.rs delete mode 100644 program/rust/output.rscargo diff --git a/program/rust/output.rs b/program/rust/output.rs deleted file mode 100644 index 7eb8cd259..000000000 --- a/program/rust/output.rs +++ /dev/null @@ -1,3039 +0,0 @@ -#![feature(prelude_import)] -#![allow(non_upper_case_globals)] -#![allow(clippy::not_unsafe_ptr_arg_deref)] -#[prelude_import] -use std::prelude::rust_2021::*; -#[macro_use] -extern crate std; -mod c_oracle_header { - #![allow(non_camel_case_types)] - #![allow(non_snake_case)] - #![allow(dead_code)] - use bytemuck::{Pod, Zeroable}; - use solana_program::pubkey::Pubkey; - use std::mem::size_of; - #[repr(C)] - pub struct __IncompleteArrayField(::std::marker::PhantomData, [T; 0]); - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::default::Default for __IncompleteArrayField { - #[inline] - fn default() -> __IncompleteArrayField { - __IncompleteArrayField( - ::core::default::Default::default(), - ::core::default::Default::default(), - ) - } - } - impl __IncompleteArrayField { - #[inline] - pub const fn new() -> Self { - __IncompleteArrayField(::std::marker::PhantomData, []) - } - #[inline] - pub fn as_ptr(&self) -> *const T { - self as *const _ as *const T - } - #[inline] - pub fn as_mut_ptr(&mut self) -> *mut T { - self as *mut _ as *mut T - } - #[inline] - pub unsafe fn as_slice(&self, len: usize) -> &[T] { - ::std::slice::from_raw_parts(self.as_ptr(), len) - } - #[inline] - pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { - ::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len) - } - } - impl ::std::fmt::Debug for __IncompleteArrayField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__IncompleteArrayField") - } - } - pub const true_: u32 = 1; - pub const false_: u32 = 0; - pub const __bool_true_false_are_defined: u32 = 1; - pub const PYTH_ORACLE_UTIL_COMPAT_STDINT_STYLE: u32 = 0; - pub const __WORDSIZE: u32 = 64; - pub const __DARWIN_ONLY_64_BIT_INO_T: u32 = 1; - pub const __DARWIN_ONLY_UNIX_CONFORMANCE: u32 = 1; - pub const __DARWIN_ONLY_VERS_1050: u32 = 1; - pub const __DARWIN_UNIX03: u32 = 1; - pub const __DARWIN_64_BIT_INO_T: u32 = 1; - pub const __DARWIN_VERS_1050: u32 = 1; - pub const __DARWIN_NON_CANCELABLE: u32 = 0; - pub const __DARWIN_SUF_EXTSN: &[u8; 14usize] = b"$DARWIN_EXTSN\0"; - pub const __DARWIN_C_ANSI: u32 = 4096; - pub const __DARWIN_C_FULL: u32 = 900000; - pub const __DARWIN_C_LEVEL: u32 = 900000; - pub const __STDC_WANT_LIB_EXT1__: u32 = 1; - pub const __DARWIN_NO_LONG_LONG: u32 = 0; - pub const _DARWIN_FEATURE_64_BIT_INODE: u32 = 1; - pub const _DARWIN_FEATURE_ONLY_64_BIT_INODE: u32 = 1; - pub const _DARWIN_FEATURE_ONLY_VERS_1050: u32 = 1; - pub const _DARWIN_FEATURE_ONLY_UNIX_CONFORMANCE: u32 = 1; - pub const _DARWIN_FEATURE_UNIX_CONFORMANCE: u32 = 3; - pub const __has_ptrcheck: u32 = 0; - pub const __PTHREAD_SIZE__: u32 = 8176; - pub const __PTHREAD_ATTR_SIZE__: u32 = 56; - pub const __PTHREAD_MUTEXATTR_SIZE__: u32 = 8; - pub const __PTHREAD_MUTEX_SIZE__: u32 = 56; - pub const __PTHREAD_CONDATTR_SIZE__: u32 = 8; - pub const __PTHREAD_COND_SIZE__: u32 = 40; - pub const __PTHREAD_ONCE_SIZE__: u32 = 8; - pub const __PTHREAD_RWLOCK_SIZE__: u32 = 192; - pub const __PTHREAD_RWLOCKATTR_SIZE__: u32 = 16; - pub const INT8_MAX: u32 = 127; - pub const INT16_MAX: u32 = 32767; - pub const INT32_MAX: u32 = 2147483647; - pub const INT64_MAX: u64 = 9223372036854775807; - pub const INT8_MIN: i32 = -128; - pub const INT16_MIN: i32 = -32768; - pub const INT32_MIN: i32 = -2147483648; - pub const INT64_MIN: i64 = -9223372036854775808; - pub const UINT8_MAX: u32 = 255; - pub const UINT16_MAX: u32 = 65535; - pub const UINT32_MAX: u32 = 4294967295; - pub const UINT64_MAX: i32 = -1; - pub const INT_LEAST8_MIN: i32 = -128; - pub const INT_LEAST16_MIN: i32 = -32768; - pub const INT_LEAST32_MIN: i32 = -2147483648; - pub const INT_LEAST64_MIN: i64 = -9223372036854775808; - pub const INT_LEAST8_MAX: u32 = 127; - pub const INT_LEAST16_MAX: u32 = 32767; - pub const INT_LEAST32_MAX: u32 = 2147483647; - pub const INT_LEAST64_MAX: u64 = 9223372036854775807; - pub const UINT_LEAST8_MAX: u32 = 255; - pub const UINT_LEAST16_MAX: u32 = 65535; - pub const UINT_LEAST32_MAX: u32 = 4294967295; - pub const UINT_LEAST64_MAX: i32 = -1; - pub const INT_FAST8_MIN: i32 = -128; - pub const INT_FAST16_MIN: i32 = -32768; - pub const INT_FAST32_MIN: i32 = -2147483648; - pub const INT_FAST64_MIN: i64 = -9223372036854775808; - pub const INT_FAST8_MAX: u32 = 127; - pub const INT_FAST16_MAX: u32 = 32767; - pub const INT_FAST32_MAX: u32 = 2147483647; - pub const INT_FAST64_MAX: u64 = 9223372036854775807; - pub const UINT_FAST8_MAX: u32 = 255; - pub const UINT_FAST16_MAX: u32 = 65535; - pub const UINT_FAST32_MAX: u32 = 4294967295; - pub const UINT_FAST64_MAX: i32 = -1; - pub const INTPTR_MAX: u64 = 9223372036854775807; - pub const INTPTR_MIN: i64 = -9223372036854775808; - pub const UINTPTR_MAX: i32 = -1; - pub const SIZE_MAX: i32 = -1; - pub const RSIZE_MAX: i32 = -1; - pub const WINT_MIN: i32 = -2147483648; - pub const WINT_MAX: u32 = 2147483647; - pub const SIG_ATOMIC_MIN: i32 = -2147483648; - pub const SIG_ATOMIC_MAX: u32 = 2147483647; - pub const PC_MAGIC: u32 = 2712847316; - pub const PC_VERSION: u32 = 2; - pub const PC_MAX_SEND_LATENCY: u32 = 25; - pub const PC_PUBKEY_SIZE: u32 = 32; - pub const PC_MAP_TABLE_SIZE: u32 = 640; - pub const PC_COMP_SIZE: u32 = 32; - pub const PC_MAX_NUM_DECIMALS: u32 = 8; - pub const PC_PROD_ACC_SIZE: u32 = 512; - pub const PC_EXP_DECAY: i32 = -9; - pub const PC_MAX_CI_DIVISOR: u32 = 20; - pub const PC_HEAP_START: u64 = 12884901888; - pub const PC_PTYPE_UNKNOWN: u32 = 0; - pub const PC_PTYPE_PRICE: u32 = 1; - pub const PC_STATUS_UNKNOWN: u32 = 0; - pub const PC_STATUS_TRADING: u32 = 1; - pub const PC_STATUS_HALTED: u32 = 2; - pub const PC_STATUS_AUCTION: u32 = 3; - pub const PC_ACCTYPE_MAPPING: u32 = 1; - pub const PC_ACCTYPE_PRODUCT: u32 = 2; - pub const PC_ACCTYPE_PRICE: u32 = 3; - pub const PC_ACCTYPE_TEST: u32 = 4; - pub type size_t = ::std::os::raw::c_ulong; - pub type wchar_t = ::std::os::raw::c_int; - pub type max_align_t = f64; - pub type int_least8_t = i8; - pub type int_least16_t = i16; - pub type int_least32_t = i32; - pub type int_least64_t = i64; - pub type uint_least8_t = u8; - pub type uint_least16_t = u16; - pub type uint_least32_t = u32; - pub type uint_least64_t = u64; - pub type int_fast8_t = i8; - pub type int_fast16_t = i16; - pub type int_fast32_t = i32; - pub type int_fast64_t = i64; - pub type uint_fast8_t = u8; - pub type uint_fast16_t = u16; - pub type uint_fast32_t = u32; - pub type uint_fast64_t = u64; - pub type __int8_t = ::std::os::raw::c_schar; - pub type __uint8_t = ::std::os::raw::c_uchar; - pub type __int16_t = ::std::os::raw::c_short; - pub type __uint16_t = ::std::os::raw::c_ushort; - pub type __int32_t = ::std::os::raw::c_int; - pub type __uint32_t = ::std::os::raw::c_uint; - pub type __int64_t = ::std::os::raw::c_longlong; - pub type __uint64_t = ::std::os::raw::c_ulonglong; - pub type __darwin_intptr_t = ::std::os::raw::c_long; - pub type __darwin_natural_t = ::std::os::raw::c_uint; - pub type __darwin_ct_rune_t = ::std::os::raw::c_int; - #[repr(C)] - pub union __mbstate_t { - pub __mbstate8: [::std::os::raw::c_char; 128usize], - pub _mbstateL: ::std::os::raw::c_longlong, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for __mbstate_t {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for __mbstate_t { - #[inline] - fn clone(&self) -> __mbstate_t { - { - let _: ::core::clone::AssertParamIsCopy; - *self - } - } - } - pub type __darwin_mbstate_t = __mbstate_t; - pub type __darwin_ptrdiff_t = ::std::os::raw::c_long; - pub type __darwin_size_t = ::std::os::raw::c_ulong; - pub type __darwin_va_list = __builtin_va_list; - pub type __darwin_wchar_t = ::std::os::raw::c_int; - pub type __darwin_rune_t = __darwin_wchar_t; - pub type __darwin_wint_t = ::std::os::raw::c_int; - pub type __darwin_clock_t = ::std::os::raw::c_ulong; - pub type __darwin_socklen_t = __uint32_t; - pub type __darwin_ssize_t = ::std::os::raw::c_long; - pub type __darwin_time_t = ::std::os::raw::c_long; - pub type __darwin_blkcnt_t = __int64_t; - pub type __darwin_blksize_t = __int32_t; - pub type __darwin_dev_t = __int32_t; - pub type __darwin_fsblkcnt_t = ::std::os::raw::c_uint; - pub type __darwin_fsfilcnt_t = ::std::os::raw::c_uint; - pub type __darwin_gid_t = __uint32_t; - pub type __darwin_id_t = __uint32_t; - pub type __darwin_ino64_t = __uint64_t; - pub type __darwin_ino_t = __darwin_ino64_t; - pub type __darwin_mach_port_name_t = __darwin_natural_t; - pub type __darwin_mach_port_t = __darwin_mach_port_name_t; - pub type __darwin_mode_t = __uint16_t; - pub type __darwin_off_t = __int64_t; - pub type __darwin_pid_t = __int32_t; - pub type __darwin_sigset_t = __uint32_t; - pub type __darwin_suseconds_t = __int32_t; - pub type __darwin_uid_t = __uint32_t; - pub type __darwin_useconds_t = __uint32_t; - pub type __darwin_uuid_t = [::std::os::raw::c_uchar; 16usize]; - pub type __darwin_uuid_string_t = [::std::os::raw::c_char; 37usize]; - #[repr(C)] - pub struct __darwin_pthread_handler_rec { - pub __routine: - ::std::option::Option, - pub __arg: *mut ::std::os::raw::c_void, - pub __next: *mut __darwin_pthread_handler_rec, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for __darwin_pthread_handler_rec { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - __routine: ref __self_0_0, - __arg: ref __self_0_1, - __next: ref __self_0_2, - } => { - let debug_trait_builder = &mut ::core::fmt::Formatter::debug_struct( - f, - "__darwin_pthread_handler_rec", - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__routine", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__arg", - &&(*__self_0_1), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__next", - &&(*__self_0_2), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for __darwin_pthread_handler_rec {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for __darwin_pthread_handler_rec { - #[inline] - fn clone(&self) -> __darwin_pthread_handler_rec { - { - let _: ::core::clone::AssertParamIsClone< - ::std::option::Option, - >; - let _: ::core::clone::AssertParamIsClone<*mut ::std::os::raw::c_void>; - let _: ::core::clone::AssertParamIsClone<*mut __darwin_pthread_handler_rec>; - *self - } - } - } - #[repr(C)] - pub struct _opaque_pthread_attr_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 56usize], - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for _opaque_pthread_attr_t { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - __sig: ref __self_0_0, - __opaque: ref __self_0_1, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "_opaque_pthread_attr_t"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__sig", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__opaque", - &&(*__self_0_1), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for _opaque_pthread_attr_t {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for _opaque_pthread_attr_t { - #[inline] - fn clone(&self) -> _opaque_pthread_attr_t { - { - let _: ::core::clone::AssertParamIsClone<::std::os::raw::c_long>; - let _: ::core::clone::AssertParamIsClone<[::std::os::raw::c_char; 56usize]>; - *self - } - } - } - #[repr(C)] - pub struct _opaque_pthread_cond_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 40usize], - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for _opaque_pthread_cond_t { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - __sig: ref __self_0_0, - __opaque: ref __self_0_1, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "_opaque_pthread_cond_t"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__sig", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__opaque", - &&(*__self_0_1), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for _opaque_pthread_cond_t {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for _opaque_pthread_cond_t { - #[inline] - fn clone(&self) -> _opaque_pthread_cond_t { - { - let _: ::core::clone::AssertParamIsClone<::std::os::raw::c_long>; - let _: ::core::clone::AssertParamIsClone<[::std::os::raw::c_char; 40usize]>; - *self - } - } - } - #[repr(C)] - pub struct _opaque_pthread_condattr_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 8usize], - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for _opaque_pthread_condattr_t { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - __sig: ref __self_0_0, - __opaque: ref __self_0_1, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "_opaque_pthread_condattr_t"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__sig", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__opaque", - &&(*__self_0_1), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for _opaque_pthread_condattr_t {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for _opaque_pthread_condattr_t { - #[inline] - fn clone(&self) -> _opaque_pthread_condattr_t { - { - let _: ::core::clone::AssertParamIsClone<::std::os::raw::c_long>; - let _: ::core::clone::AssertParamIsClone<[::std::os::raw::c_char; 8usize]>; - *self - } - } - } - #[repr(C)] - pub struct _opaque_pthread_mutex_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 56usize], - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for _opaque_pthread_mutex_t { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - __sig: ref __self_0_0, - __opaque: ref __self_0_1, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "_opaque_pthread_mutex_t"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__sig", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__opaque", - &&(*__self_0_1), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for _opaque_pthread_mutex_t {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for _opaque_pthread_mutex_t { - #[inline] - fn clone(&self) -> _opaque_pthread_mutex_t { - { - let _: ::core::clone::AssertParamIsClone<::std::os::raw::c_long>; - let _: ::core::clone::AssertParamIsClone<[::std::os::raw::c_char; 56usize]>; - *self - } - } - } - #[repr(C)] - pub struct _opaque_pthread_mutexattr_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 8usize], - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for _opaque_pthread_mutexattr_t { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - __sig: ref __self_0_0, - __opaque: ref __self_0_1, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "_opaque_pthread_mutexattr_t"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__sig", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__opaque", - &&(*__self_0_1), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for _opaque_pthread_mutexattr_t {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for _opaque_pthread_mutexattr_t { - #[inline] - fn clone(&self) -> _opaque_pthread_mutexattr_t { - { - let _: ::core::clone::AssertParamIsClone<::std::os::raw::c_long>; - let _: ::core::clone::AssertParamIsClone<[::std::os::raw::c_char; 8usize]>; - *self - } - } - } - #[repr(C)] - pub struct _opaque_pthread_once_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 8usize], - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for _opaque_pthread_once_t { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - __sig: ref __self_0_0, - __opaque: ref __self_0_1, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "_opaque_pthread_once_t"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__sig", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__opaque", - &&(*__self_0_1), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for _opaque_pthread_once_t {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for _opaque_pthread_once_t { - #[inline] - fn clone(&self) -> _opaque_pthread_once_t { - { - let _: ::core::clone::AssertParamIsClone<::std::os::raw::c_long>; - let _: ::core::clone::AssertParamIsClone<[::std::os::raw::c_char; 8usize]>; - *self - } - } - } - #[repr(C)] - pub struct _opaque_pthread_rwlock_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 192usize], - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for _opaque_pthread_rwlock_t { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - __sig: ref __self_0_0, - __opaque: ref __self_0_1, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "_opaque_pthread_rwlock_t"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__sig", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__opaque", - &&(*__self_0_1), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for _opaque_pthread_rwlock_t {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for _opaque_pthread_rwlock_t { - #[inline] - fn clone(&self) -> _opaque_pthread_rwlock_t { - { - let _: ::core::clone::AssertParamIsClone<::std::os::raw::c_long>; - let _: ::core::clone::AssertParamIsClone<[::std::os::raw::c_char; 192usize]>; - *self - } - } - } - #[repr(C)] - pub struct _opaque_pthread_rwlockattr_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 16usize], - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for _opaque_pthread_rwlockattr_t { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - __sig: ref __self_0_0, - __opaque: ref __self_0_1, - } => { - let debug_trait_builder = &mut ::core::fmt::Formatter::debug_struct( - f, - "_opaque_pthread_rwlockattr_t", - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__sig", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__opaque", - &&(*__self_0_1), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for _opaque_pthread_rwlockattr_t {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for _opaque_pthread_rwlockattr_t { - #[inline] - fn clone(&self) -> _opaque_pthread_rwlockattr_t { - { - let _: ::core::clone::AssertParamIsClone<::std::os::raw::c_long>; - let _: ::core::clone::AssertParamIsClone<[::std::os::raw::c_char; 16usize]>; - *self - } - } - } - #[repr(C)] - pub struct _opaque_pthread_t { - pub __sig: ::std::os::raw::c_long, - pub __cleanup_stack: *mut __darwin_pthread_handler_rec, - pub __opaque: [::std::os::raw::c_char; 8176usize], - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for _opaque_pthread_t { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - __sig: ref __self_0_0, - __cleanup_stack: ref __self_0_1, - __opaque: ref __self_0_2, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "_opaque_pthread_t"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__sig", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__cleanup_stack", - &&(*__self_0_1), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "__opaque", - &&(*__self_0_2), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for _opaque_pthread_t {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for _opaque_pthread_t { - #[inline] - fn clone(&self) -> _opaque_pthread_t { - { - let _: ::core::clone::AssertParamIsClone<::std::os::raw::c_long>; - let _: ::core::clone::AssertParamIsClone<*mut __darwin_pthread_handler_rec>; - let _: ::core::clone::AssertParamIsClone<[::std::os::raw::c_char; 8176usize]>; - *self - } - } - } - pub type __darwin_pthread_attr_t = _opaque_pthread_attr_t; - pub type __darwin_pthread_cond_t = _opaque_pthread_cond_t; - pub type __darwin_pthread_condattr_t = _opaque_pthread_condattr_t; - pub type __darwin_pthread_key_t = ::std::os::raw::c_ulong; - pub type __darwin_pthread_mutex_t = _opaque_pthread_mutex_t; - pub type __darwin_pthread_mutexattr_t = _opaque_pthread_mutexattr_t; - pub type __darwin_pthread_once_t = _opaque_pthread_once_t; - pub type __darwin_pthread_rwlock_t = _opaque_pthread_rwlock_t; - pub type __darwin_pthread_rwlockattr_t = _opaque_pthread_rwlockattr_t; - pub type __darwin_pthread_t = *mut _opaque_pthread_t; - pub type u_int8_t = ::std::os::raw::c_uchar; - pub type u_int16_t = ::std::os::raw::c_ushort; - pub type u_int32_t = ::std::os::raw::c_uint; - pub type u_int64_t = ::std::os::raw::c_ulonglong; - pub type register_t = i64; - pub type user_addr_t = u_int64_t; - pub type user_size_t = u_int64_t; - pub type user_ssize_t = i64; - pub type user_long_t = i64; - pub type user_ulong_t = u_int64_t; - pub type user_time_t = i64; - pub type user_off_t = i64; - pub type syscall_arg_t = u_int64_t; - pub type intmax_t = ::std::os::raw::c_long; - pub type uintmax_t = ::std::os::raw::c_ulong; - pub const TIME_MACHINE_STRUCT_SIZE: u64 = 1864; - pub const EXTRA_PUBLISHER_SPACE: u64 = 1000; - extern "C" { - pub static sysvar_clock: [u64; 4usize]; - } - #[repr(C)] - pub union pc_pub_key { - pub k1_: [u8; 32usize], - pub k8_: [u64; 4usize], - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for pc_pub_key {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for pc_pub_key { - #[inline] - fn clone(&self) -> pc_pub_key { - { - let _: ::core::clone::AssertParamIsCopy; - *self - } - } - } - pub type pc_pub_key_t = pc_pub_key; - #[repr(C)] - pub struct pc_acc { - pub magic_: u32, - pub ver_: u32, - pub type_: u32, - pub size_: u32, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for pc_acc { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - magic_: ref __self_0_0, - ver_: ref __self_0_1, - type_: ref __self_0_2, - size_: ref __self_0_3, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "pc_acc"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "magic_", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "ver_", - &&(*__self_0_1), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "type_", - &&(*__self_0_2), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "size_", - &&(*__self_0_3), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for pc_acc {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for pc_acc { - #[inline] - fn clone(&self) -> pc_acc { - { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - *self - } - } - } - pub type pc_acc_t = pc_acc; - #[repr(C)] - pub struct pc_map_table { - pub magic_: u32, - pub ver_: u32, - pub type_: u32, - pub size_: u32, - pub num_: u32, - pub unused_: u32, - pub next_: pc_pub_key_t, - pub prod_: [pc_pub_key_t; 640usize], - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for pc_map_table {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for pc_map_table { - #[inline] - fn clone(&self) -> pc_map_table { - { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone<[pc_pub_key_t; 640usize]>; - *self - } - } - } - pub type pc_map_table_t = pc_map_table; - #[repr(C)] - pub struct pc_str { - pub len_: u8, - pub data_: __IncompleteArrayField<::std::os::raw::c_char>, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for pc_str { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - len_: ref __self_0_0, - data_: ref __self_0_1, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "pc_str"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "len_", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "data_", - &&(*__self_0_1), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - pub type pc_str_t = pc_str; - #[repr(C)] - pub struct pc_prod { - pub magic_: u32, - pub ver_: u32, - pub type_: u32, - pub size_: u32, - pub px_acc_: pc_pub_key_t, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for pc_prod {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for pc_prod { - #[inline] - fn clone(&self) -> pc_prod { - { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - *self - } - } - } - pub type pc_prod_t = pc_prod; - #[repr(C)] - pub struct pc_price_info { - pub price_: i64, - pub conf_: u64, - pub status_: u32, - pub corp_act_status_: u32, - pub pub_slot_: u64, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for pc_price_info { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - price_: ref __self_0_0, - conf_: ref __self_0_1, - status_: ref __self_0_2, - corp_act_status_: ref __self_0_3, - pub_slot_: ref __self_0_4, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "pc_price_info"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "price_", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "conf_", - &&(*__self_0_1), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "status_", - &&(*__self_0_2), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "corp_act_status_", - &&(*__self_0_3), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "pub_slot_", - &&(*__self_0_4), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for pc_price_info {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for pc_price_info { - #[inline] - fn clone(&self) -> pc_price_info { - { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - *self - } - } - } - pub type pc_price_info_t = pc_price_info; - #[repr(C)] - pub struct pc_price_comp { - pub pub_: pc_pub_key_t, - pub agg_: pc_price_info_t, - pub latest_: pc_price_info_t, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for pc_price_comp {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for pc_price_comp { - #[inline] - fn clone(&self) -> pc_price_comp { - { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - *self - } - } - } - pub type pc_price_comp_t = pc_price_comp; - #[repr(C)] - pub struct pc_ema { - pub val_: i64, - pub numer_: i64, - pub denom_: i64, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for pc_ema { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - val_: ref __self_0_0, - numer_: ref __self_0_1, - denom_: ref __self_0_2, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "pc_ema"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "val_", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "numer_", - &&(*__self_0_1), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "denom_", - &&(*__self_0_2), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for pc_ema {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for pc_ema { - #[inline] - fn clone(&self) -> pc_ema { - { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - *self - } - } - } - pub type pc_ema_t = pc_ema; - #[repr(C)] - pub struct pc_price { - pub magic_: u32, - pub ver_: u32, - pub type_: u32, - pub size_: u32, - pub ptype_: u32, - pub expo_: i32, - pub num_: u32, - pub num_qt_: u32, - pub last_slot_: u64, - pub valid_slot_: u64, - pub twap_: pc_ema_t, - pub twac_: pc_ema_t, - pub timestamp_: i64, - pub min_pub_: u8, - pub drv2_: i8, - pub drv3_: i16, - pub drv4_: i32, - pub prod_: pc_pub_key_t, - pub next_: pc_pub_key_t, - pub prev_slot_: u64, - pub prev_price_: i64, - pub prev_conf_: u64, - pub prev_timestamp_: i64, - pub agg_: pc_price_info_t, - pub comp_: [pc_price_comp_t; 32usize], - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for pc_price {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for pc_price { - #[inline] - fn clone(&self) -> pc_price { - { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone<[pc_price_comp_t; 32usize]>; - *self - } - } - } - pub type pc_price_t = pc_price; - pub const PRICE_ACCOUNT_SIZE: u64 = 6176; - pub const command_t_e_cmd_init_mapping: command_t = 0; - pub const command_t_e_cmd_add_mapping: command_t = 1; - pub const command_t_e_cmd_add_product: command_t = 2; - pub const command_t_e_cmd_upd_product: command_t = 3; - pub const command_t_e_cmd_add_price: command_t = 4; - pub const command_t_e_cmd_add_publisher: command_t = 5; - pub const command_t_e_cmd_del_publisher: command_t = 6; - pub const command_t_e_cmd_upd_price: command_t = 7; - pub const command_t_e_cmd_agg_price: command_t = 8; - pub const command_t_e_cmd_init_price: command_t = 9; - pub const command_t_e_cmd_init_test: command_t = 10; - pub const command_t_e_cmd_upd_test: command_t = 11; - pub const command_t_e_cmd_set_min_pub: command_t = 12; - pub const command_t_e_cmd_upd_price_no_fail_on_error: command_t = 13; - pub const command_t_e_cmd_resize_price_account: command_t = 14; - pub const command_t_e_cmd_del_price: command_t = 15; - pub type command_t = ::std::os::raw::c_uint; - #[repr(C)] - pub struct cmd_hdr { - pub ver_: u32, - pub cmd_: i32, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for cmd_hdr { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - ver_: ref __self_0_0, - cmd_: ref __self_0_1, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "cmd_hdr"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "ver_", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "cmd_", - &&(*__self_0_1), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for cmd_hdr {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for cmd_hdr { - #[inline] - fn clone(&self) -> cmd_hdr { - { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - *self - } - } - } - pub type cmd_hdr_t = cmd_hdr; - #[repr(C)] - pub struct cmd_add_product { - pub ver_: u32, - pub cmd_: i32, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for cmd_add_product { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - ver_: ref __self_0_0, - cmd_: ref __self_0_1, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "cmd_add_product"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "ver_", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "cmd_", - &&(*__self_0_1), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for cmd_add_product {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for cmd_add_product { - #[inline] - fn clone(&self) -> cmd_add_product { - { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - *self - } - } - } - pub type cmd_add_product_t = cmd_add_product; - #[repr(C)] - pub struct cmd_upd_product { - pub ver_: u32, - pub cmd_: i32, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for cmd_upd_product { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - ver_: ref __self_0_0, - cmd_: ref __self_0_1, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "cmd_upd_product"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "ver_", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "cmd_", - &&(*__self_0_1), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for cmd_upd_product {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for cmd_upd_product { - #[inline] - fn clone(&self) -> cmd_upd_product { - { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - *self - } - } - } - pub type cmd_upd_product_t = cmd_upd_product; - #[repr(C)] - pub struct cmd_add_price { - pub ver_: u32, - pub cmd_: i32, - pub expo_: i32, - pub ptype_: u32, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for cmd_add_price { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - ver_: ref __self_0_0, - cmd_: ref __self_0_1, - expo_: ref __self_0_2, - ptype_: ref __self_0_3, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "cmd_add_price"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "ver_", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "cmd_", - &&(*__self_0_1), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "expo_", - &&(*__self_0_2), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "ptype_", - &&(*__self_0_3), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for cmd_add_price {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for cmd_add_price { - #[inline] - fn clone(&self) -> cmd_add_price { - { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - *self - } - } - } - pub type cmd_add_price_t = cmd_add_price; - #[repr(C)] - pub struct cmd_init_price { - pub ver_: u32, - pub cmd_: i32, - pub expo_: i32, - pub ptype_: u32, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for cmd_init_price { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - ver_: ref __self_0_0, - cmd_: ref __self_0_1, - expo_: ref __self_0_2, - ptype_: ref __self_0_3, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "cmd_init_price"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "ver_", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "cmd_", - &&(*__self_0_1), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "expo_", - &&(*__self_0_2), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "ptype_", - &&(*__self_0_3), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for cmd_init_price {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for cmd_init_price { - #[inline] - fn clone(&self) -> cmd_init_price { - { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - *self - } - } - } - pub type cmd_init_price_t = cmd_init_price; - #[repr(C)] - pub struct cmd_set_min_pub { - pub ver_: u32, - pub cmd_: i32, - pub min_pub_: u8, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for cmd_set_min_pub { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - ver_: ref __self_0_0, - cmd_: ref __self_0_1, - min_pub_: ref __self_0_2, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "cmd_set_min_pub"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "ver_", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "cmd_", - &&(*__self_0_1), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "min_pub_", - &&(*__self_0_2), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for cmd_set_min_pub {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for cmd_set_min_pub { - #[inline] - fn clone(&self) -> cmd_set_min_pub { - { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - *self - } - } - } - pub type cmd_set_min_pub_t = cmd_set_min_pub; - #[repr(C)] - pub struct cmd_add_publisher { - pub ver_: u32, - pub cmd_: i32, - pub pub_: pc_pub_key_t, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for cmd_add_publisher {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for cmd_add_publisher { - #[inline] - fn clone(&self) -> cmd_add_publisher { - { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - *self - } - } - } - pub type cmd_add_publisher_t = cmd_add_publisher; - #[repr(C)] - pub struct cmd_del_publisher { - pub ver_: u32, - pub cmd_: i32, - pub pub_: pc_pub_key_t, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for cmd_del_publisher {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for cmd_del_publisher { - #[inline] - fn clone(&self) -> cmd_del_publisher { - { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - *self - } - } - } - pub type cmd_del_publisher_t = cmd_del_publisher; - #[repr(C)] - pub struct cmd_upd_price { - pub ver_: u32, - pub cmd_: i32, - pub status_: u32, - pub unused_: u32, - pub price_: i64, - pub conf_: u64, - pub pub_slot_: u64, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for cmd_upd_price { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - ver_: ref __self_0_0, - cmd_: ref __self_0_1, - status_: ref __self_0_2, - unused_: ref __self_0_3, - price_: ref __self_0_4, - conf_: ref __self_0_5, - pub_slot_: ref __self_0_6, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "cmd_upd_price"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "ver_", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "cmd_", - &&(*__self_0_1), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "status_", - &&(*__self_0_2), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "unused_", - &&(*__self_0_3), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "price_", - &&(*__self_0_4), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "conf_", - &&(*__self_0_5), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "pub_slot_", - &&(*__self_0_6), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for cmd_upd_price {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for cmd_upd_price { - #[inline] - fn clone(&self) -> cmd_upd_price { - { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - *self - } - } - } - pub type cmd_upd_price_t = cmd_upd_price; - #[repr(C)] - pub struct cmd_upd_test { - pub ver_: u32, - pub cmd_: i32, - pub num_: u32, - pub expo_: i32, - pub slot_diff_: [i8; 32usize], - pub price_: [i64; 32usize], - pub conf_: [u64; 32usize], - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for cmd_upd_test { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - ver_: ref __self_0_0, - cmd_: ref __self_0_1, - num_: ref __self_0_2, - expo_: ref __self_0_3, - slot_diff_: ref __self_0_4, - price_: ref __self_0_5, - conf_: ref __self_0_6, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "cmd_upd_test"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "ver_", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "cmd_", - &&(*__self_0_1), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "num_", - &&(*__self_0_2), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "expo_", - &&(*__self_0_3), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "slot_diff_", - &&(*__self_0_4), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "price_", - &&(*__self_0_5), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "conf_", - &&(*__self_0_6), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for cmd_upd_test {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for cmd_upd_test { - #[inline] - fn clone(&self) -> cmd_upd_test { - { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone<[i8; 32usize]>; - let _: ::core::clone::AssertParamIsClone<[i64; 32usize]>; - let _: ::core::clone::AssertParamIsClone<[u64; 32usize]>; - *self - } - } - } - pub type cmd_upd_test_t = cmd_upd_test; - #[repr(C)] - pub struct sysvar_clock { - pub slot_: u64, - pub epoch_start_timestamp_: i64, - pub epoch_: u64, - pub leader_schedule_epoch_: u64, - pub unix_timestamp_: i64, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for sysvar_clock { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - slot_: ref __self_0_0, - epoch_start_timestamp_: ref __self_0_1, - epoch_: ref __self_0_2, - leader_schedule_epoch_: ref __self_0_3, - unix_timestamp_: ref __self_0_4, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "sysvar_clock"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "slot_", - &&(*__self_0_0), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "epoch_start_timestamp_", - &&(*__self_0_1), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "epoch_", - &&(*__self_0_2), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "leader_schedule_epoch_", - &&(*__self_0_3), - ); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "unix_timestamp_", - &&(*__self_0_4), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for sysvar_clock {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for sysvar_clock { - #[inline] - fn clone(&self) -> sysvar_clock { - { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - *self - } - } - } - pub type sysvar_clock_t = sysvar_clock; - pub const PC_PRICE_T_COMP_OFFSET: size_t = 240; - pub const PC_MAP_TABLE_T_PROD_OFFSET: size_t = 56; - pub type __builtin_va_list = *mut ::std::os::raw::c_char; - /// The PythAccount trait's purpose is to attach constants to the 3 types of accounts that Pyth has - /// (mapping, price, product). This allows less duplicated code, because now we can create generic - /// functions to perform common checks on the accounts and to load and initialize the accounts. - pub trait PythAccount: Pod { - /// `ACCOUNT_TYPE` is just the account discriminator, it is different for mapping, product and - /// price - const ACCOUNT_TYPE: u32; - /// `INITIAL_SIZE` is the value that the field `size_` will take when the account is first - /// initialized this one is slightly tricky because for mapping (resp. price) `size_` won't - /// include the unpopulated entries of `prod_` (resp. `comp_`). At the beginning there are 0 - /// products (resp. 0 components) therefore `INITIAL_SIZE` will be equal to the offset of - /// `prod_` (resp. `comp_`) Similarly the product account `INITIAL_SIZE` won't include any - /// key values. - const INITIAL_SIZE: u32; - /// `minimum_size()` is the minimum size that the solana account holding the struct needs to - /// have. `INITIAL_SIZE` <= `minimum_size()` - fn minimum_size() -> usize { - size_of::() - } - } - impl PythAccount for pc_map_table_t { - const ACCOUNT_TYPE: u32 = PC_ACCTYPE_MAPPING; - const INITIAL_SIZE: u32 = PC_MAP_TABLE_T_PROD_OFFSET as u32; - } - impl PythAccount for pc_prod_t { - const ACCOUNT_TYPE: u32 = PC_ACCTYPE_PRODUCT; - const INITIAL_SIZE: u32 = size_of::() as u32; - fn minimum_size() -> usize { - PC_PROD_ACC_SIZE as usize - } - } - impl PythAccount for pc_price_t { - const ACCOUNT_TYPE: u32 = PC_ACCTYPE_PRICE; - const INITIAL_SIZE: u32 = PC_PRICE_T_COMP_OFFSET as u32; - } - #[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 {} - #[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 {} - #[cfg(target_endian = "little")] - unsafe impl Zeroable for cmd_hdr {} - #[cfg(target_endian = "little")] - unsafe impl Pod for cmd_hdr {} - #[cfg(target_endian = "little")] - unsafe impl Zeroable for pc_price_info {} - #[cfg(target_endian = "little")] - unsafe impl Pod for pc_price_info {} - #[cfg(target_endian = "little")] - unsafe impl Zeroable for cmd_upd_price {} - #[cfg(target_endian = "little")] - unsafe impl Pod for cmd_upd_price {} - #[cfg(target_endian = "little")] - unsafe impl Zeroable for pc_ema {} - #[cfg(target_endian = "little")] - unsafe impl Pod for pc_ema {} - #[cfg(target_endian = "little")] - 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 cmd_init_price_t {} - #[cfg(target_endian = "little")] - unsafe impl Pod for cmd_init_price_t {} - #[cfg(target_endian = "little")] - unsafe impl Zeroable for cmd_add_publisher_t {} - #[cfg(target_endian = "little")] - unsafe impl Pod for cmd_add_publisher_t {} - #[cfg(target_endian = "little")] - unsafe impl Zeroable for cmd_del_publisher_t {} - #[cfg(target_endian = "little")] - unsafe impl Pod for cmd_del_publisher_t {} - unsafe impl Zeroable for cmd_set_min_pub_t {} - #[cfg(target_endian = "little")] - unsafe impl Pod for cmd_set_min_pub_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 {} - #[cfg(target_endian = "little")] - unsafe impl Zeroable for pc_price_comp_t {} - #[cfg(target_endian = "little")] - unsafe impl Pod for pc_price_comp_t {} - impl pc_pub_key_t { - pub fn new_unique() -> pc_pub_key_t { - let solana_unique = Pubkey::new_unique(); - pc_pub_key_t { - k1_: solana_unique.to_bytes(), - } - } - } -} -mod deserialize { - use std::mem::size_of; - use bytemuck::{try_from_bytes, try_from_bytes_mut, Pod}; - use crate::c_oracle_header::{pc_acc, PythAccount, PC_MAGIC}; - use crate::utils::{clear_account, pyth_assert}; - use solana_program::account_info::AccountInfo; - use solana_program::program_error::ProgramError; - use std::cell::{Ref, RefMut}; - /// Interpret the bytes in `data` as a value of type `T` - pub fn load(data: &[u8]) -> Result<&T, ProgramError> { - 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` - #[allow(unused)] - pub fn load_mut(data: &mut [u8]) -> Result<&mut T, ProgramError> { - try_from_bytes_mut( - data.get_mut(0..size_of::()) - .ok_or(ProgramError::InvalidArgument)?, - ) - .map_err(|_| ProgramError::InvalidArgument) - } - /// Get the data stored in `account` as a value of type `T` - pub 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. - pub 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::()]) - })) - } - pub fn load_checked<'a, T: PythAccount>( - account: &'a AccountInfo, - version: u32, - ) -> Result, ProgramError> { - { - let account_header = load_account_as::(account)?; - pyth_assert( - account_header.magic_ == PC_MAGIC - && account_header.ver_ == version - && account_header.type_ == T::ACCOUNT_TYPE, - ProgramError::InvalidArgument, - )?; - } - load_account_as_mut::(account) - } - pub fn initialize_pyth_account_checked<'a, T: PythAccount>( - account: &'a AccountInfo, - version: u32, - ) -> Result, ProgramError> { - clear_account(account)?; - { - let mut account_header = load_account_as_mut::(account)?; - account_header.magic_ = PC_MAGIC; - account_header.ver_ = version; - account_header.type_ = T::ACCOUNT_TYPE; - account_header.size_ = T::INITIAL_SIZE; - } - load_account_as_mut::(account) - } -} -mod error { - //! Error types - use solana_program::program_error::ProgramError; - use thiserror::Error; - /// Errors that may be returned by the oracle program - pub enum OracleError { - /// Generic catch all error - #[error("Generic")] - Generic = 600, - /// integer casting error - #[error("IntegerCastingError")] - IntegerCastingError = 601, - /// c_entrypoint returned an unexpected value - #[error("UnknownCError")] - UnknownCError = 602, - #[error("UnrecognizedInstruction")] - UnrecognizedInstruction = 603, - #[error("InvalidFundingAccount")] - InvalidFundingAccount = 604, - #[error("InvalidSignableAccount")] - InvalidSignableAccount = 605, - #[error("InvalidSystemAccount")] - InvalidSystemAccount = 606, - #[error("InvalidWritableAccount")] - InvalidWritableAccount = 607, - #[error("InvalidFreshAccount")] - InvalidFreshAccount = 608, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for OracleError { - #[inline] - fn clone(&self) -> OracleError { - match (&*self,) { - (&OracleError::Generic,) => OracleError::Generic, - (&OracleError::IntegerCastingError,) => OracleError::IntegerCastingError, - (&OracleError::UnknownCError,) => OracleError::UnknownCError, - (&OracleError::UnrecognizedInstruction,) => OracleError::UnrecognizedInstruction, - (&OracleError::InvalidFundingAccount,) => OracleError::InvalidFundingAccount, - (&OracleError::InvalidSignableAccount,) => OracleError::InvalidSignableAccount, - (&OracleError::InvalidSystemAccount,) => OracleError::InvalidSystemAccount, - (&OracleError::InvalidWritableAccount,) => OracleError::InvalidWritableAccount, - (&OracleError::InvalidFreshAccount,) => OracleError::InvalidFreshAccount, - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for OracleError { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match (&*self,) { - (&OracleError::Generic,) => ::core::fmt::Formatter::write_str(f, "Generic"), - (&OracleError::IntegerCastingError,) => { - ::core::fmt::Formatter::write_str(f, "IntegerCastingError") - } - (&OracleError::UnknownCError,) => { - ::core::fmt::Formatter::write_str(f, "UnknownCError") - } - (&OracleError::UnrecognizedInstruction,) => { - ::core::fmt::Formatter::write_str(f, "UnrecognizedInstruction") - } - (&OracleError::InvalidFundingAccount,) => { - ::core::fmt::Formatter::write_str(f, "InvalidFundingAccount") - } - (&OracleError::InvalidSignableAccount,) => { - ::core::fmt::Formatter::write_str(f, "InvalidSignableAccount") - } - (&OracleError::InvalidSystemAccount,) => { - ::core::fmt::Formatter::write_str(f, "InvalidSystemAccount") - } - (&OracleError::InvalidWritableAccount,) => { - ::core::fmt::Formatter::write_str(f, "InvalidWritableAccount") - } - (&OracleError::InvalidFreshAccount,) => { - ::core::fmt::Formatter::write_str(f, "InvalidFreshAccount") - } - } - } - } - impl ::core::marker::StructuralEq for OracleError {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::cmp::Eq for OracleError { - #[inline] - #[doc(hidden)] - #[no_coverage] - fn assert_receiver_is_total_eq(&self) -> () { - {} - } - } - #[allow(unused_qualifications)] - impl std::error::Error for OracleError {} - #[allow(unused_qualifications)] - impl std::fmt::Display for OracleError { - fn fmt(&self, __formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - OracleError::Generic {} => { - let result = - __formatter.write_fmt(::core::fmt::Arguments::new_v1(&["Generic"], &[])); - result - } - OracleError::IntegerCastingError {} => { - let result = __formatter.write_fmt(::core::fmt::Arguments::new_v1( - &["IntegerCastingError"], - &[], - )); - result - } - OracleError::UnknownCError {} => { - let result = __formatter - .write_fmt(::core::fmt::Arguments::new_v1(&["UnknownCError"], &[])); - result - } - OracleError::UnrecognizedInstruction {} => { - let result = __formatter.write_fmt(::core::fmt::Arguments::new_v1( - &["UnrecognizedInstruction"], - &[], - )); - result - } - OracleError::InvalidFundingAccount {} => { - let result = __formatter.write_fmt(::core::fmt::Arguments::new_v1( - &["InvalidFundingAccount"], - &[], - )); - result - } - OracleError::InvalidSignableAccount {} => { - let result = __formatter.write_fmt(::core::fmt::Arguments::new_v1( - &["InvalidSignableAccount"], - &[], - )); - result - } - OracleError::InvalidSystemAccount {} => { - let result = __formatter.write_fmt(::core::fmt::Arguments::new_v1( - &["InvalidSystemAccount"], - &[], - )); - result - } - OracleError::InvalidWritableAccount {} => { - let result = __formatter.write_fmt(::core::fmt::Arguments::new_v1( - &["InvalidWritableAccount"], - &[], - )); - result - } - OracleError::InvalidFreshAccount {} => { - let result = __formatter.write_fmt(::core::fmt::Arguments::new_v1( - &["InvalidFreshAccount"], - &[], - )); - result - } - } - } - } - impl ::core::marker::StructuralPartialEq for OracleError {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::cmp::PartialEq for OracleError { - #[inline] - fn eq(&self, other: &OracleError) -> bool { - { - let __self_vi = ::core::intrinsics::discriminant_value(&*self); - let __arg_1_vi = ::core::intrinsics::discriminant_value(&*other); - if true && __self_vi == __arg_1_vi { - match (&*self, &*other) { - _ => true, - } - } else { - false - } - } - } - } - impl From for ProgramError { - fn from(e: OracleError) -> Self { - ProgramError::Custom(e as u32) - } - } -} -mod processor { - use crate::c_oracle_header::{ - cmd_hdr, command_t_e_cmd_add_mapping, command_t_e_cmd_add_price, - command_t_e_cmd_add_product, command_t_e_cmd_add_publisher, command_t_e_cmd_agg_price, - command_t_e_cmd_del_price, command_t_e_cmd_del_publisher, command_t_e_cmd_init_mapping, - command_t_e_cmd_init_price, command_t_e_cmd_resize_price_account, - command_t_e_cmd_set_min_pub, command_t_e_cmd_upd_price, - command_t_e_cmd_upd_price_no_fail_on_error, command_t_e_cmd_upd_product, PC_VERSION, - }; - use crate::instruction::OracleCommand; - use crate::deserialize::load; - use crate::error::OracleError; - use solana_program::entrypoint::ProgramResult; - use solana_program::program_error::ProgramError; - use solana_program::pubkey::Pubkey; - use solana_program::sysvar::slot_history::AccountInfo; - use crate::rust_oracle::{ - add_mapping, add_price, add_product, add_publisher, del_price, del_publisher, init_mapping, - init_price, resize_price_account, set_min_pub, upd_price, upd_price_no_fail_on_error, - upd_product, - }; - ///dispatch to the right instruction in the oracle - pub fn process_instruction( - program_id: &Pubkey, - accounts: &[AccountInfo], - instruction_data: &[u8], - ) -> ProgramResult { - let cmd_data = load::(instruction_data)?; - if cmd_data.ver_ != PC_VERSION { - return Err(ProgramError::InvalidArgument); - } - match OracleCommand::try_from(cmd_data.cmd_) { - OracleCommand::InitMapping => ::core::panicking::panic("not yet implemented"), - OracleCommand::AddMapping => ::core::panicking::panic("not yet implemented"), - OracleCommand::AddProduct => ::core::panicking::panic("not yet implemented"), - OracleCommand::UpdProduct => ::core::panicking::panic("not yet implemented"), - OracleCommand::AddPrice => ::core::panicking::panic("not yet implemented"), - OracleCommand::AddPublisher => ::core::panicking::panic("not yet implemented"), - OracleCommand::DelPublisher => ::core::panicking::panic("not yet implemented"), - OracleCommand::UpdPrice => ::core::panicking::panic("not yet implemented"), - OracleCommand::AggPrice => ::core::panicking::panic("not yet implemented"), - OracleCommand::InitPrice => ::core::panicking::panic("not yet implemented"), - OracleCommand::InitTest => ::core::panicking::panic("not yet implemented"), - OracleCommand::UpdTest => ::core::panicking::panic("not yet implemented"), - OracleCommand::SetMinPub => ::core::panicking::panic("not yet implemented"), - OracleCommand::UpdPriceNoFailOnError => ::core::panicking::panic("not yet implemented"), - OracleCommand::ResizePriceAccount => ::core::panicking::panic("not yet implemented"), - OracleCommand::DelPrice => ::core::panicking::panic("not yet implemented"), - } - } -} -mod rust_oracle { - use std::mem::{size_of, size_of_val}; - use bytemuck::{bytes_of, bytes_of_mut}; - use solana_program::account_info::AccountInfo; - use solana_program::clock::Clock; - use solana_program::entrypoint::ProgramResult; - use solana_program::program::invoke; - use solana_program::program_error::ProgramError; - use solana_program::program_memory::{sol_memcpy, sol_memset}; - use solana_program::pubkey::Pubkey; - use solana_program::rent::Rent; - use solana_program::system_instruction::transfer; - use solana_program::system_program::check_id; - use solana_program::sysvar::Sysvar; - use crate::c_oracle_header::{ - cmd_add_price_t, cmd_add_publisher_t, cmd_del_publisher_t, cmd_hdr_t, cmd_init_price_t, - cmd_set_min_pub_t, cmd_upd_price_t, cmd_upd_product_t, pc_ema_t, pc_map_table_t, - pc_price_comp, pc_price_info_t, pc_price_t, pc_prod_t, pc_pub_key_t, PC_COMP_SIZE, - PC_MAP_TABLE_SIZE, PC_MAX_CI_DIVISOR, PC_PROD_ACC_SIZE, PC_PTYPE_UNKNOWN, - PC_STATUS_UNKNOWN, PC_VERSION, - }; - use crate::deserialize::{initialize_pyth_account_checked, load, load_account_as_mut, load_checked}; - use crate::time_machine_types::PriceAccountWrapper; - use crate::utils::{ - check_exponent_range, check_valid_fresh_account, check_valid_funding_account, - check_valid_signable_account, check_valid_writable_account, is_component_update, - pubkey_assign, pubkey_equal, pubkey_is_zero, pyth_assert, read_pc_str_t, try_convert, - }; - use crate::OracleError; - const PRICE_T_SIZE: usize = size_of::(); - const PRICE_ACCOUNT_SIZE: usize = size_of::(); - #[cfg(not(target_arch = "bpf"))] - #[link(name = "cpyth-native")] - extern "C" { - pub fn c_upd_aggregate(_input: *mut u8, clock_slot: u64, clock_timestamp: i64) -> bool; - } - fn send_lamports<'a>( - from: &AccountInfo<'a>, - to: &AccountInfo<'a>, - system_program: &AccountInfo<'a>, - amount: u64, - ) -> Result<(), ProgramError> { - let transfer_instruction = transfer(from.key, to.key, amount); - invoke( - &transfer_instruction, - &[from.clone(), to.clone(), system_program.clone()], - )?; - Ok(()) - } - /// resizes a price account so that it fits the Time Machine - /// key[0] funding account [signer writable] - /// key[1] price account [Signer writable] - /// key[2] system program [readable] - pub fn resize_price_account( - program_id: &Pubkey, - accounts: &[AccountInfo], - _instruction_data: &[u8], - ) -> ProgramResult { - let [funding_account_info, price_account_info, system_program] = match accounts { - [x, y, z] => Ok([x, y, z]), - _ => Err(ProgramError::InvalidArgument), - }?; - check_valid_funding_account(funding_account_info)?; - check_valid_signable_account(program_id, price_account_info, size_of::())?; - pyth_assert( - check_id(system_program.key), - OracleError::InvalidSystemAccount.into(), - )?; - { - load_checked::(price_account_info, PC_VERSION)?; - } - let account_len = price_account_info.try_data_len()?; - match account_len { - PRICE_T_SIZE => { - let rent: Rent = Default::default(); - let lamports_needed: u64 = rent - .minimum_balance(size_of::()) - .saturating_sub(price_account_info.lamports()); - if lamports_needed > 0 { - send_lamports( - funding_account_info, - price_account_info, - system_program, - lamports_needed, - )?; - } - price_account_info.realloc(size_of::(), false)?; - let mut price_account = - load_checked::(price_account_info, PC_VERSION)?; - price_account.initialize_time_machine()?; - Ok(()) - } - PRICE_ACCOUNT_SIZE => Ok(()), - _ => Err(ProgramError::InvalidArgument), - } - } - /// 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: &[AccountInfo], - instruction_data: &[u8], - ) -> ProgramResult { - let [funding_account, fresh_mapping_account] = match accounts { - [x, y] => Ok([x, y]), - _ => Err(ProgramError::InvalidArgument), - }?; - check_valid_funding_account(funding_account)?; - check_valid_signable_account( - program_id, - fresh_mapping_account, - size_of::(), - )?; - check_valid_fresh_account(fresh_mapping_account)?; - let hdr = load::(instruction_data)?; - initialize_pyth_account_checked::(fresh_mapping_account, hdr.ver_)?; - Ok(()) - } - pub fn add_mapping( - program_id: &Pubkey, - accounts: &[AccountInfo], - instruction_data: &[u8], - ) -> ProgramResult { - let [funding_account, cur_mapping, next_mapping] = match accounts { - [x, y, z] => Ok([x, y, z]), - _ => Err(ProgramError::InvalidArgument), - }?; - check_valid_funding_account(funding_account)?; - check_valid_signable_account(program_id, cur_mapping, size_of::())?; - check_valid_signable_account(program_id, next_mapping, size_of::())?; - check_valid_fresh_account(next_mapping)?; - let hdr = load::(instruction_data)?; - let mut cur_mapping = load_checked::(cur_mapping, hdr.ver_)?; - pyth_assert( - cur_mapping.num_ == PC_MAP_TABLE_SIZE && pubkey_is_zero(&cur_mapping.next_), - ProgramError::InvalidArgument, - )?; - initialize_pyth_account_checked::(next_mapping, hdr.ver_)?; - pubkey_assign(&mut cur_mapping.next_, &next_mapping.key.to_bytes()); - Ok(()) - } - /// a publisher updates a price - /// accounts[0] publisher account [signer writable] - /// accounts[1] price account to update [writable] - /// accounts[2] sysvar clock [] - pub fn upd_price( - program_id: &Pubkey, - accounts: &[AccountInfo], - instruction_data: &[u8], - ) -> ProgramResult { - let cmd_args = load::(instruction_data)?; - let [funding_account, price_account, clock_account] = match accounts { - [x, y, z] => Ok([x, y, z]), - [x, y, _, z] => Ok([x, y, z]), - _ => Err(ProgramError::InvalidArgument), - }?; - check_valid_funding_account(funding_account)?; - check_valid_writable_account(program_id, price_account, size_of::())?; - let clock = Clock::from_account_info(clock_account)?; - let mut publisher_index: usize = 0; - let latest_aggregate_price: pc_price_info_t; - { - let price_data = load_checked::(price_account, cmd_args.ver_)?; - while publisher_index < price_data.num_ as usize { - if pubkey_equal( - &price_data.comp_[publisher_index].pub_, - &funding_account.key.to_bytes(), - ) { - break; - } - publisher_index += 1; - } - pyth_assert( - publisher_index < price_data.num_ as usize, - ProgramError::InvalidArgument, - )?; - latest_aggregate_price = price_data.agg_; - let latest_publisher_price = price_data.comp_[publisher_index].latest_; - pyth_assert( - !is_component_update(cmd_args)? - || cmd_args.pub_slot_ > latest_publisher_price.pub_slot_, - ProgramError::InvalidArgument, - )?; - } - let mut aggregate_updated = false; - if clock.slot > latest_aggregate_price.pub_slot_ { - unsafe { - aggregate_updated = c_upd_aggregate( - price_account.try_borrow_mut_data()?.as_mut_ptr(), - clock.slot, - clock.unix_timestamp, - ); - } - } - let account_len = price_account.try_data_len()?; - if aggregate_updated && account_len == PRICE_ACCOUNT_SIZE { - let mut price_account = load_account_as_mut::(price_account)?; - price_account.add_price_to_time_machine()?; - } - if is_component_update(cmd_args)? { - let mut status: u32 = cmd_args.status_; - let mut threshold_conf = cmd_args.price_ / PC_MAX_CI_DIVISOR as i64; - if threshold_conf < 0 { - threshold_conf = -threshold_conf; - } - if cmd_args.conf_ > try_convert::<_, u64>(threshold_conf)? { - status = PC_STATUS_UNKNOWN - } - { - let mut price_data = load_checked::(price_account, cmd_args.ver_)?; - let publisher_price = &mut price_data.comp_[publisher_index].latest_; - publisher_price.price_ = cmd_args.price_; - publisher_price.conf_ = cmd_args.conf_; - publisher_price.status_ = status; - publisher_price.pub_slot_ = cmd_args.pub_slot_; - } - } - Ok(()) - } - pub fn upd_price_no_fail_on_error( - program_id: &Pubkey, - accounts: &[AccountInfo], - instruction_data: &[u8], - ) -> ProgramResult { - match upd_price(program_id, accounts, instruction_data) { - Err(_) => Ok(()), - Ok(value) => Ok(value), - } - } - /// 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], - ) -> ProgramResult { - let cmd_args = load::(instruction_data)?; - check_exponent_range(cmd_args.expo_)?; - pyth_assert( - cmd_args.ptype_ != PC_PTYPE_UNKNOWN, - ProgramError::InvalidArgument, - )?; - let [funding_account, product_account, price_account] = match accounts { - [x, y, z] => Ok([x, y, z]), - _ => Err(ProgramError::InvalidArgument), - }?; - check_valid_funding_account(funding_account)?; - check_valid_signable_account(program_id, product_account, PC_PROD_ACC_SIZE as usize)?; - check_valid_signable_account(program_id, price_account, size_of::())?; - check_valid_fresh_account(price_account)?; - let mut product_data = load_checked::(product_account, cmd_args.ver_)?; - let mut price_data = - initialize_pyth_account_checked::(price_account, cmd_args.ver_)?; - price_data.expo_ = cmd_args.expo_; - price_data.ptype_ = cmd_args.ptype_; - 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(()) - } - /// Delete a price account. This function will remove the link between the price account and its - /// corresponding product account, then transfer any SOL in the price account to the funding - /// account. This function can only delete the first price account in the linked list of - /// price accounts for the given product. - /// - /// Warning: This function is dangerous and will break any programs that depend on the deleted - /// price account! - pub fn del_price( - program_id: &Pubkey, - accounts: &[AccountInfo], - instruction_data: &[u8], - ) -> ProgramResult { - let [funding_account, product_account, price_account] = match accounts { - [w, x, y] => Ok([w, x, y]), - _ => Err(ProgramError::InvalidArgument), - }?; - check_valid_funding_account(funding_account)?; - check_valid_signable_account(program_id, product_account, PC_PROD_ACC_SIZE as usize)?; - check_valid_signable_account(program_id, price_account, size_of::())?; - { - let cmd_args = load::(instruction_data)?; - let mut product_data = load_checked::(product_account, cmd_args.ver_)?; - let price_data = load_checked::(price_account, cmd_args.ver_)?; - pyth_assert( - pubkey_equal(&product_data.px_acc_, &price_account.key.to_bytes()), - ProgramError::InvalidArgument, - )?; - pyth_assert( - pubkey_equal(&price_data.prod_, &product_account.key.to_bytes()), - ProgramError::InvalidArgument, - )?; - pubkey_assign(&mut product_data.px_acc_, bytes_of(&price_data.next_)); - } - let lamports = price_account.lamports(); - **price_account.lamports.borrow_mut() = 0; - **funding_account.lamports.borrow_mut() += lamports; - Ok(()) - } - pub fn init_price( - program_id: &Pubkey, - accounts: &[AccountInfo], - instruction_data: &[u8], - ) -> ProgramResult { - let cmd_args = load::(instruction_data)?; - check_exponent_range(cmd_args.expo_)?; - let [funding_account, price_account] = match accounts { - [x, y] => Ok([x, y]), - _ => Err(ProgramError::InvalidArgument), - }?; - check_valid_funding_account(funding_account)?; - check_valid_signable_account(program_id, price_account, size_of::())?; - let mut price_data = load_checked::(price_account, cmd_args.ver_)?; - pyth_assert( - price_data.ptype_ == cmd_args.ptype_, - ProgramError::InvalidArgument, - )?; - price_data.expo_ = cmd_args.expo_; - price_data.last_slot_ = 0; - price_data.valid_slot_ = 0; - price_data.agg_.pub_slot_ = 0; - price_data.prev_slot_ = 0; - price_data.prev_price_ = 0; - price_data.prev_conf_ = 0; - price_data.prev_timestamp_ = 0; - sol_memset( - bytes_of_mut(&mut price_data.twap_), - 0, - size_of::(), - ); - sol_memset( - bytes_of_mut(&mut price_data.twac_), - 0, - size_of::(), - ); - sol_memset( - bytes_of_mut(&mut price_data.agg_), - 0, - size_of::(), - ); - for i in 0..(price_data.comp_.len() as usize) { - sol_memset( - bytes_of_mut(&mut price_data.comp_[i].agg_), - 0, - size_of::(), - ); - sol_memset( - bytes_of_mut(&mut price_data.comp_[i].latest_), - 0, - size_of::(), - ); - } - Ok(()) - } - /// add a publisher to a price account - /// accounts[0] funding account [signer writable] - /// accounts[1] price account to add the publisher to [signer writable] - pub fn add_publisher( - program_id: &Pubkey, - accounts: &[AccountInfo], - instruction_data: &[u8], - ) -> ProgramResult { - let cmd_args = load::(instruction_data)?; - pyth_assert( - instruction_data.len() == size_of::() - && !pubkey_is_zero(&cmd_args.pub_), - ProgramError::InvalidArgument, - )?; - let [funding_account, price_account] = match accounts { - [x, y] => Ok([x, y]), - _ => Err(ProgramError::InvalidArgument), - }?; - check_valid_funding_account(funding_account)?; - check_valid_signable_account(program_id, price_account, size_of::())?; - let mut price_data = load_checked::(price_account, cmd_args.ver_)?; - if price_data.num_ >= PC_COMP_SIZE { - return Err(ProgramError::InvalidArgument); - } - for i in 0..(price_data.num_ as usize) { - if pubkey_equal(&cmd_args.pub_, bytes_of(&price_data.comp_[i].pub_)) { - return Err(ProgramError::InvalidArgument); - } - } - let current_index: usize = try_convert(price_data.num_)?; - sol_memset( - bytes_of_mut(&mut price_data.comp_[current_index]), - 0, - size_of::(), - ); - pubkey_assign( - &mut price_data.comp_[current_index].pub_, - bytes_of(&cmd_args.pub_), - ); - price_data.num_ += 1; - price_data.size_ = - try_convert::<_, u32>(size_of::() - size_of_val(&price_data.comp_))? - + price_data.num_ * try_convert::<_, u32>(size_of::())?; - Ok(()) - } - /// add a publisher to a price account - /// accounts[0] funding account [signer writable] - /// accounts[1] price account to delete the publisher from [signer writable] - pub fn del_publisher( - program_id: &Pubkey, - accounts: &[AccountInfo], - instruction_data: &[u8], - ) -> ProgramResult { - let cmd_args = load::(instruction_data)?; - pyth_assert( - instruction_data.len() == size_of::() - && !pubkey_is_zero(&cmd_args.pub_), - ProgramError::InvalidArgument, - )?; - let [funding_account, price_account] = match accounts { - [x, y] => Ok([x, y]), - _ => Err(ProgramError::InvalidArgument), - }?; - check_valid_funding_account(funding_account)?; - check_valid_signable_account(program_id, price_account, size_of::())?; - let mut price_data = load_checked::(price_account, cmd_args.ver_)?; - for i in 0..(price_data.num_ as usize) { - if pubkey_equal(&cmd_args.pub_, bytes_of(&price_data.comp_[i].pub_)) { - for j in i + 1..(price_data.num_ as usize) { - price_data.comp_[j - 1] = price_data.comp_[j]; - } - price_data.num_ -= 1; - let current_index: usize = try_convert(price_data.num_)?; - sol_memset( - bytes_of_mut(&mut price_data.comp_[current_index]), - 0, - size_of::(), - ); - price_data.size_ = try_convert::<_, u32>( - size_of::() - size_of_val(&price_data.comp_), - )? + price_data.num_ - * try_convert::<_, u32>(size_of::())?; - return Ok(()); - } - } - Err(ProgramError::InvalidArgument) - } - pub fn add_product( - program_id: &Pubkey, - accounts: &[AccountInfo], - instruction_data: &[u8], - ) -> ProgramResult { - let [funding_account, tail_mapping_account, new_product_account] = match accounts { - [x, y, z] => Ok([x, y, z]), - _ => Err(ProgramError::InvalidArgument), - }?; - check_valid_funding_account(funding_account)?; - check_valid_signable_account( - program_id, - tail_mapping_account, - size_of::(), - )?; - check_valid_signable_account(program_id, new_product_account, PC_PROD_ACC_SIZE as usize)?; - check_valid_fresh_account(new_product_account)?; - let hdr = load::(instruction_data)?; - let mut mapping_data = load_checked::(tail_mapping_account, hdr.ver_)?; - pyth_assert( - mapping_data.num_ < PC_MAP_TABLE_SIZE, - ProgramError::InvalidArgument, - )?; - initialize_pyth_account_checked::(new_product_account, hdr.ver_)?; - let current_index: usize = try_convert(mapping_data.num_)?; - pubkey_assign( - &mut mapping_data.prod_[current_index], - bytes_of(&new_product_account.key.to_bytes()), - ); - mapping_data.num_ += 1; - mapping_data.size_ = - try_convert::<_, u32>(size_of::() - size_of_val(&mapping_data.prod_))? - + mapping_data.num_ * try_convert::<_, u32>(size_of::())?; - Ok(()) - } - /// Update the metadata associated with a product, overwriting any existing metadata. - /// The metadata is provided as a list of key-value pairs at the end of the `instruction_data`. - pub fn upd_product( - program_id: &Pubkey, - accounts: &[AccountInfo], - instruction_data: &[u8], - ) -> ProgramResult { - let [funding_account, product_account] = match accounts { - [x, y] => Ok([x, y]), - _ => Err(ProgramError::InvalidArgument), - }?; - check_valid_funding_account(funding_account)?; - check_valid_signable_account(program_id, product_account, try_convert(PC_PROD_ACC_SIZE)?)?; - let hdr = load::(instruction_data)?; - { - let mut _product_data = load_checked::(product_account, hdr.ver_)?; - } - pyth_assert( - instruction_data.len() >= size_of::(), - ProgramError::InvalidInstructionData, - )?; - let new_data_len = instruction_data.len() - size_of::(); - let max_data_len = try_convert::<_, usize>(PC_PROD_ACC_SIZE)? - size_of::(); - pyth_assert(new_data_len <= max_data_len, ProgramError::InvalidArgument)?; - let new_data = &instruction_data[size_of::()..instruction_data.len()]; - let mut idx = 0; - while idx < new_data.len() { - let key = read_pc_str_t(&new_data[idx..])?; - idx += key.len(); - let value = read_pc_str_t(&new_data[idx..])?; - idx += value.len(); - } - pyth_assert(idx == new_data.len(), ProgramError::InvalidArgument)?; - { - let mut data = product_account.try_borrow_mut_data()?; - sol_memcpy( - &mut data[size_of::()..], - new_data, - new_data.len(), - ); - } - let mut product_data = load_checked::(product_account, hdr.ver_)?; - product_data.size_ = try_convert(size_of::() + new_data.len())?; - Ok(()) - } - pub fn set_min_pub( - program_id: &Pubkey, - accounts: &[AccountInfo], - instruction_data: &[u8], - ) -> ProgramResult { - let cmd = load::(instruction_data)?; - pyth_assert( - instruction_data.len() == size_of::(), - ProgramError::InvalidArgument, - )?; - let [funding_account, price_account] = match accounts { - [x, y] => Ok([x, y]), - _ => Err(ProgramError::InvalidArgument), - }?; - check_valid_funding_account(funding_account)?; - check_valid_signable_account(program_id, price_account, size_of::())?; - let mut price_account_data = load_checked::(price_account, cmd.ver_)?; - price_account_data.min_pub_ = cmd.min_pub_; - Ok(()) - } -} -mod time_machine_types { - use crate::c_oracle_header::{ - pc_price_t, PythAccount, EXTRA_PUBLISHER_SPACE, PC_ACCTYPE_PRICE, PC_PRICE_T_COMP_OFFSET, - }; - use crate::error::OracleError; - use bytemuck::{Pod, Zeroable}; - use solana_program::msg; - #[repr(C)] - /// this wraps multiple SMA and tick trackers, and includes all the state - /// used by the time machine - pub struct TimeMachineWrapper { - place_holder: [u8; 1864], - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::fmt::Debug for TimeMachineWrapper { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self { - Self { - place_holder: ref __self_0_0, - } => { - let debug_trait_builder = - &mut ::core::fmt::Formatter::debug_struct(f, "TimeMachineWrapper"); - let _ = ::core::fmt::DebugStruct::field( - debug_trait_builder, - "place_holder", - &&(*__self_0_0), - ); - ::core::fmt::DebugStruct::finish(debug_trait_builder) - } - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for TimeMachineWrapper { - #[inline] - fn clone(&self) -> TimeMachineWrapper { - { - let _: ::core::clone::AssertParamIsClone<[u8; 1864]>; - *self - } - } - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for TimeMachineWrapper {} - #[repr(C)] - /// wraps everything stored in a price account - pub struct PriceAccountWrapper { - pub price_data: pc_price_t, - pub extra_publisher_space: [u8; EXTRA_PUBLISHER_SPACE as usize], - pub time_machine: TimeMachineWrapper, - } - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::marker::Copy for PriceAccountWrapper {} - #[automatically_derived] - #[allow(unused_qualifications)] - impl ::core::clone::Clone for PriceAccountWrapper { - #[inline] - fn clone(&self) -> PriceAccountWrapper { - { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone<[u8; EXTRA_PUBLISHER_SPACE as usize]>; - let _: ::core::clone::AssertParamIsClone; - *self - } - } - } - impl PriceAccountWrapper { - pub fn initialize_time_machine(&mut self) -> Result<(), OracleError> { - ::solana_program::log::sol_log("implement me"); - Ok(()) - } - pub fn add_price_to_time_machine(&mut self) -> Result<(), OracleError> { - ::solana_program::log::sol_log("implement me"); - Ok(()) - } - } - #[cfg(target_endian = "little")] - unsafe impl Zeroable for PriceAccountWrapper {} - #[cfg(target_endian = "little")] - unsafe impl Pod for PriceAccountWrapper {} - impl PythAccount for PriceAccountWrapper { - const ACCOUNT_TYPE: u32 = PC_ACCTYPE_PRICE; - const INITIAL_SIZE: u32 = PC_PRICE_T_COMP_OFFSET as u32; - } -} -mod instruction { - use num_derive::FromPrimitive; - #[repr(i32)] - pub enum OracleCommand { - InitMapping, - AddMapping, - AddProduct, - UpdProduct, - AddPrice, - AddPublisher, - DelPublisher, - UpdPrice, - AggPrice, - InitPrice, - InitTest, - UpdTest, - SetMinPub, - UpdPriceNoFailOnError, - ResizePriceAccount, - DelPrice, - } - #[allow(non_upper_case_globals, unused_qualifications)] - const _IMPL_NUM_FromPrimitive_FOR_OracleCommand: () = { - #[allow(clippy::useless_attribute)] - #[allow(rust_2018_idioms)] - extern crate num_traits as _num_traits; - impl _num_traits::FromPrimitive for OracleCommand { - #[allow(trivial_numeric_casts)] - #[inline] - fn from_i64(n: i64) -> Option { - if n == OracleCommand::InitMapping as i64 { - Some(OracleCommand::InitMapping) - } else if n == OracleCommand::AddMapping as i64 { - Some(OracleCommand::AddMapping) - } else if n == OracleCommand::AddProduct as i64 { - Some(OracleCommand::AddProduct) - } else if n == OracleCommand::UpdProduct as i64 { - Some(OracleCommand::UpdProduct) - } else if n == OracleCommand::AddPrice as i64 { - Some(OracleCommand::AddPrice) - } else if n == OracleCommand::AddPublisher as i64 { - Some(OracleCommand::AddPublisher) - } else if n == OracleCommand::DelPublisher as i64 { - Some(OracleCommand::DelPublisher) - } else if n == OracleCommand::UpdPrice as i64 { - Some(OracleCommand::UpdPrice) - } else if n == OracleCommand::AggPrice as i64 { - Some(OracleCommand::AggPrice) - } else if n == OracleCommand::InitPrice as i64 { - Some(OracleCommand::InitPrice) - } else if n == OracleCommand::InitTest as i64 { - Some(OracleCommand::InitTest) - } else if n == OracleCommand::UpdTest as i64 { - Some(OracleCommand::UpdTest) - } else if n == OracleCommand::SetMinPub as i64 { - Some(OracleCommand::SetMinPub) - } else if n == OracleCommand::UpdPriceNoFailOnError as i64 { - Some(OracleCommand::UpdPriceNoFailOnError) - } else if n == OracleCommand::ResizePriceAccount as i64 { - Some(OracleCommand::ResizePriceAccount) - } else if n == OracleCommand::DelPrice as i64 { - Some(OracleCommand::DelPrice) - } else { - None - } - } - #[inline] - fn from_u64(n: u64) -> Option { - Self::from_i64(n as i64) - } - } - }; -} -mod utils { - use crate::c_oracle_header::{ - cmd_upd_price_t, command_t_e_cmd_upd_price, command_t_e_cmd_upd_price_no_fail_on_error, - pc_acc, pc_pub_key_t, PC_MAX_NUM_DECIMALS, - }; - use crate::deserialize::load_account_as; - use crate::OracleError; - use solana_program::account_info::AccountInfo; - use solana_program::program_error::ProgramError; - use solana_program::program_memory::sol_memset; - use solana_program::pubkey::Pubkey; - use solana_program::sysvar::rent::Rent; - use std::borrow::BorrowMut; - pub fn pyth_assert(condition: bool, error_code: ProgramError) -> Result<(), ProgramError> { - if !condition { - Result::Err(error_code) - } else { - Result::Ok(()) - } - } - /// Sets the data of account to all-zero - pub 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(()) - } - pub fn valid_funding_account(account: &AccountInfo) -> bool { - account.is_signer && account.is_writable - } - pub fn check_valid_funding_account(account: &AccountInfo) -> Result<(), ProgramError> { - pyth_assert( - valid_funding_account(account), - OracleError::InvalidFundingAccount.into(), - ) - } - 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()) - } - pub fn check_valid_signable_account( - program_id: &Pubkey, - account: &AccountInfo, - minimum_size: usize, - ) -> Result<(), ProgramError> { - pyth_assert( - valid_signable_account(program_id, account, minimum_size), - OracleError::InvalidSignableAccount.into(), - ) - } - /// 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. - pub 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, - } - } - pub fn check_valid_fresh_account(account: &AccountInfo) -> Result<(), ProgramError> { - pyth_assert( - valid_fresh_account(account), - OracleError::InvalidFreshAccount.into(), - ) - } - pub fn check_exponent_range(expo: i32) -> Result<(), ProgramError> { - pyth_assert( - expo >= -(PC_MAX_NUM_DECIMALS as i32) && expo <= PC_MAX_NUM_DECIMALS as i32, - ProgramError::InvalidArgument, - ) - } - pub fn pubkey_assign(target: &mut pc_pub_key_t, source: &[u8]) { - unsafe { target.k1_.copy_from_slice(source) } - } - pub fn pubkey_is_zero(key: &pc_pub_key_t) -> bool { - return unsafe { key.k8_.iter().all(|x| *x == 0) }; - } - pub fn pubkey_equal(target: &pc_pub_key_t, source: &[u8]) -> bool { - unsafe { target.k1_ == *source } - } - /// Convert `x: T` into a `U`, returning the appropriate `OracleError` if the conversion fails. - pub fn try_convert>(x: T) -> Result { - U::try_from(x).map_err(|_| OracleError::IntegerCastingError) - } - /// Read a `pc_str_t` from the beginning of `source`. Returns a slice of `source` containing - /// the bytes of the `pc_str_t`. - pub fn read_pc_str_t(source: &[u8]) -> Result<&[u8], ProgramError> { - if source.is_empty() { - Err(ProgramError::InvalidArgument) - } else { - let tag_len: usize = try_convert(source[0])?; - if tag_len + 1 > source.len() { - Err(ProgramError::InvalidArgument) - } else { - Ok(&source[..(1 + tag_len)]) - } - } - } - fn valid_writable_account( - program_id: &Pubkey, - account: &AccountInfo, - minimum_size: usize, - ) -> bool { - account.is_writable - && account.owner == program_id - && account.data_len() >= minimum_size - && Rent::default().is_exempt(account.lamports(), account.data_len()) - } - pub fn check_valid_writable_account( - program_id: &Pubkey, - account: &AccountInfo, - minimum_size: usize, - ) -> Result<(), ProgramError> { - pyth_assert( - valid_writable_account(program_id, account, minimum_size), - OracleError::InvalidWritableAccount.into(), - ) - } - /// Checks whether this instruction is trying to update an individual publisher's price (`true`) or - /// is only trying to refresh the aggregate (`false`) - pub fn is_component_update(cmd_args: &cmd_upd_price_t) -> Result { - Ok( - try_convert::<_, u32>(cmd_args.cmd_)? == command_t_e_cmd_upd_price - || try_convert::<_, u32>(cmd_args.cmd_)? - == command_t_e_cmd_upd_price_no_fail_on_error, - ) - } -} -use crate::error::OracleError; -use processor::process_instruction; -use solana_program::entrypoint; -/// # Safety -#[no_mangle] -pub unsafe extern "C" fn entrypoint(input: *mut u8) -> u64 { - let (program_id, accounts, instruction_data) = - unsafe { ::solana_program::entrypoint::deserialize(input) }; - match process_instruction(&program_id, &accounts, &instruction_data) { - Ok(()) => ::solana_program::entrypoint::SUCCESS, - Err(error) => error.into(), - } -} diff --git a/program/rust/output.rscargo b/program/rust/output.rscargo deleted file mode 100644 index e69de29bb..000000000 From dc4eec52ba3eb93266251330c12417f1da9e4b3a Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Alapont Date: Mon, 22 Aug 2022 15:31:19 -0500 Subject: [PATCH 7/8] Explicit instruction order --- program/rust/src/instruction.rs | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/program/rust/src/instruction.rs b/program/rust/src/instruction.rs index f5ea4cca1..bd994f2f0 100644 --- a/program/rust/src/instruction.rs +++ b/program/rust/src/instruction.rs @@ -11,77 +11,78 @@ use num_derive::{ }; use num_traits::FromPrimitive; +/// WARNING : NEW COMMANDS SHOULD BE ADDED AT THE END OF THE LIST #[repr(i32)] #[derive(FromPrimitive, ToPrimitive)] pub enum OracleCommand { // initialize first mapping list account // account[0] funding account [signer writable] // account[1] mapping account [signer writable] - InitMapping, + InitMapping = 0, // initialize and add new mapping account // account[0] funding account [signer writable] // account[1] tail mapping account [signer writable] // account[2] new mapping account [signer writable] - AddMapping, + AddMapping = 1, // initialize and add new product reference data account // account[0] funding account [signer writable] // account[1] mapping account [signer writable] // account[2] new product account [signer writable] - AddProduct, + AddProduct = 2, // update product account // account[0] funding account [signer writable] // account[1] product account [signer writable] - UpdProduct, + UpdProduct = 3, // add new price account to a product account // account[0] funding account [signer writable] // account[1] product account [signer writable] // account[2] new price account [signer writable] - AddPrice, + AddPrice = 4, // add publisher to symbol account // account[0] funding account [signer writable] // account[1] price account [signer writable] - AddPublisher, + AddPublisher = 5, // delete publisher from symbol account // account[0] funding account [signer writable] // account[1] price account [signer writable] - DelPublisher, + DelPublisher = 6, // publish component price // account[0] funding account [signer writable] // account[1] price account [writable] // account[2] sysvar_clock account [] - UpdPrice, + UpdPrice = 7, // compute aggregate price // account[0] funding account [signer writable] // account[1] price account [writable] // account[2] sysvar_clock account [] - AggPrice, + AggPrice = 8, // (re)initialize price account // account[0] funding account [signer writable] // account[1] new price account [signer writable] - InitPrice, + InitPrice = 9, // deprecated - InitTest, + InitTest = 10, // deprecated - UpdTest, + UpdTest = 11, // set min publishers // account[0] funding account [signer writable] // account[1] price account [signer writable] - SetMinPub, + SetMinPub = 12, // publish component price, never returning an error even if the update failed // account[0] funding account [signer writable] // account[1] price account [writable] // account[2] sysvar_clock account [] - UpdPriceNoFailOnError, + UpdPriceNoFailOnError = 13, // resizes a price account so that it fits the Time Machine // account[0] funding account [signer writable] // account[1] price account [signer writable] // account[2] system program [] - ResizePriceAccount, + ResizePriceAccount = 14, // deletes a price account // account[0] funding account [signer writable] // account[1] product account [signer writable] // account[2] price account [signer writable] - DelPrice, + DelPrice = 15, } #[repr(C)] From 5d613b1aa345cdd756c0da98784080be8e56987c Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Alapont Date: Mon, 22 Aug 2022 15:46:00 -0500 Subject: [PATCH 8/8] Fix rust oracle --- program/rust/src/rust_oracle.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 653b796cd..bf9a7ccf0 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -52,6 +52,7 @@ use crate::deserialize::{ load_account_as_mut, load_checked, }; +use crate::instruction::CommandHeader; use crate::time_machine_types::PriceAccountWrapper; use crate::utils::{ check_exponent_range, @@ -728,9 +729,9 @@ pub fn del_product( check_valid_signable_account(program_id, product_account, PC_PROD_ACC_SIZE as usize)?; { - let cmd_args = load::(instruction_data)?; - let mut mapping_data = load_checked::(mapping_account, cmd_args.ver_)?; - let product_data = load_checked::(product_account, cmd_args.ver_)?; + let cmd_args = load::(instruction_data)?; + let mut mapping_data = load_checked::(mapping_account, cmd_args.version)?; + let product_data = load_checked::(product_account, cmd_args.version)?; // This assertion is just to make the subtractions below simpler pyth_assert(mapping_data.num_ >= 1, ProgramError::InvalidArgument)?;