ScanningAccountRetriever uses fallback oracles
This commit is contained in:
parent
20261bf734
commit
a0a47af6a4
|
@ -34,6 +34,7 @@ pub async fn new(
|
|||
begin_perp: active_token_len * 2,
|
||||
begin_serum3: active_token_len * 2 + active_perp_len * 2,
|
||||
staleness_slot: None,
|
||||
begin_fallback_oracles: metas.len(), // TODO: add support for fallback oracle accounts
|
||||
};
|
||||
let now_ts = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
|
||||
mango_v4::health::new_health_cache(&account.borrow(), &retriever, now_ts)
|
||||
|
@ -67,6 +68,7 @@ pub fn new_sync(
|
|||
begin_perp: active_token_len * 2,
|
||||
begin_serum3: active_token_len * 2 + active_perp_len * 2,
|
||||
staleness_slot: None,
|
||||
begin_fallback_oracles: metas.len(), // TODO: add support for fallback oracle accounts
|
||||
};
|
||||
let now_ts = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
|
||||
mango_v4::health::new_health_cache(&account.borrow(), &retriever, now_ts)
|
||||
|
|
|
@ -55,7 +55,7 @@ pub struct FixedOrderAccountRetriever<T: KeyedAccountReader> {
|
|||
pub begin_perp: usize,
|
||||
pub begin_serum3: usize,
|
||||
pub staleness_slot: Option<u64>,
|
||||
pub fallback_oracle_ais: Vec<T>,
|
||||
pub begin_fallback_oracles: usize,
|
||||
}
|
||||
|
||||
pub fn new_fixed_order_account_retriever<'a, 'info>(
|
||||
|
@ -73,17 +73,15 @@ pub fn new_fixed_order_account_retriever<'a, 'info>(
|
|||
ais.len(), expected_ais,
|
||||
active_token_len, active_token_len, active_perp_len, active_perp_len, active_serum3_len
|
||||
);
|
||||
let fixed_ais = AccountInfoRef::borrow_slice(&ais[..expected_ais])?;
|
||||
let fallback_oracle_ais = AccountInfoRef::borrow_slice(&ais[expected_ais..])?;
|
||||
|
||||
Ok(FixedOrderAccountRetriever {
|
||||
ais: fixed_ais,
|
||||
ais: AccountInfoRef::borrow_slice(ais)?,
|
||||
n_banks: active_token_len,
|
||||
n_perps: active_perp_len,
|
||||
begin_perp: active_token_len * 2,
|
||||
begin_serum3: active_token_len * 2 + active_perp_len * 2,
|
||||
staleness_slot: Some(Clock::get()?.slot),
|
||||
fallback_oracle_ais,
|
||||
begin_fallback_oracles: expected_ais,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -135,8 +133,7 @@ impl<T: KeyedAccountReader> AccountRetriever for FixedOrderAccountRetriever<T> {
|
|||
|
||||
let oracle_index = self.n_banks + active_token_position_index;
|
||||
let oracle = &self.ais[oracle_index];
|
||||
let fallback_opt = self
|
||||
.fallback_oracle_ais
|
||||
let fallback_opt = self.ais[self.begin_fallback_oracles..]
|
||||
.iter()
|
||||
.find(|ai| ai.key() == &bank.fallback_oracle);
|
||||
let oracle_price_result =
|
||||
|
@ -203,6 +200,7 @@ impl<T: KeyedAccountReader> AccountRetriever for FixedOrderAccountRetriever<T> {
|
|||
pub struct ScannedBanksAndOracles<'a, 'info> {
|
||||
banks: Vec<AccountInfoRefMut<'a, 'info>>,
|
||||
oracles: Vec<AccountInfoRef<'a, 'info>>,
|
||||
fallback_oracles: HashMap<Pubkey, AccountInfoRef<'a, 'info>>,
|
||||
index_map: HashMap<TokenIndex, usize>,
|
||||
staleness_slot: Option<u64>,
|
||||
}
|
||||
|
@ -229,7 +227,9 @@ impl<'a, 'info> ScannedBanksAndOracles<'a, 'info> {
|
|||
let index = self.bank_index(token_index1)?;
|
||||
let bank = self.banks[index].load_mut_fully_unchecked::<Bank>()?;
|
||||
let oracle = &self.oracles[index];
|
||||
let price = bank.oracle_price(oracle, self.staleness_slot)?;
|
||||
let fallback_oracle_opt = self.fallback_oracles.get(&bank.fallback_oracle);
|
||||
let price =
|
||||
bank.oracle_price_with_fallback(oracle, fallback_oracle_opt, self.staleness_slot)?;
|
||||
return Ok((bank, price, None));
|
||||
}
|
||||
let index1 = self.bank_index(token_index1)?;
|
||||
|
@ -247,8 +247,12 @@ impl<'a, 'info> ScannedBanksAndOracles<'a, 'info> {
|
|||
let bank2 = second_bank_part[second - (first + 1)].load_mut_fully_unchecked::<Bank>()?;
|
||||
let oracle1 = &self.oracles[first];
|
||||
let oracle2 = &self.oracles[second];
|
||||
let price1 = bank1.oracle_price(oracle1, self.staleness_slot)?;
|
||||
let price2 = bank2.oracle_price(oracle2, self.staleness_slot)?;
|
||||
let fallback_oracle_opt1 = self.fallback_oracles.get(&bank1.fallback_oracle);
|
||||
let fallback_oracle_opt2 = self.fallback_oracles.get(&bank2.fallback_oracle);
|
||||
let price1 =
|
||||
bank1.oracle_price_with_fallback(oracle1, fallback_oracle_opt1, self.staleness_slot)?;
|
||||
let price2 =
|
||||
bank2.oracle_price_with_fallback(oracle2, fallback_oracle_opt2, self.staleness_slot)?;
|
||||
if swap {
|
||||
Ok((bank2, price2, Some((bank1, price1))))
|
||||
} else {
|
||||
|
@ -261,7 +265,10 @@ impl<'a, 'info> ScannedBanksAndOracles<'a, 'info> {
|
|||
// The account was already loaded successfully during construction
|
||||
let bank = self.banks[index].load_fully_unchecked::<Bank>()?;
|
||||
let oracle = &self.oracles[index];
|
||||
let price = bank.oracle_price(oracle, self.staleness_slot)?;
|
||||
let fallback_oracle_opt = self.fallback_oracles.get(&bank.fallback_oracle);
|
||||
let price =
|
||||
bank.oracle_price_with_fallback(oracle, fallback_oracle_opt, self.staleness_slot)?;
|
||||
|
||||
Ok((bank, price))
|
||||
}
|
||||
}
|
||||
|
@ -272,6 +279,7 @@ impl<'a, 'info> ScannedBanksAndOracles<'a, 'info> {
|
|||
/// - an unknown number of PerpMarket accounts
|
||||
/// - the same number of oracles in the same order as the perp markets
|
||||
/// - an unknown number of serum3 OpenOrders accounts
|
||||
/// - an unknown number of fallback oracle accounts
|
||||
/// and retrieves accounts needed for the health computation by doing a linear
|
||||
/// scan for each request.
|
||||
pub struct ScanningAccountRetriever<'a, 'info> {
|
||||
|
@ -357,11 +365,21 @@ impl<'a, 'info> ScanningAccountRetriever<'a, 'info> {
|
|||
let n_perps = perp_index_map.len();
|
||||
let perp_oracles_start = perps_start + n_perps;
|
||||
let serum3_start = perp_oracles_start + n_perps;
|
||||
let n_serum3 = ais[serum3_start..]
|
||||
.iter()
|
||||
.filter(|x| serum3_cpi::load_open_orders_ref(x).is_ok())
|
||||
.count();
|
||||
let fallback_oracles_start = serum3_start + n_serum3;
|
||||
let fallback_oracles: HashMap<Pubkey, AccountInfoRef> = ais[fallback_oracles_start..]
|
||||
.into_iter()
|
||||
.map(|ai| (ai.key(), AccountInfoRef::borrow(ai).unwrap()))
|
||||
.collect();
|
||||
|
||||
Ok(Self {
|
||||
banks_and_oracles: ScannedBanksAndOracles {
|
||||
banks: AccountInfoRefMut::borrow_slice(&ais[..n_banks])?,
|
||||
oracles: AccountInfoRef::borrow_slice(&ais[n_banks..perps_start])?,
|
||||
fallback_oracles,
|
||||
index_map: token_index_map,
|
||||
staleness_slot,
|
||||
},
|
||||
|
|
|
@ -49,7 +49,7 @@ pub fn token_edit(
|
|||
maint_weight_shift_asset_target_opt: Option<f32>,
|
||||
maint_weight_shift_liab_target_opt: Option<f32>,
|
||||
maint_weight_shift_abort: bool,
|
||||
fallback_oracle_opt: Option<Pubkey>,
|
||||
set_fallback_oracle: bool,
|
||||
) -> Result<()> {
|
||||
let group = ctx.accounts.group.load()?;
|
||||
|
||||
|
@ -77,14 +77,14 @@ pub fn token_edit(
|
|||
mint_info.oracle = oracle;
|
||||
require_group_admin = true;
|
||||
}
|
||||
if let Some(fallback_oracle) = fallback_oracle_opt {
|
||||
if set_fallback_oracle {
|
||||
msg!(
|
||||
"Fallback oracle old {:?}, new {:?}",
|
||||
bank.fallback_oracle,
|
||||
fallback_oracle
|
||||
ctx.accounts.fallback_oracle.key()
|
||||
);
|
||||
bank.fallback_oracle = fallback_oracle;
|
||||
mint_info.fallback_oracle = fallback_oracle;
|
||||
bank.fallback_oracle = ctx.accounts.fallback_oracle.key();
|
||||
mint_info.fallback_oracle = ctx.accounts.fallback_oracle.key();
|
||||
require_group_admin = true;
|
||||
}
|
||||
if reset_stable_price {
|
||||
|
|
|
@ -234,7 +234,7 @@ pub mod mango_v4 {
|
|||
maint_weight_shift_asset_target_opt: Option<f32>,
|
||||
maint_weight_shift_liab_target_opt: Option<f32>,
|
||||
maint_weight_shift_abort: bool,
|
||||
fallback_oracle_opt: Option<Pubkey>,
|
||||
set_fallback_oracle: bool,
|
||||
) -> Result<()> {
|
||||
#[cfg(feature = "enable-gpl")]
|
||||
instructions::token_edit(
|
||||
|
@ -273,7 +273,7 @@ pub mod mango_v4 {
|
|||
maint_weight_shift_asset_target_opt,
|
||||
maint_weight_shift_liab_target_opt,
|
||||
maint_weight_shift_abort,
|
||||
fallback_oracle_opt,
|
||||
set_fallback_oracle,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -294,7 +294,7 @@ impl Bank {
|
|||
maint_weight_shift_duration_inv: existing_bank.maint_weight_shift_duration_inv,
|
||||
maint_weight_shift_asset_target: existing_bank.maint_weight_shift_asset_target,
|
||||
maint_weight_shift_liab_target: existing_bank.maint_weight_shift_liab_target,
|
||||
fallback_oracle: existing_bank.oracle, // bongo
|
||||
fallback_oracle: existing_bank.oracle,
|
||||
reserved: [0; 1976],
|
||||
}
|
||||
}
|
||||
|
|
|
@ -460,6 +460,7 @@ async fn test_bank_maint_weight_shift() -> Result<(), TransportError> {
|
|||
group,
|
||||
admin,
|
||||
mint: mints[0].pubkey,
|
||||
fallback_oracle: Pubkey::default(),
|
||||
options: mango_v4::instruction::TokenEdit {
|
||||
maint_weight_shift_start_opt: Some(start_time + 1000),
|
||||
maint_weight_shift_end_opt: Some(start_time + 2000),
|
||||
|
@ -493,6 +494,7 @@ async fn test_bank_maint_weight_shift() -> Result<(), TransportError> {
|
|||
group,
|
||||
admin,
|
||||
mint: mints[0].pubkey,
|
||||
fallback_oracle: Pubkey::default(),
|
||||
options: mango_v4::instruction::TokenEdit {
|
||||
maint_weight_shift_abort: true,
|
||||
..token_edit_instruction_default()
|
||||
|
|
|
@ -107,6 +107,7 @@ async fn test_health_compute_tokens_during_maint_weight_shift() -> Result<(), Tr
|
|||
group,
|
||||
admin,
|
||||
mint: mint.pubkey,
|
||||
fallback_oracle: Pubkey::default(),
|
||||
options: mango_v4::instruction::TokenEdit {
|
||||
maint_weight_shift_start_opt: Some(now - 1000),
|
||||
maint_weight_shift_end_opt: Some(now + 1000),
|
||||
|
|
|
@ -278,6 +278,7 @@ async fn test_flash_loan_swap_fee() -> Result<(), BanksClientError> {
|
|||
group,
|
||||
admin,
|
||||
mint: tokens[1].mint.pubkey,
|
||||
fallback_oracle: Pubkey::default(),
|
||||
options: mango_v4::instruction::TokenEdit {
|
||||
flash_loan_swap_fee_rate_opt: Some(swap_fee_rate as f32),
|
||||
..token_edit_instruction_default()
|
||||
|
|
|
@ -192,10 +192,6 @@ async fn test_fallback_oracle_withdraw() -> Result<(), TransportError> {
|
|||
let mints = &context.mints[0..3];
|
||||
let payer_token_accounts = &context.users[1].token_accounts[0..3];
|
||||
|
||||
//
|
||||
// SETUP: Create a group, account, register tokens
|
||||
//Foracle_
|
||||
|
||||
let mango_setup::GroupWithTokens { group, tokens, .. } = mango_setup::GroupWithTokensConfig {
|
||||
admin,
|
||||
payer,
|
||||
|
@ -226,8 +222,9 @@ async fn test_fallback_oracle_withdraw() -> Result<(), TransportError> {
|
|||
group,
|
||||
admin,
|
||||
mint: mints[2].pubkey,
|
||||
fallback_oracle,
|
||||
options: mango_v4::instruction::TokenEdit {
|
||||
fallback_oracle_opt: Some(fallback_oracle),
|
||||
set_fallback_oracle: true,
|
||||
..token_edit_instruction_default()
|
||||
},
|
||||
},
|
||||
|
|
|
@ -71,6 +71,7 @@ async fn test_token_conditional_swap_basic() -> Result<(), TransportError> {
|
|||
group,
|
||||
admin,
|
||||
mint: quote_token.mint.pubkey,
|
||||
fallback_oracle: Pubkey::default(),
|
||||
options: mango_v4::instruction::TokenEdit {
|
||||
token_conditional_swap_taker_fee_rate_opt: Some(0.05),
|
||||
token_conditional_swap_maker_fee_rate_opt: Some(0.1),
|
||||
|
@ -388,6 +389,7 @@ async fn test_token_conditional_swap_linear_auction() -> Result<(), TransportErr
|
|||
group,
|
||||
admin,
|
||||
mint: quote_token.mint.pubkey,
|
||||
fallback_oracle: Pubkey::default(),
|
||||
options: mango_v4::instruction::TokenEdit {
|
||||
token_conditional_swap_taker_fee_rate_opt: Some(0.05),
|
||||
token_conditional_swap_maker_fee_rate_opt: Some(0.1),
|
||||
|
@ -648,6 +650,7 @@ async fn test_token_conditional_swap_premium_auction() -> Result<(), TransportEr
|
|||
group,
|
||||
admin,
|
||||
mint: quote_token.mint.pubkey,
|
||||
fallback_oracle: Pubkey::default(),
|
||||
options: mango_v4::instruction::TokenEdit {
|
||||
token_conditional_swap_taker_fee_rate_opt: Some(0.05),
|
||||
token_conditional_swap_maker_fee_rate_opt: Some(0.1),
|
||||
|
|
|
@ -1276,7 +1276,7 @@ pub fn token_edit_instruction_default() -> mango_v4::instruction::TokenEdit {
|
|||
maint_weight_shift_asset_target_opt: None,
|
||||
maint_weight_shift_liab_target_opt: None,
|
||||
maint_weight_shift_abort: false,
|
||||
fallback_oracle_opt: None,
|
||||
set_fallback_oracle: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1284,6 +1284,7 @@ pub struct TokenEdit {
|
|||
pub group: Pubkey,
|
||||
pub admin: TestKeypair,
|
||||
pub mint: Pubkey,
|
||||
pub fallback_oracle: Pubkey,
|
||||
pub options: mango_v4::instruction::TokenEdit,
|
||||
}
|
||||
#[async_trait::async_trait(?Send)]
|
||||
|
@ -1312,7 +1313,7 @@ impl ClientInstruction for TokenEdit {
|
|||
admin: self.admin.pubkey(),
|
||||
mint_info: mint_info_key,
|
||||
oracle: mint_info.oracle,
|
||||
fallback_oracle: mint_info.fallback_oracle,
|
||||
fallback_oracle: self.fallback_oracle,
|
||||
};
|
||||
|
||||
let mut instruction = make_instruction(program_id, &accounts, &self.options);
|
||||
|
|
Loading…
Reference in New Issue