Skip to content

Commit 70912fd

Browse files
committed
refactor: separate header checks and account data casts
1 parent fe2abc4 commit 70912fd

File tree

1 file changed

+25
-27
lines changed

1 file changed

+25
-27
lines changed

program/rust/src/validator.rs

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -45,35 +45,9 @@ fn check_price_account_header(price_account_info: &[u8]) -> Result<(), ProgramEr
4545
&& account_header.account_type == PriceAccount::ACCOUNT_TYPE,
4646
OracleError::InvalidAccountHeader.into(),
4747
)?;
48-
4948
Ok(())
5049
}
5150

52-
// Attempts to validate and access the contents of an account as a PriceAccount.
53-
pub fn validate_price_account(
54-
price_account_info: &mut [u8],
55-
) -> Result<&mut PriceAccount, AggregationError> {
56-
check_price_account_header(price_account_info)
57-
.map_err(|_| AggregationError::NotPriceFeedAccount)?;
58-
59-
let data = bytemuck::from_bytes_mut::<PriceAccount>(
60-
&mut price_account_info[0..size_of::<PriceAccount>()],
61-
);
62-
if !data.flags.contains(PriceAccountFlags::ACCUMULATOR_V2) {
63-
return Err(AggregationError::V1AggregationMode);
64-
}
65-
if !data
66-
.flags
67-
.contains(PriceAccountFlags::MESSAGE_BUFFER_CLEARED)
68-
{
69-
// We make sure that we don't generate v2 messages while v1 messages are still
70-
// in the message buffer.
71-
return Err(AggregationError::V1AggregationMode);
72-
}
73-
74-
Ok(data)
75-
}
76-
7751
fn update_aggregate(slot: u64, timestamp: i64, price_account: &mut PriceAccount) {
7852
// NOTE: c_upd_aggregate must use a raw pointer to price data. We already
7953
// have the exclusive mut reference so we can simply cast before calling
@@ -125,6 +99,21 @@ pub fn aggregate_price(
12599
price_account_pubkey: &Pubkey,
126100
price_account: &mut PriceAccount,
127101
) -> Result<[Vec<u8>; 2], AggregationError> {
102+
if !price_account
103+
.flags
104+
.contains(PriceAccountFlags::ACCUMULATOR_V2)
105+
{
106+
return Err(AggregationError::V1AggregationMode);
107+
}
108+
if !price_account
109+
.flags
110+
.contains(PriceAccountFlags::MESSAGE_BUFFER_CLEARED)
111+
{
112+
// We make sure that we don't generate v2 messages while v1 messages are still
113+
// in the message buffer.
114+
return Err(AggregationError::V1AggregationMode);
115+
}
116+
128117
if price_account.agg_.pub_slot_ == slot {
129118
// Avoid v2 aggregation if v1 aggregation has happened in the same slot
130119
// (this should normally happen only in the slot that contains the v1->v2 transition).
@@ -142,13 +131,22 @@ pub fn aggregate_price(
142131
}
143132

144133
/// Load a price account as read-only, returning `None` if it isn't a valid price account.
145-
fn checked_load_price_account(price_account_info: &[u8]) -> Option<&PriceAccount> {
134+
pub fn checked_load_price_account(price_account_info: &[u8]) -> Option<&PriceAccount> {
146135
check_price_account_header(price_account_info).ok()?;
147136
Some(bytemuck::from_bytes::<PriceAccount>(
148137
&price_account_info[0..size_of::<PriceAccount>()],
149138
))
150139
}
151140

141+
pub fn checked_load_price_account_mut(
142+
price_account_info: &mut [u8],
143+
) -> Result<&mut PriceAccount, ProgramError> {
144+
check_price_account_header(price_account_info)?;
145+
Ok(bytemuck::from_bytes_mut::<PriceAccount>(
146+
&mut price_account_info[0..size_of::<PriceAccount>()],
147+
))
148+
}
149+
152150
/// Computes the stake caps for each publisher based on the oracle program accounts provided
153151
/// - `account_datas` - the account datas of the oracle program accounts
154152
/// - `timestamp` - the timestamp to include in the message

0 commit comments

Comments
 (0)