Merge branch 'ts/fix-health-remaining' into ts-client

This commit is contained in:
tjs 2023-01-07 17:24:44 -05:00
commit 36fb7ae181
2 changed files with 65 additions and 85 deletions

View File

@ -22,11 +22,7 @@ import {
import bs58 from 'bs58';
import { Bank, MintInfo, TokenIndex } from './accounts/bank';
import { Group } from './accounts/group';
import {
MangoAccount,
PerpPosition,
TokenPosition,
} from './accounts/mangoAccount';
import { MangoAccount } from './accounts/mangoAccount';
import { StubOracle } from './accounts/oracle';
import {
FillEvent,
@ -48,12 +44,7 @@ import { OPENBOOK_PROGRAM_ID } from './constants';
import { Id } from './ids';
import { IDL, MangoV4 } from './mango_v4';
import { I80F48 } from './numbers/I80F48';
import {
AdditionalHealthAccounts,
FlashLoanType,
InterestRateParams,
OracleConfigParams,
} from './types';
import { FlashLoanType, InterestRateParams, OracleConfigParams } from './types';
import {
I64_MAX_BN,
createAssociatedTokenAccountIdempotentInstruction,
@ -1198,44 +1189,30 @@ export class MangoClient {
externalMarketPk.toBase58(),
)!;
let ooPk;
let healthAdditionalAccounts: AdditionalHealthAccounts | undefined =
undefined;
const healthBanks: Bank[] = [];
let openOrderPk: PublicKey | undefined = undefined;
const banks: Bank[] = [];
const openOrdersForMarket: [Serum3Market, PublicKey][] = [];
if (!mangoAccount.getSerum3Account(serum3Market.marketIndex)) {
const ix = await this.serum3CreateOpenOrdersIx(
group,
mangoAccount,
serum3Market.serumMarketExternal,
);
ooPk = await serum3Market.findOoPda(
ixs.push(ix);
openOrderPk = await serum3Market.findOoPda(
this.program.programId,
mangoAccount.publicKey,
);
openOrdersForMarket.push([serum3Market, openOrderPk]);
const baseTokenIndex = serum3Market.baseTokenIndex;
const quoteTokenIndex = serum3Market.quoteTokenIndex;
const baseBank = group.getFirstBankByTokenIndex(baseTokenIndex);
const quoteBank = group.getFirstBankByTokenIndex(quoteTokenIndex);
// only push bank/oracle if no deposit has been previously made for same token
const baseTokenIsInactive = !mangoAccount
.getToken(baseTokenIndex)
?.isActive();
const quoteTokenIsInactive = !mangoAccount
.getToken(quoteTokenIndex)
?.isActive();
if (baseTokenIsInactive) {
healthBanks.push(baseBank);
// only include banks if no deposit has been previously made for same token
if (!mangoAccount.getToken(baseTokenIndex)?.isActive()) {
banks.push(group.getFirstBankByTokenIndex(baseTokenIndex));
}
if (quoteTokenIsInactive) {
healthBanks.push(quoteBank);
if (!mangoAccount.getToken(quoteTokenIndex)?.isActive()) {
banks.push(group.getFirstBankByTokenIndex(quoteTokenIndex));
}
healthAdditionalAccounts = {
openOrders: [ooPk],
};
ixs.push(ix);
}
const healthRemainingAccounts: PublicKey[] =
@ -1243,9 +1220,9 @@ export class MangoClient {
AccountRetriever.Fixed,
group,
[mangoAccount],
healthBanks,
banks,
[],
healthAdditionalAccounts,
openOrdersForMarket,
);
const serum3MarketExternal = group.serum3ExternalMarketsMap.get(
@ -1293,7 +1270,7 @@ export class MangoClient {
account: mangoAccount.publicKey,
owner: (this.program.provider as AnchorProvider).wallet.publicKey,
openOrders:
ooPk ||
openOrderPk ||
mangoAccount.getSerum3Account(serum3Market.marketIndex)?.openOrders,
serumMarket: serum3Market.publicKey,
serumProgram: OPENBOOK_PROGRAM_ID[this.cluster],
@ -2578,9 +2555,9 @@ export class MangoClient {
retriever: AccountRetriever,
group: Group,
mangoAccounts: MangoAccount[],
banks: Bank[],
perpMarkets: PerpMarket[],
additionalAccounts?: AdditionalHealthAccounts,
banks: Bank[] = [],
perpMarkets: PerpMarket[] = [],
openOrdersForMarket: [Serum3Market, PublicKey][] = [],
): PublicKey[] {
if (retriever === AccountRetriever.Fixed) {
return this.buildFixedAccountRetrieverHealthAccounts(
@ -2588,7 +2565,7 @@ export class MangoClient {
mangoAccounts[0],
banks,
perpMarkets,
additionalAccounts,
openOrdersForMarket,
);
} else {
return this.buildScanningAccountRetrieverHealthAccounts(
@ -2607,33 +2584,26 @@ export class MangoClient {
// but user would potentially open new positions.
banks: Bank[],
perpMarkets: PerpMarket[],
additionalAccounts: AdditionalHealthAccounts = {
openOrders: [],
},
openOrdersForMarket: [Serum3Market, PublicKey][],
): PublicKey[] {
const healthRemainingAccounts: PublicKey[] = [];
const allTokenIndices = mangoAccount.tokens.map(
(token) => token.tokenIndex,
);
if (banks) {
for (const bank of banks) {
if (allTokenIndices.indexOf(bank.tokenIndex) < 0) {
allTokenIndices[
mangoAccount.tokens.findIndex(
(token, index) =>
!token.isActive() &&
allTokenIndices[index] == TokenPosition.TokenIndexUnset,
)
] = bank.tokenIndex;
const tokenPositions = [...mangoAccount.tokens];
for (const bank of banks) {
const tokenPositionExists = tokenPositions.find(
(t) => t.tokenIndex === bank.tokenIndex,
);
if (!tokenPositionExists) {
const inActiveTokenPosition = tokenPositions.find((t) => !t.isActive());
if (inActiveTokenPosition) {
inActiveTokenPosition.tokenIndex = bank.tokenIndex;
}
}
}
const mintInfos = allTokenIndices
.filter((index) => index != TokenPosition.TokenIndexUnset)
.map((tokenIndex) => group.mintInfosMapByTokenIndex.get(tokenIndex)!);
const mintInfos = tokenPositions
.filter((token) => token.isActive())
.map((token) => group.mintInfosMapByTokenIndex.get(token.tokenIndex)!);
healthRemainingAccounts.push(
...mintInfos.map((mintInfo) => mintInfo.firstBank()),
);
@ -2641,35 +2611,49 @@ export class MangoClient {
...mintInfos.map((mintInfo) => mintInfo.oracle),
);
const allPerpIndices = mangoAccount.perps.map((perp) => perp.marketIndex);
// insert any extra perp markets in the free perp position slots
if (perpMarkets) {
for (const perpMarket of perpMarkets) {
if (allPerpIndices.indexOf(perpMarket.perpMarketIndex) < 0) {
allPerpIndices[
mangoAccount.perps.findIndex(
(perp, index) =>
!perp.isActive() &&
allPerpIndices[index] == PerpPosition.PerpMarketIndexUnset,
)
] = perpMarket.perpMarketIndex;
const perpPositions = [...mangoAccount.perps];
for (const perpMarket of perpMarkets) {
const perpPositionExists = perpPositions.find(
(p) => p.marketIndex === perpMarket.perpMarketIndex,
);
if (!perpPositionExists) {
const perpPosition = perpPositions.find((perp) => !perp.isActive());
if (perpPosition) {
perpPosition.marketIndex = perpMarket.perpMarketIndex;
}
}
}
const allPerpMarkets = allPerpIndices
.filter((index) => index != PerpPosition.PerpMarketIndexUnset)
.map((index) => group.findPerpMarket(index)!);
const allPerpMarkets = perpPositions
.filter((perp) => perp.isActive())
.map((perp) => group.getPerpMarketByMarketIndex(perp.marketIndex)!);
healthRemainingAccounts.push(
...allPerpMarkets.map((perp) => perp.publicKey),
);
healthRemainingAccounts.push(...allPerpMarkets.map((perp) => perp.oracle));
// insert any extra open orders accounts in the cooresponding free serum market slot
const serumOpenOrders = [...mangoAccount.serum3];
for (const [serum3Market, openOrderPk] of openOrdersForMarket) {
const ooPositionExists = serumOpenOrders.find(
(oo) => oo.marketIndex === serum3Market.marketIndex,
);
if (!ooPositionExists) {
const serum3Order = serumOpenOrders.find(
(serumOrder) => !serumOrder.isActive(),
);
if (serum3Order) {
serum3Order.marketIndex = serum3Market.marketIndex;
serum3Order.openOrders = openOrderPk;
}
}
}
healthRemainingAccounts.push(
...mangoAccount.serum3
.filter((serum3Account) => serum3Account.marketIndex !== 65535)
...serumOpenOrders
.filter((serum3Account) => serum3Account.isActive())
.map((serum3Account) => serum3Account.openOrders),
...additionalAccounts.openOrders,
);
// debugHealthAccounts(group, mangoAccount, healthRemainingAccounts);

View File

@ -26,7 +26,3 @@ export class OracleConfigParams {
confFilter: number;
maxStalenessSlots: number | null;
}
export type AdditionalHealthAccounts = {
openOrders: PublicKey[];
};