Add parser for the now deprecated instruction ForceSettleQuotePositions

This commit is contained in:
Nicholas Clarke 2022-01-12 21:53:36 -08:00
parent f59c55b1d8
commit a3d5bffb62
4 changed files with 114 additions and 12 deletions

View File

@ -24,6 +24,10 @@ async function insertMangoTransactions(
// Insert parsed transactions to appropriate tables on timescaledb
// Update process states on transactions table - only once parsed transactions are sucessfully completed (can't use the same db transaction as they are on different databases)
transactionSummaries = []
console.log('starting inserts')
const batchSize = 1000;
let tableName;
@ -59,6 +63,8 @@ async function insertMangoTransactions(
} finally {
rawClient.release();
}
console.log('finished inserts')
}
async function insertParsedTransactions(parsedTransactionsPool, schema, parsedTransactions) {
@ -213,7 +219,7 @@ async function consumeTransactions() {
);
console.log('Refresh complete');
await sleep(5 * 1000);
await sleep(10 * 1000);
}
}

View File

@ -5,6 +5,7 @@ import {
Config,
GroupConfig,
PerpMarketConfig,
orderTypeLayout,
} from '@blockworks-foundation/mango-client';
import { getLatestObjPerCombination } from './utils';
@ -253,6 +254,17 @@ export function jsonParser(parsedTransactions, result, instructions, signature,
blockDatetime,
),
);
} else if (instructionName === 'ForceSettleQuotePositions') {
parsedTransactions.force_settle_quote_positions.push(
...parseForceSettleQuotePositions(
result.meta.logMessages,
instruction.accounts,
signature,
blockTime,
slot,
blockDatetime,
),
);
} else if (instructionName === 'UpdateFunding') {
// read through the program logs and filter for the one that starts with open curly bracket
// TODO what about the case where it's part of a CPI?
@ -1367,7 +1379,87 @@ function extractSettleFees(
return [];
}
}
function parseForceSettleQuotePositions(
logMessages: string,
accounts: string[],
signature,
blockTime,
slot,
blockDatetime,
) {
const config = new Config(IDS);
const mangoGroupPk = accounts[0];
const groupConfig = config.groups.find(
(g) => g.publicKey.toString() === mangoGroupPk,
) as GroupConfig;
let liqee = accounts[2]
let liqor = accounts[3]
let startDetailsStr = 'Program log: force_settle_quote_positions details: ';
let instructionNum = 1
let out: any = []
for (let logMessage of logMessages) {
if (logMessage.startsWith(startDetailsStr)) {
let forceSettleQuoteDetails;
try {
forceSettleQuoteDetails = JSON.parse(logMessage.slice(startDetailsStr.length));
} catch {
let jsonString = logMessage.slice(startDetailsStr.length);
jsonString = insertQuotesAroundField(jsonString, 'liqee');
jsonString = insertQuotesAroundField(jsonString, 'liqor');
jsonString = jsonString.replace(', }', ' }');
forceSettleQuoteDetails = JSON.parse(jsonString);
}
for (let [marketIndex, settlement] of forceSettleQuoteDetails['settlements'].entries()) {
let perpMarketConfig = groupConfig.perpMarkets.find(
(p) => p.marketIndex === marketIndex,
) as PerpMarketConfig;
if (settlement !== 0) {
console.log(perpMarketConfig.name)
console.log(perpMarketConfig.baseSymbol)
let settlementUi = settlement / Math.pow(10, perpMarketConfig.quoteDecimals)
// console.log(perpMarketConfig.quoteDecimals)
out.push(...[
{
liqee: liqee,
liqor: liqor,
settlement: settlementUi,
perp_market_name: perpMarketConfig.name,
base_symbol: perpMarketConfig.baseSymbol,
instruction_num: instructionNum,
mango_group: mangoGroupPk,
block_datetime: blockDatetime,
slot: slot,
signature: signature,
blocktime: blockTime,
}
])
instructionNum++
}
}
}
}
return out
}
function extractUpdateFundings(
result,
instructions,

View File

@ -16,7 +16,7 @@ export function parseTransactions(transactionsResult, mangoProgramId) {
settle_pnl: [],
settle_fees: [],
// 'force_settle_quote_positions': [], // Deprecated?
force_settle_quote_positions: [], // Deprecated
liquidate_token_and_token: [],
liquidate_token_and_perp: [],
@ -85,8 +85,8 @@ export function parseTransactions(transactionsResult, mangoProgramId) {
// Populate instruction num and name for each instruction
let ixNum = 1;
for (const ix of instructions) {
let decodeData = bs58.decode(ix.data);
let decodedInstruction = MangoInstructionLayout.decode(decodeData, 0);
let decodedData = bs58.decode(ix.data);
let decodedInstruction = MangoInstructionLayout.decode(decodedData, 0);
let instructionName = Object.keys(decodedInstruction)[0];
ix.instructionNum = ixNum;
ix.instructionName = instructionName;

View File

@ -8,6 +8,9 @@ export async function getNewSignatures(
addressPk: PublicKey,
requestWaitTime: number,
) {
console.log('Fetching all signatures after slot ' + afterSlot)
// Fetches all signatures associated with the account - working backwards in time until it encounters the "afterSlot" slot
let signatures;
let slots;
@ -29,6 +32,13 @@ export async function getNewSignatures(
signatures = signaturesInfo.map((x) => x['signature']);
slots = signaturesInfo.map((x) => x['slot']);
console.log('slots ' + signaturesInfo[0].slot + ' to ' + signaturesInfo[signaturesInfo.length - 1].slot)
console.log(
new Date(
signaturesInfo[signaturesInfo.length - 1].blockTime! * 1000,
).toISOString(),
);
// Stop when we reach a slot we have already stored in the database
// Use slot instead of signature here as can have multiple signatures per slot and signatures are
// stored in a arbitray order per slot - leading to attempting to insert a duplicate signature
@ -44,7 +54,7 @@ export async function getNewSignatures(
// otherwise we have an issue where the rpc endpoint does not have enough history
if (signaturesInfo.length !== limit) {
throw (
'rpc endpoint does not have sufficient signature history to reach afterSignature ' +
'rpc endpoint does not have sufficient signature history to reach slot ' +
afterSlot
);
}
@ -52,12 +62,6 @@ export async function getNewSignatures(
}
before = signatures[signatures.length - 1];
console.log(
new Date(
signaturesInfo[signaturesInfo.length - 1].blockTime! * 1000,
).toISOString(),
);
await sleep(requestWaitTime);
}