serum health: use lower-precision division (#750)
This saves around 1/3rd of the compute for active serum markets.
This commit is contained in:
parent
20eb02af01
commit
dfde7ec43f
|
@ -19,6 +19,7 @@ use anchor_lang::prelude::*;
|
|||
use fixed::types::I80F48;
|
||||
|
||||
use crate::error::*;
|
||||
use crate::i80f48::LowPrecisionDivision;
|
||||
use crate::serum3_cpi::{OpenOrdersAmounts, OpenOrdersSlim};
|
||||
use crate::state::{
|
||||
Bank, MangoAccountRef, PerpMarket, PerpMarketIndex, PerpPosition, Serum3MarketIndex,
|
||||
|
@ -293,8 +294,9 @@ impl Serum3Info {
|
|||
) -> I80F48 {
|
||||
let quote_asset = quote_info.prices.asset(health_type);
|
||||
let base_liab = base_info.prices.liab(health_type);
|
||||
// OPTIMIZATION: These divisions can be extremely expensive (up to 5k CU each)
|
||||
let reserved_quote_as_base_oracle = self.reserved_quote * quote_asset / base_liab;
|
||||
let reserved_quote_as_base_oracle = (self.reserved_quote * quote_asset)
|
||||
.checked_div_f64_precision(base_liab)
|
||||
.unwrap();
|
||||
if self.reserved_quote_as_base_highest_bid != 0 {
|
||||
self.reserved_base
|
||||
+ reserved_quote_as_base_oracle.min(self.reserved_quote_as_base_highest_bid)
|
||||
|
@ -312,8 +314,9 @@ impl Serum3Info {
|
|||
) -> I80F48 {
|
||||
let base_asset = base_info.prices.asset(health_type);
|
||||
let quote_liab = quote_info.prices.liab(health_type);
|
||||
// OPTIMIZATION: These divisions can be extremely expensive (up to 5k CU each)
|
||||
let reserved_base_as_quote_oracle = self.reserved_base * base_asset / quote_liab;
|
||||
let reserved_base_as_quote_oracle = (self.reserved_base * base_asset)
|
||||
.checked_div_f64_precision(quote_liab)
|
||||
.unwrap();
|
||||
if self.reserved_base_as_quote_lowest_ask != 0 {
|
||||
self.reserved_quote
|
||||
+ reserved_base_as_quote_oracle.min(self.reserved_base_as_quote_lowest_ask)
|
||||
|
|
|
@ -77,7 +77,7 @@ async fn test_health_compute_tokens() -> Result<(), TransportError> {
|
|||
#[tokio::test]
|
||||
async fn test_health_compute_serum() -> Result<(), TransportError> {
|
||||
let mut test_builder = TestContextBuilder::new();
|
||||
test_builder.test().set_compute_max_units(150_000);
|
||||
test_builder.test().set_compute_max_units(130_000);
|
||||
let context = test_builder.start_default().await;
|
||||
let solana = &context.solana.clone();
|
||||
|
||||
|
@ -244,7 +244,7 @@ async fn test_health_compute_serum() -> Result<(), TransportError> {
|
|||
let avg_cu_increase = cu_measurements.windows(2).map(|p| p[1] - p[0]).sum::<u64>()
|
||||
/ (cu_measurements.len() - 1) as u64;
|
||||
println!("average cu increase: {avg_cu_increase}");
|
||||
assert!(avg_cu_increase < 10000);
|
||||
assert!(avg_cu_increase < 7000);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue