oracle: don't force logging in OracleState functions (#828)

The msg!() caused writes to stdout in the liquidator etc in codepaths
that just wanted to check if the oracle was usable.
This commit is contained in:
Christian Kamm 2024-01-03 08:37:35 +01:00 committed by GitHub
parent f10fc01388
commit 34aebf01f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 33 deletions

View File

@ -373,7 +373,6 @@ pub async fn init(
{
if unchecked_oracle_state
.check_confidence_and_maybe_staleness(
&mkt.1.name,
&oracle_config.to_oracle_config(),
None, // force this to always return a price no matter how stale
)

View File

@ -211,9 +211,14 @@ pub fn token_withdraw(ctx: Context<TokenWithdraw>, amount: u64, allow_borrow: bo
// net borrow check.
let slot_opt = Some(Clock::get()?.slot);
unsafe_oracle_state
.check_confidence_and_maybe_staleness(&bank.name(), &bank.oracle_config, slot_opt)
.check_confidence_and_maybe_staleness(&bank.oracle_config, slot_opt)
.with_context(|| {
oracle_log_context(&unsafe_oracle_state, &bank.oracle_config, slot_opt)
oracle_log_context(
bank.name(),
&unsafe_oracle_state,
&bank.oracle_config,
slot_opt,
)
})?;
bank.check_net_borrows(unsafe_oracle_state.price)?;
} else {

View File

@ -1102,8 +1102,10 @@ impl Bank {
require_keys_eq!(self.oracle, *oracle_acc.key());
let state = oracle::oracle_state_unchecked(oracle_acc, self.mint_decimals)?;
state
.check_confidence_and_maybe_staleness(&self.name(), &self.oracle_config, staleness_slot)
.with_context(|| oracle_log_context(&state, &self.oracle_config, staleness_slot))?;
.check_confidence_and_maybe_staleness(&self.oracle_config, staleness_slot)
.with_context(|| {
oracle_log_context(self.name(), &state, &self.oracle_config, staleness_slot)
})?;
Ok(state.price)
}
@ -1116,32 +1118,41 @@ impl Bank {
) -> Result<I80F48> {
require_keys_eq!(self.oracle, *oracle_acc.key());
let primary_state = oracle::oracle_state_unchecked(oracle_acc, self.mint_decimals)?;
let primary_ok = primary_state.check_confidence_and_maybe_staleness(
&self.name(),
&self.oracle_config,
staleness_slot,
);
let primary_ok =
primary_state.check_confidence_and_maybe_staleness(&self.oracle_config, staleness_slot);
if primary_ok.is_oracle_error() && fallback_oracle_acc_opt.is_some() {
let fallback_oracle_acc = fallback_oracle_acc_opt.unwrap();
require_keys_eq!(self.fallback_oracle, *fallback_oracle_acc.key());
let fallback_state =
oracle::oracle_state_unchecked(fallback_oracle_acc, self.mint_decimals)?;
let fallback_ok = fallback_state.check_confidence_and_maybe_staleness(
&self.name(),
&self.oracle_config,
staleness_slot,
);
let fallback_ok = fallback_state
.check_confidence_and_maybe_staleness(&self.oracle_config, staleness_slot);
fallback_ok.with_context(|| {
format!(
"{} {}",
oracle_log_context(&primary_state, &self.oracle_config, staleness_slot),
oracle_log_context(&fallback_state, &self.oracle_config, staleness_slot)
oracle_log_context(
self.name(),
&primary_state,
&self.oracle_config,
staleness_slot
),
oracle_log_context(
self.name(),
&fallback_state,
&self.oracle_config,
staleness_slot
)
)
})?;
Ok(fallback_state.price)
} else {
primary_ok.with_context(|| {
oracle_log_context(&primary_state, &self.oracle_config, staleness_slot)
oracle_log_context(
self.name(),
&primary_state,
&self.oracle_config,
staleness_slot,
)
})?;
Ok(primary_state.price)
}

View File

@ -105,37 +105,29 @@ impl OracleState {
#[inline]
pub fn check_confidence_and_maybe_staleness(
&self,
oracle_name: &str,
config: &OracleConfig,
staleness_slot: Option<u64>,
) -> Result<()> {
if let Some(now_slot) = staleness_slot {
self.check_staleness(oracle_name, config, now_slot)?;
self.check_staleness(config, now_slot)?;
}
self.check_confidence(oracle_name, config)
self.check_confidence(config)
}
pub fn check_staleness(
&self,
oracle_name: &str,
config: &OracleConfig,
now_slot: u64,
) -> Result<()> {
pub fn check_staleness(&self, config: &OracleConfig, now_slot: u64) -> Result<()> {
if config.max_staleness_slots >= 0
&& self
.last_update_slot
.saturating_add(config.max_staleness_slots as u64)
< now_slot
{
msg!("Oracle is stale: {}", oracle_name);
return Err(MangoError::OracleStale.into());
}
Ok(())
}
pub fn check_confidence(&self, oracle_name: &str, config: &OracleConfig) -> Result<()> {
pub fn check_confidence(&self, config: &OracleConfig) -> Result<()> {
if self.deviation > config.conf_filter * self.price {
msg!("Oracle confidence not good enough: {}", oracle_name);
return Err(MangoError::OracleConfidence.into());
}
Ok(())
@ -321,12 +313,14 @@ pub fn oracle_state_unchecked(
}
pub fn oracle_log_context(
name: &str,
state: &OracleState,
oracle_config: &OracleConfig,
staleness_slot: Option<u64>,
) -> String {
format!(
"price: {}, deviation: {}, last_update_slot: {}, now_slot: {}, conf_filter: {:#?}",
"name: {}, price: {}, deviation: {}, last_update_slot: {}, now_slot: {}, conf_filter: {:#?}",
name,
state.price.to_num::<f64>(),
state.deviation.to_num::<f64>(),
state.last_update_slot,

View File

@ -277,8 +277,10 @@ impl PerpMarket {
require_keys_eq!(self.oracle, *oracle_acc.key());
let state = oracle::oracle_state_unchecked(oracle_acc, self.base_decimals)?;
state
.check_confidence_and_maybe_staleness(&self.name(), &self.oracle_config, staleness_slot)
.with_context(|| oracle_log_context(&state, &self.oracle_config, staleness_slot))?;
.check_confidence_and_maybe_staleness(&self.oracle_config, staleness_slot)
.with_context(|| {
oracle_log_context(self.name(), &state, &self.oracle_config, staleness_slot)
})?;
Ok(state)
}