Add global address lookup table test

This commit is contained in:
Christian Kamm 2022-03-03 21:43:21 +01:00
parent c6031acbdb
commit 51991d8546
4 changed files with 190 additions and 8 deletions

View File

@ -41,10 +41,6 @@ pub fn extend<'info>(
payer_ai.key(),
new_addresses,
);
let account_infos = [
lookup_table_ai,
authority_ai,
payer_ai,
];
let account_infos = [lookup_table_ai, authority_ai, payer_ai];
solana_program::program::invoke_signed(&instruction, &account_infos, signer_seeds)
}

View File

@ -113,6 +113,15 @@ impl TestContext {
pubkey: Pubkey::default(),
authority: Keypair::new(),
}, // symbol: "MNGO".to_string()
MintCookie {
index: 0,
decimals: 6,
unit: 10u64.pow(6) as f64,
base_lot: 100 as f64,
quote_lot: 10 as f64,
pubkey: Pubkey::default(),
authority: Keypair::new(),
},
MintCookie {
index: 1,
decimals: 6,

View File

@ -65,14 +65,24 @@ impl SolanaCookie {
}
#[allow(dead_code)]
pub async fn advance_clock_by_slots(&self, slots: u64) {
pub async fn advance_by_slots(&self, slots: u64) {
let clock = self.get_clock().await;
self.context
.borrow_mut()
.warp_to_slot(clock.slot + slots)
.warp_to_slot(clock.slot + slots + 1)
.unwrap();
}
pub async fn get_newest_slot_from_history(&self) -> u64 {
self.context
.borrow_mut()
.banks_client
.get_sysvar::<solana_program::slot_history::SlotHistory>()
.await
.unwrap()
.newest()
}
#[allow(dead_code)]
pub async fn create_token_account(&self, owner: &Pubkey, mint: Pubkey) -> Pubkey {
let keypair = Keypair::new();
@ -101,6 +111,7 @@ impl SolanaCookie {
return keypair.pubkey();
}
// Note: Only one table can be created per authority per slot!
#[allow(dead_code)]
pub async fn create_address_lookup_table(
&self,
@ -110,7 +121,7 @@ impl SolanaCookie {
let (instruction, alt_address) = mango_v4::address_lookup_table::create_lookup_table(
authority.pubkey(),
payer.pubkey(),
0, // TODO: get a good recent slot value from a sysvar
self.get_newest_slot_from_history().await,
);
self.process_transaction(&[instruction], Some(&[authority, payer]))
.await

View File

@ -0,0 +1,166 @@
#![cfg(feature = "test-bpf")]
use anchor_lang::prelude::*;
use solana_program_test::*;
use solana_sdk::signature::Keypair;
use mango_v4::address_lookup_table;
use program_test::*;
mod program_test;
// This is an unspecific happy-case test that just runs a few instructions to check
// that they work in principle. It should be split up / renamed.
#[tokio::test]
async fn test_group_address_lookup_tables() -> Result<()> {
let context = TestContext::new().await;
let solana = &context.solana.clone();
let admin = &Keypair::new();
let owner = &context.users[0].key;
let payer = &context.users[1].key;
let mint0 = &context.mints[0];
let mint1 = &context.mints[1];
let mint2 = &context.mints[2];
let payer_mint_accounts = &context.users[1].token_accounts[0..=2];
//
// SETUP: Create a group
//
let group = send_tx(solana, CreateGroupInstruction { admin, payer })
.await
.unwrap()
.group;
let account = send_tx(
solana,
CreateAccountInstruction {
account_num: 0,
group,
owner,
payer,
},
)
.await
.unwrap()
.account;
//
// SETUP: Register three mints (and make oracles for them)
//
let register_mint = |mint: MintCookie, address_lookup_table: Pubkey| async move {
let create_stub_oracle_accounts = send_tx(
solana,
CreateStubOracle {
mint: mint.pubkey,
payer,
},
)
.await
.unwrap();
let oracle = create_stub_oracle_accounts.oracle;
send_tx(
solana,
SetStubOracle {
mint: mint.pubkey,
payer,
price: "1.0",
},
)
.await
.unwrap();
let register_token_accounts = send_tx(
solana,
RegisterTokenInstruction {
decimals: mint.decimals,
maint_asset_weight: 0.9,
init_asset_weight: 0.8,
maint_liab_weight: 1.1,
init_liab_weight: 1.2,
group,
admin,
mint: mint.pubkey,
address_lookup_table,
payer,
},
)
.await
.unwrap();
let bank = register_token_accounts.bank;
(oracle, bank)
};
// mint0 and mint1
let address_lookup_table1 = solana.create_address_lookup_table(admin, payer).await;
// mint2
solana.advance_by_slots(1).await; // to get a different address
let address_lookup_table2 = solana.create_address_lookup_table(admin, payer).await;
let (oracle0, bank0) = register_mint(mint0.clone(), address_lookup_table1).await;
let (oracle1, bank1) = register_mint(mint1.clone(), address_lookup_table1).await;
let (oracle2, bank2) = register_mint(mint2.clone(), address_lookup_table2).await;
// check the resulting address maps
let data = solana
.get_account_data(address_lookup_table1)
.await
.unwrap();
assert_eq!(
address_lookup_table::addresses(&data),
[bank0, oracle0, bank1, oracle1]
);
let data = solana
.get_account_data(address_lookup_table2)
.await
.unwrap();
assert_eq!(address_lookup_table::addresses(&data), [bank2, oracle2]);
//
// TEST: Deposit funds for each token
//
{
let deposit_amount = 100;
for &payer_token in payer_mint_accounts {
send_tx(
solana,
DepositInstruction {
amount: deposit_amount,
account,
token_account: payer_token,
token_authority: payer,
},
)
.await
.unwrap();
}
}
//
// TEST: Withdraw funds for each token
//
{
let withdraw_amount = 50;
for &payer_token in payer_mint_accounts {
send_tx(
solana,
WithdrawInstruction {
amount: withdraw_amount,
allow_borrow: true,
account,
owner,
token_account: payer_token,
},
)
.await
.unwrap();
}
}
Ok(())
}