Add a ComputeHealth instruction
This way the client can ask for simulation to determine an account's health.
This commit is contained in:
parent
712bece0b2
commit
6ff4ff5910
|
@ -0,0 +1,21 @@
|
||||||
|
use crate::state::*;
|
||||||
|
use anchor_lang::prelude::*;
|
||||||
|
use fixed::types::I80F48;
|
||||||
|
|
||||||
|
#[derive(Accounts)]
|
||||||
|
pub struct ComputeHealth<'info> {
|
||||||
|
pub group: AccountLoader<'info, Group>,
|
||||||
|
|
||||||
|
#[account(
|
||||||
|
has_one = group,
|
||||||
|
)]
|
||||||
|
pub account: AccountLoader<'info, MangoAccount>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn compute_health(ctx: Context<ComputeHealth>, health_type: HealthType) -> Result<I80F48> {
|
||||||
|
let account = ctx.accounts.account.load()?;
|
||||||
|
let health = compute_health_from_fixed_accounts(&account, health_type, ctx.remaining_accounts)?;
|
||||||
|
msg!("health: {}", health);
|
||||||
|
|
||||||
|
Ok(health)
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ pub use benchmark::*;
|
||||||
pub use close_account::*;
|
pub use close_account::*;
|
||||||
pub use close_group::*;
|
pub use close_group::*;
|
||||||
pub use close_stub_oracle::*;
|
pub use close_stub_oracle::*;
|
||||||
|
pub use compute_health::*;
|
||||||
pub use create_account::*;
|
pub use create_account::*;
|
||||||
pub use create_group::*;
|
pub use create_group::*;
|
||||||
pub use create_stub_oracle::*;
|
pub use create_stub_oracle::*;
|
||||||
|
@ -36,6 +37,7 @@ mod benchmark;
|
||||||
mod close_account;
|
mod close_account;
|
||||||
mod close_group;
|
mod close_group;
|
||||||
mod close_stub_oracle;
|
mod close_stub_oracle;
|
||||||
|
mod compute_health;
|
||||||
mod create_account;
|
mod create_account;
|
||||||
mod create_group;
|
mod create_group;
|
||||||
mod create_stub_oracle;
|
mod create_stub_oracle;
|
||||||
|
|
|
@ -17,7 +17,9 @@ mod serum3_cpi;
|
||||||
pub mod state;
|
pub mod state;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
use state::{OracleConfig, OrderType, PerpMarketIndex, Serum3MarketIndex, Side, TokenIndex};
|
use state::{
|
||||||
|
HealthType, OracleConfig, OrderType, PerpMarketIndex, Serum3MarketIndex, Side, TokenIndex,
|
||||||
|
};
|
||||||
|
|
||||||
declare_id!("m43thNJ58XCjL798ZSq6JGAG1BnWskhdq5or6kcnfsD");
|
declare_id!("m43thNJ58XCjL798ZSq6JGAG1BnWskhdq5or6kcnfsD");
|
||||||
|
|
||||||
|
@ -340,6 +342,10 @@ pub mod mango_v4 {
|
||||||
|
|
||||||
// resolve_banktruptcy
|
// resolve_banktruptcy
|
||||||
|
|
||||||
|
pub fn compute_health(ctx: Context<ComputeHealth>, health_type: HealthType) -> Result<I80F48> {
|
||||||
|
instructions::compute_health(ctx, health_type)
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// benchmark
|
/// benchmark
|
||||||
///
|
///
|
||||||
|
|
|
@ -258,7 +258,7 @@ impl<'a, 'info> AccountRetriever for ScanningAccountRetriever<'a, 'info> {
|
||||||
/// slightly smaller weights for the liabilities. Zero is used as the bright line for both
|
/// slightly smaller weights for the liabilities. Zero is used as the bright line for both
|
||||||
/// i.e. if your init health falls below zero, you cannot open new positions and if your maint. health
|
/// i.e. if your init health falls below zero, you cannot open new positions and if your maint. health
|
||||||
/// falls below zero you will be liquidated.
|
/// falls below zero you will be liquidated.
|
||||||
#[derive(PartialEq, Copy, Clone)]
|
#[derive(PartialEq, Copy, Clone, AnchorSerialize, AnchorDeserialize)]
|
||||||
pub enum HealthType {
|
pub enum HealthType {
|
||||||
Init,
|
Init,
|
||||||
Maint,
|
Maint,
|
||||||
|
|
|
@ -2059,3 +2059,47 @@ impl ClientInstruction for UpdateIndexInstruction {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ComputeHealthInstruction {
|
||||||
|
pub account: Pubkey,
|
||||||
|
pub health_type: HealthType,
|
||||||
|
}
|
||||||
|
#[async_trait::async_trait(?Send)]
|
||||||
|
impl ClientInstruction for ComputeHealthInstruction {
|
||||||
|
type Accounts = mango_v4::accounts::ComputeHealth;
|
||||||
|
type Instruction = mango_v4::instruction::ComputeHealth;
|
||||||
|
async fn to_instruction(
|
||||||
|
&self,
|
||||||
|
account_loader: impl ClientAccountLoader + 'async_trait,
|
||||||
|
) -> (Self::Accounts, instruction::Instruction) {
|
||||||
|
let program_id = mango_v4::id();
|
||||||
|
let instruction = Self::Instruction {
|
||||||
|
health_type: self.health_type,
|
||||||
|
};
|
||||||
|
|
||||||
|
let account: MangoAccount = account_loader.load(&self.account).await.unwrap();
|
||||||
|
|
||||||
|
let health_check_metas = derive_health_check_remaining_account_metas(
|
||||||
|
&account_loader,
|
||||||
|
&account,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let accounts = Self::Accounts {
|
||||||
|
group: account.group,
|
||||||
|
account: self.account,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut instruction = make_instruction(program_id, &accounts, instruction);
|
||||||
|
instruction.accounts.extend(health_check_metas.into_iter());
|
||||||
|
|
||||||
|
(accounts, instruction)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signers(&self) -> Vec<&Keypair> {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -84,6 +84,19 @@ async fn test_basic() -> Result<(), TransportError> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// TEST: Compute the account health
|
||||||
|
//
|
||||||
|
send_tx(
|
||||||
|
solana,
|
||||||
|
ComputeHealthInstruction {
|
||||||
|
account,
|
||||||
|
health_type: HealthType::Init,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
//
|
//
|
||||||
// TEST: Withdraw funds
|
// TEST: Withdraw funds
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in New Issue