From b05b069e4856245681728e8d27b47c28e1c92a95 Mon Sep 17 00:00:00 2001 From: De Facto Date: Thu, 4 Feb 2021 18:23:32 +0800 Subject: [PATCH] function to read resolved median --- program/src/error.rs | 3 ++ program/src/lib.rs | 66 ++++++++++++++++++++++++++++---------------- 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/program/src/error.rs b/program/src/error.rs index 09b6bdb..d9e7d26 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -34,6 +34,9 @@ pub enum Error { #[error("Rewards overflow")] RewardsOverflow, + #[error("No resolve answer")] + NoResolvedAnswer, + #[error("Unknown error")] UnknownError, } diff --git a/program/src/lib.rs b/program/src/lib.rs index 30a8ce0..18988af 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -9,38 +9,56 @@ pub mod instruction; pub mod processor; pub mod state; +use crate::error::Error; +use borsh_state::InitBorshState; +use solana_program::{ + account_info::AccountInfo, program_error::ProgramError, program_pack::IsInitialized, +}; +use state::Aggregator; + #[cfg(not(feature = "no-entrypoint"))] pub mod entrypoint; -/// Get median value from the aggregator account -// pub fn get_median(aggregator_info: &AccountInfo) -> Result { -// let aggregator = Aggregator::unpack_unchecked(&aggregator_info.data.borrow())?; -// if !aggregator.is_initialized { -// return Err(Error::NotFoundAggregator.into()); -// } +pub struct ResolvedMedian { + pub value: u64, + pub updated_at: u64, + pub created_at: u64, +} -// let submissions = aggregator.submissions; +/// Read resolved median value from the aggregator +pub fn read_median(aggregator_info: &AccountInfo) -> Result { + let aggregator = Aggregator::load_initialized(&aggregator_info)?; -// let mut values = vec![]; + if !aggregator.answer.is_initialized() { + return Err(Error::NoResolvedAnswer)?; + } -// // if the submission value is 0, maybe the oracle is not initialized -// for s in &submissions { -// if s.value != 0 { -// values.push(s.value); -// } -// } + let mut values: Vec<_> = aggregator + .answer + .submissions + .iter() + .filter(|s| s.is_initialized()) + .map(|s| s.value) + .collect(); -// // get median value -// values.sort(); + // get median value + values.sort(); -// let l = values.len(); -// let i = l / 2; -// if l % 2 == 0 { -// return Ok((values[i] + values[i - 1]) / 2); -// } else { -// return Ok(values[i]); -// } -// } + let median: u64; + let l = values.len(); + let i = l / 2; + if l % 2 == 0 { + median = (values[i] + values[i - 1]) / 2; + } else { + median = values[i]; + } + + Ok(ResolvedMedian { + value: median, + updated_at: aggregator.answer.updated_at, + created_at: aggregator.answer.created_at, + }) +} // Export current sdk types for downstream users building with a different pub use solana_program;