Skip to content

Commit

Permalink
Do not crash when global accounts are not needed (#168)
Browse files Browse the repository at this point in the history
* Do not crash when global accounts are not needed
* more tests
* remove global in jup


---------

Co-authored-by: Maximilian Schneider <[email protected]>
  • Loading branch information
brittcyr and mschneider authored Oct 9, 2024
1 parent e6ba7d9 commit 181e63a
Show file tree
Hide file tree
Showing 4 changed files with 345 additions and 333 deletions.
284 changes: 4 additions & 280 deletions client/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,16 +212,12 @@ mod test {
use super::*;
use hypertree::{get_mut_helper, trace, DataIndex};
use manifest::{
quantities::{BaseAtoms, GlobalAtoms},
quantities::BaseAtoms,
state::{
constants::NO_EXPIRATION_LAST_VALID_SLOT, AddOrderToMarketArgs, GlobalFixed,
GlobalValue, OrderType, GLOBAL_BLOCK_SIZE, GLOBAL_FIXED_SIZE, MARKET_BLOCK_SIZE,
MARKET_FIXED_SIZE,
},
validation::{
loaders::GlobalTradeAccounts, ManifestAccountInfo, MintAccountInfo, Signer,
TokenAccountInfo, TokenProgram,
constants::NO_EXPIRATION_LAST_VALID_SLOT, AddOrderToMarketArgs, OrderType,
MARKET_BLOCK_SIZE, MARKET_FIXED_SIZE,
},
validation::MintAccountInfo,
};
use solana_sdk::{account::Account, account_info::AccountInfo};
use spl_token_2022::state::Mint;
Expand Down Expand Up @@ -560,276 +556,4 @@ mod test {
assert!(!manifest_market.unidirectional());
assert_eq!(manifest_market.program_dependencies().len(), 0);
}

#[test]
fn test_jupiter_global_22() {
let base_mint_key: Pubkey =
Pubkey::from_str("So11111111111111111111111111111111111111112").unwrap();
// pyusd
let quote_mint_key: Pubkey =
Pubkey::from_str("2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo").unwrap();

let mut base_mint_lamports: u64 = 0;
let base_mint: MintAccountInfo = MintAccountInfo {
mint: Mint {
mint_authority: None.into(),
supply: 0,
decimals: 9,
is_initialized: true,
freeze_authority: None.into(),
},
info: &AccountInfo {
key: &base_mint_key,
lamports: Rc::new(RefCell::new(&mut base_mint_lamports)),
data: Rc::new(RefCell::new(&mut [])),
owner: &Pubkey::new_unique(),
rent_epoch: 0,
is_signer: false,
is_writable: false,
executable: false,
},
};

let mut quote_mint_lamports: u64 = 0;
let quote_mint_info: MintAccountInfo = MintAccountInfo {
mint: Mint {
mint_authority: None.into(),
supply: 0,
decimals: 6,
is_initialized: true,
freeze_authority: None.into(),
},
info: &AccountInfo {
key: &quote_mint_key,
lamports: Rc::new(RefCell::new(&mut quote_mint_lamports)),
data: Rc::new(RefCell::new(&mut [])),
owner: &spl_token_2022::id(),
rent_epoch: 0,
is_signer: false,
is_writable: false,
executable: false,
},
};
let quote_mint_account: Account = Account {
lamports: 0,
data: Vec::new(),
owner: spl_token_2022::id(),
executable: false,
rent_epoch: 0,
};

let market_key: Pubkey =
Pubkey::from_str("GPPda3ZQZannxp3AK8bSishVqvhHAxogiWdhw1mvmoZr").unwrap();

let mut market_value: DynamicAccount<MarketFixed, Vec<u8>> = MarketValue {
fixed: MarketFixed::new_empty(&base_mint, &quote_mint_info, &market_key),
// 4 because 1 extra, 1 seat, 2 orders.
dynamic: vec![0; MARKET_BLOCK_SIZE * 4],
};
let trader_key: Pubkey =
Pubkey::from_str("GCtjtH2ehL6BZTjismuZ8JhQnuM6U3bmtxVoFyiHMHGc").unwrap();
market_value.market_expand().unwrap();
market_value.claim_seat(&trader_key).unwrap();

let manifest_id: Pubkey = manifest::id();
let global_key: Pubkey = get_global_address(&quote_mint_key).0;
let mut global_lamports: u64 = 1_000_000;
let mut global_data_vec: Vec<u8> = Vec::new();
let global_account_info: AccountInfo = {
let mut global_value: DynamicAccount<GlobalFixed, Vec<u8>> = GlobalValue {
fixed: GlobalFixed::new_empty(&quote_mint_key),
dynamic: vec![0; GLOBAL_BLOCK_SIZE * 2],
};
global_value.global_expand().unwrap();
global_value.add_trader(&trader_key).unwrap();
global_value
.deposit_global(&trader_key, GlobalAtoms::new(1_000_000_000_000))
.unwrap();
let mut header_bytes: [u8; GLOBAL_FIXED_SIZE] = [0; GLOBAL_FIXED_SIZE];
*get_mut_helper::<GlobalFixed>(&mut header_bytes, 0_u32) = global_value.fixed;
global_data_vec.extend_from_slice(&header_bytes);
global_data_vec.append(&mut global_value.dynamic);
let global_account_info: AccountInfo = AccountInfo {
key: &global_key,
lamports: Rc::new(RefCell::new(&mut global_lamports)),
data: Rc::new(RefCell::new(&mut global_data_vec)),
owner: &manifest_id,
rent_epoch: 0,
is_signer: false,
is_writable: false,
executable: false,
};
global_account_info
};
let mut global_vault_lamports: u64 = 0;
let mut quote_mint_key_bytes: Vec<u8> = Vec::from(quote_mint_key.as_ref());
let global_vault_account_info: AccountInfo = AccountInfo {
key: &get_global_vault_address(&quote_mint_key).0,
lamports: Rc::new(RefCell::new(&mut global_vault_lamports)),
data: Rc::new(RefCell::new(&mut quote_mint_key_bytes)),
owner: &spl_token_2022::id(),
rent_epoch: 0,
is_signer: false,
is_writable: false,
executable: false,
};
let mut quote_mint_key_bytes: Vec<u8> = Vec::from(quote_mint_key.as_ref());
let mut market_vault_lamports: u64 = 0;
let market_vault_account_info: AccountInfo = AccountInfo {
key: &get_vault_address(&market_key, &quote_mint_key).0,
lamports: Rc::new(RefCell::new(&mut market_vault_lamports)),
data: Rc::new(RefCell::new(&mut quote_mint_key_bytes)),
owner: &spl_token_2022::id(),
rent_epoch: 0,
is_signer: false,
is_writable: false,
executable: false,
};

let mut token_program_lamports: u64 = 0;
let token_program_account_info: AccountInfo = AccountInfo {
key: &spl_token_2022::id(),
lamports: Rc::new(RefCell::new(&mut token_program_lamports)),
data: Rc::new(RefCell::new(&mut [])),
owner: &spl_token_2022::id(),
rent_epoch: 0,
is_signer: false,
is_writable: false,
executable: false,
};

let trader_index: DataIndex = market_value.get_trader_index(&trader_key);
market_value
.deposit(trader_index, 1_000_000_000_000, true)
.unwrap();
market_value
.deposit(trader_index, 1_000_000_000_000, false)
.unwrap();

// Bid for 10 SOL
market_value.market_expand().unwrap();

let mut lamports: u64 = 100_000;
let trader_account_info: AccountInfo<'_> = AccountInfo {
key: &trader_key,
lamports: Rc::new(RefCell::new(&mut lamports)),
data: Rc::new(RefCell::new(&mut [])),
owner: &Pubkey::new_unique(),
rent_epoch: 0,
is_signer: true,
is_writable: false,
executable: false,
};

let quote_global_trade_accounts: GlobalTradeAccounts = GlobalTradeAccounts {
mint_opt: Some(quote_mint_info.clone()),
global: ManifestAccountInfo::new(&global_account_info).unwrap(),
global_vault_opt: Some(
TokenAccountInfo::new(&global_vault_account_info, &quote_mint_key).unwrap(),
),
market_vault_opt: Some(
TokenAccountInfo::new(&market_vault_account_info, &quote_mint_key).unwrap(),
),
token_program_opt: Some(TokenProgram::new(&token_program_account_info).unwrap()),
system_program: None,
gas_payer_opt: Some(Signer::new(&trader_account_info).unwrap()),
gas_receiver_opt: Some(Signer::new(&trader_account_info).unwrap()),
market: market_key.clone(),
};

let trader_index: DataIndex = market_value.get_trader_index(&trader_key);
market_value
.place_order(AddOrderToMarketArgs {
market: market_key,
trader_index,
num_base_atoms: BaseAtoms::new(10_000),
price: 0.150.try_into().unwrap(),
is_bid: true,
last_valid_slot: NO_EXPIRATION_LAST_VALID_SLOT,
order_type: OrderType::Global,
global_trade_accounts_opts: &[None, Some(quote_global_trade_accounts)],
current_slot: None,
})
.unwrap();

// Ask 10 SOL
market_value.market_expand().unwrap();
market_value
.place_order(AddOrderToMarketArgs {
market: market_key,
trader_index,
num_base_atoms: BaseAtoms::new(10_000),
price: 0.180.try_into().unwrap(),
last_valid_slot: NO_EXPIRATION_LAST_VALID_SLOT,
order_type: OrderType::Limit,
global_trade_accounts_opts: &[None, None],
is_bid: false,
current_slot: None,
})
.unwrap();

let mut header_bytes: [u8; MARKET_FIXED_SIZE] = [0; MARKET_FIXED_SIZE];
*get_mut_helper::<MarketFixed>(&mut header_bytes, 0_u32) = market_value.fixed;

let mut data_vec: Vec<u8> = Vec::new();
data_vec.extend_from_slice(&header_bytes);
data_vec.append(&mut market_value.dynamic);

let market_account: Account = Account {
lamports: 0,
data: data_vec,
owner: manifest::id(),
executable: false,
rent_epoch: 0,
};

let market_keyed_account: KeyedAccount = KeyedAccount {
key: market_key,
account: market_account.clone(),
params: None,
};

let mut manifest_market: ManifestMarket =
ManifestMarket::from_keyed_account(&market_keyed_account).unwrap();

let accounts_map: AccountMap = HashMap::from([
(market_key, market_account),
(quote_mint_key, quote_mint_account),
]);

manifest_market.update(&accounts_map).unwrap();

let (base_mint, quote_mint) = {
let reserves: Vec<Pubkey> = manifest_market.get_reserve_mints();
(reserves[0], reserves[1])
};

// Ask for 1 SOL, Bid for 180 USDC
for (side, in_amount) in [(Side::Ask, 1_000_000_000), (Side::Bid, 180_000_000)] {
let (input_mint, output_mint) = match side {
Side::Ask => (base_mint, quote_mint),
Side::Bid => (quote_mint, base_mint),
};

let quote_params: QuoteParams = QuoteParams {
in_amount,
input_mint,
output_mint,
};

let quote: Quote = manifest_market.quote(&quote_params).unwrap();

trace!("{:#?}", quote_params);
trace!("{:#?}", quote);

match side {
Side::Ask => {
assert_eq!(quote.out_amount, 1_500);
}
Side::Bid => {
assert_eq!(quote.out_amount, 10_000);
}
};
}
}
}
Loading

0 comments on commit 181e63a

Please sign in to comment.