Skip to content

Commit d7bc3ee

Browse files
authored
amm cache init refactor (#1998)
1 parent fb3f9a0 commit d7bc3ee

File tree

6 files changed

+89
-21
lines changed

6 files changed

+89
-21
lines changed

programs/drift/src/instructions/admin.rs

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,15 +1135,37 @@ pub fn handle_initialize_perp_market(
11351135

11361136
pub fn handle_initialize_amm_cache(ctx: Context<InitializeAmmCache>) -> Result<()> {
11371137
let amm_cache = &mut ctx.accounts.amm_cache;
1138-
let state = &ctx.accounts.state;
1139-
amm_cache
1140-
.cache
1141-
.resize_with(state.number_of_markets as usize, CacheInfo::default);
11421138
amm_cache.bump = ctx.bumps.amm_cache;
11431139

11441140
Ok(())
11451141
}
11461142

1143+
pub fn handle_resize_amm_cache(ctx: Context<ResizeAmmCache>) -> Result<()> {
1144+
let amm_cache = &mut ctx.accounts.amm_cache;
1145+
let state = &ctx.accounts.state;
1146+
let current_size = amm_cache.cache.len();
1147+
let new_size = (state.number_of_markets as usize).min(current_size + 20_usize);
1148+
1149+
msg!(
1150+
"resizing amm cache from {} entries to {}",
1151+
current_size,
1152+
new_size
1153+
);
1154+
1155+
let growth = new_size.saturating_sub(current_size);
1156+
validate!(
1157+
growth <= 20,
1158+
ErrorCode::DefaultError,
1159+
"cannot grow amm_cache by more than 20 entries in a single resize (requested +{})",
1160+
growth
1161+
)?;
1162+
1163+
amm_cache.cache.resize_with(new_size, CacheInfo::default);
1164+
amm_cache.validate(state)?;
1165+
1166+
Ok(())
1167+
}
1168+
11471169
#[access_control(
11481170
perp_market_valid(&ctx.accounts.perp_market)
11491171
)]
@@ -5510,7 +5532,7 @@ pub struct InitializeAmmCache<'info> {
55105532
#[account(
55115533
init,
55125534
seeds = [AMM_POSITIONS_CACHE.as_ref()],
5513-
space = AmmCache::space(state.number_of_markets as usize),
5535+
space = AmmCache::init_space(),
55145536
bump,
55155537
payer = admin
55165538
)]
@@ -5519,6 +5541,27 @@ pub struct InitializeAmmCache<'info> {
55195541
pub system_program: Program<'info, System>,
55205542
}
55215543

5544+
#[derive(Accounts)]
5545+
pub struct ResizeAmmCache<'info> {
5546+
#[account(
5547+
mut,
5548+
constraint = admin.key() == admin_hot_wallet::id() || admin.key() == state.admin
5549+
)]
5550+
pub admin: Signer<'info>,
5551+
pub state: Box<Account<'info, State>>,
5552+
#[account(
5553+
mut,
5554+
seeds = [AMM_POSITIONS_CACHE.as_ref()],
5555+
bump,
5556+
realloc = AmmCache::space(amm_cache.cache.len() + (state.number_of_markets as usize - amm_cache.cache.len()).min(20_usize)),
5557+
realloc::payer = admin,
5558+
realloc::zero = false,
5559+
)]
5560+
pub amm_cache: Box<Account<'info, AmmCache>>,
5561+
pub rent: Sysvar<'info, Rent>,
5562+
pub system_program: Program<'info, System>,
5563+
}
5564+
55225565
#[derive(Accounts)]
55235566
pub struct DeleteInitializedPerpMarket<'info> {
55245567
#[account(mut)]

programs/drift/src/state/amm_cache.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,19 @@ impl HasLen for AmmCacheFixed {
175175
}
176176

177177
impl AmmCache {
178+
pub fn init_space() -> usize {
179+
8 + 8 + 4
180+
}
181+
178182
pub fn space(num_markets: usize) -> usize {
179183
8 + 8 + 4 + num_markets * CacheInfo::SIZE
180184
}
181185

182186
pub fn validate(&self, state: &State) -> DriftResult<()> {
183187
validate!(
184-
self.cache.len() == state.number_of_markets as usize,
188+
self.cache.len() <= state.number_of_markets as usize,
185189
ErrorCode::DefaultError,
186-
"Number of amm positions is different than number of markets"
190+
"Number of amm positions is no larger than number of markets"
187191
)?;
188192
Ok(())
189193
}

sdk/src/adminClient.ts

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -507,12 +507,6 @@ export class AdminClient extends DriftClient {
507507
): Promise<TransactionSignature> {
508508
const currentPerpMarketIndex = this.getStateAccount().numberOfMarkets;
509509

510-
const ammCachePublicKey = getAmmCachePublicKey(this.program.programId);
511-
const ammCacheAccount = await this.connection.getAccountInfo(
512-
ammCachePublicKey
513-
);
514-
const mustInitializeAmmCache = ammCacheAccount?.data == null;
515-
516510
const initializeMarketIxs = await this.getInitializePerpMarketIx(
517511
marketIndex,
518512
priceOracle,
@@ -540,7 +534,6 @@ export class AdminClient extends DriftClient {
540534
curveUpdateIntensity,
541535
ammJitIntensity,
542536
name,
543-
mustInitializeAmmCache,
544537
lpPoolId
545538
);
546539
const tx = await this.buildTransaction(initializeMarketIxs);
@@ -588,7 +581,6 @@ export class AdminClient extends DriftClient {
588581
curveUpdateIntensity = 0,
589582
ammJitIntensity = 0,
590583
name = DEFAULT_MARKET_NAME,
591-
includeInitAmmCacheIx = false,
592584
lpPoolId: number = 0
593585
): Promise<TransactionInstruction[]> {
594586
const perpMarketPublicKey = await getPerpMarketPublicKey(
@@ -597,9 +589,6 @@ export class AdminClient extends DriftClient {
597589
);
598590

599591
const ixs: TransactionInstruction[] = [];
600-
if (includeInitAmmCacheIx) {
601-
ixs.push(await this.getInitializeAmmCacheIx());
602-
}
603592

604593
const nameBuffer = encodeName(name);
605594
const initPerpIx = await this.program.instruction.initializePerpMarket(
@@ -663,9 +652,35 @@ export class AdminClient extends DriftClient {
663652
return await this.program.instruction.initializeAmmCache({
664653
accounts: {
665654
state: await this.getStatePublicKey(),
666-
admin: this.isSubscribed
667-
? this.getStateAccount().admin
668-
: this.wallet.publicKey,
655+
admin: this.useHotWalletAdmin
656+
? this.wallet.publicKey
657+
: this.getStateAccount().admin,
658+
ammCache: getAmmCachePublicKey(this.program.programId),
659+
rent: SYSVAR_RENT_PUBKEY,
660+
systemProgram: anchor.web3.SystemProgram.programId,
661+
},
662+
});
663+
}
664+
665+
public async resizeAmmCache(
666+
txParams?: TxParams
667+
): Promise<TransactionSignature> {
668+
const initializeAmmCacheIx = await this.getInitializeAmmCacheIx();
669+
670+
const tx = await this.buildTransaction(initializeAmmCacheIx, txParams);
671+
672+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
673+
674+
return txSig;
675+
}
676+
677+
public async getResizeAmmCacheIx(): Promise<TransactionInstruction> {
678+
return await this.program.instruction.resizeAmmCache({
679+
accounts: {
680+
state: await this.getStatePublicKey(),
681+
admin: this.useHotWalletAdmin
682+
? this.wallet.publicKey
683+
: this.getStateAccount().admin,
669684
ammCache: getAmmCachePublicKey(this.program.programId),
670685
rent: SYSVAR_RENT_PUBKEY,
671686
systemProgram: anchor.web3.SystemProgram.programId,

tests/lpPool.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ describe('LP Pool', () => {
191191
solUsdLazer = getPythLazerOraclePublicKey(program.programId, 6);
192192
await adminClient.initializePythLazerOracle(6);
193193

194+
await adminClient.initializeAmmCache();
195+
194196
await adminClient.initializePerpMarket(
195197
0,
196198
solUsd,

tests/lpPoolCUs.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ describe('LP Pool', () => {
171171

172172
solUsd = await mockOracleNoProgram(bankrunContextWrapper, 200);
173173

174+
await adminClient.initializeAmmCache();
175+
174176
adminClient = new TestClient({
175177
connection: bankrunContextWrapper.connection.toConnection(),
176178
wallet: new anchor.Wallet(keypair),

tests/lpPoolSwap.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ describe('LP Pool', () => {
176176

177177
const periodicity = new BN(0);
178178

179+
await adminClient.initializeAmmCache();
180+
179181
await adminClient.initializePerpMarket(
180182
0,
181183
spotMarketOracle,

0 commit comments

Comments
 (0)