Skip to content

Commit

Permalink
refactor: upgrade handlers for latest subql multi-chain (#74)
Browse files Browse the repository at this point in the history
  • Loading branch information
filo87 authored Oct 31, 2023
1 parent 9a04710 commit f8702fc
Show file tree
Hide file tree
Showing 21 changed files with 4,965 additions and 4,413 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,5 @@ src/types
.data/

project.yaml
centrifuge.yaml

2 changes: 1 addition & 1 deletion chains/demo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ network:
file: ./dist/chaintypes.js
dataSources:
- kind: substrate/Runtime
startBlock: 1534900 #1st October 2023
startBlock: 1534900 #1st October 2023
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"build": "subql build",
"prepack": "rm -rf dist && subql build",
"test": "jest",
"codegen": "./node_modules/.bin/subql codegen",
"codegen": "subql codegen",
"generate:defs": "ts-node --skip-project node_modules/.bin/polkadot-types-from-defs --package centrifuge-subql/src/api-interfaces --endpoint 'wss://fullnode.development.cntrfg.com' --input ./src/api-interfaces",
"generate:meta": "ts-node --skip-project node_modules/.bin/polkadot-types-from-chain --endpoint 'wss://fullnode.development.cntrfg.com' --output ./src/api-interfaces --strict",
"interface-build": "yarn generate:defs && yarn generate:meta && yarn build",
Expand All @@ -31,9 +31,9 @@
"@jest/globals": "^29.2.0",
"@polkadot/api": "^10",
"@polkadot/typegen": "^10",
"@subql/cli": "latest",
"@subql/types": "latest",
"@subql/cli": "^4.1.0",
"@subql/testing": "latest",
"@subql/types": "^3.2.0",
"@types/jest": "^29.1.2",
"@typescript-eslint/eslint-plugin": "^5.28.0",
"@typescript-eslint/parser": "^5.28.0",
Expand Down
17 changes: 10 additions & 7 deletions src/helpers/paginatedGetter.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import { errorHandler } from './errorHandler'
import type { Entity } from '@subql/types-core'

type StoreArgs = Parameters<typeof store.getByField>
type StoreReturn = ReturnType<typeof store.getByField>

interface Entity {
id: string
}

async function _paginatedGetter(entity: StoreArgs[0], field: StoreArgs[1], value: StoreArgs[2]): StoreReturn {
async function _paginatedGetter(
entity: StoreArgs[0],
field: StoreArgs[1],
value: StoreArgs[2]
): Promise<Entity[]> {
let results: Entity[] = []
const batch = 100
let amount = 0
do {
const entities = await store.getByField(entity, field, value, { offset: amount, limit: batch })
const entities: Entity[] = (await store.getByField(entity, field, value, {
offset: amount,
limit: batch,
})) as Entity[]
results = results.concat(entities)
amount += results.length
} while (results.length === batch)
Expand Down
26 changes: 22 additions & 4 deletions src/helpers/stateSnapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { SubstrateBlock } from '@subql/types'
import { errorHandler } from './errorHandler'
import { paginatedGetter } from './paginatedGetter'
import { getPeriodStart } from './timekeeperService'
import type { Entity } from '@subql/types-core'
/**
* Creates a snapshot of a generic stateModel to a snapshotModel.
* A snapshotModel has the same fields as the originating stateModel, however a timestamp and a blockNumber are added.
Expand All @@ -20,26 +21,30 @@ async function _stateSnapshotter(
stateModel: string,
snapshotModel: string,
block: SubstrateBlock,
fkReferenceName: string = undefined,
fkReferenceName: string | undefined = undefined,
filterKey = 'type',
filterValue: string | boolean = 'ALL'
): Promise<void> {
const entitySaves: Promise<void>[] = []
logger.info(`Performing snapshots of ${stateModel}`)
const stateEntities = await paginatedGetter(stateModel, filterKey, filterValue)
const stateEntities = (await paginatedGetter(
stateModel,
filterKey,
filterValue
)) as ResettableEntity[]
for (const stateEntity of stateEntities) {
const blockNumber = block.block.header.number.toNumber()
const { id, ...copyStateEntity } = stateEntity
logger.info(`Snapshotting ${stateModel}: ${id}`)
const snapshotEntity = { ...copyStateEntity, id: `${id}-${blockNumber.toString()}` }
const snapshotEntity: SnapshotEntity = { ...copyStateEntity, id: `${id}-${blockNumber.toString()}` }
snapshotEntity['timestamp'] = block.timestamp
snapshotEntity['blockNumber'] = blockNumber
snapshotEntity['periodStart'] = getPeriodStart(block.timestamp)

if (fkReferenceName) snapshotEntity[fkReferenceName] = stateEntity.id

const propNames = Object.getOwnPropertyNames(stateEntity)
const propNamesToReset = propNames.filter((propName) => propName.endsWith('ByPeriod'))
const propNamesToReset = propNames.filter((propName) => propName.endsWith('ByPeriod')) as ResettableKey[]
for (const propName of propNamesToReset) {
stateEntity[propName] = BigInt(0)
}
Expand All @@ -48,3 +53,16 @@ async function _stateSnapshotter(
}
await Promise.all(entitySaves)
}

interface SnapshotEntity extends Entity {
blockNumber?: number
timestamp?: Date
periodStart?: Date
[fkReferenceName: string]: unknown
}

type ResettableKey = `${string}ByPeriod`

interface ResettableEntity extends Entity {
[propName: ResettableKey]: bigint
}
12 changes: 3 additions & 9 deletions src/helpers/timekeeperService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,11 @@ export class TimekeeperService {
}

static init = async function (): Promise<TimekeeperService> {
let lastPeriodStart: Date
try {
lastPeriodStart = (await Timekeeper.get('global')).lastPeriodStart
} catch (error) {
lastPeriodStart = new Date(0)
}
const lastPeriodStart = (await Timekeeper.get('global'))?.lastPeriodStart ?? new Date(0)
return new TimekeeperService(lastPeriodStart)
}

private _currentPeriodStart: Date = null
private _currentPeriodStart: Date
public getCurrentPeriod = (): Date => this._currentPeriodStart
public processBlock = (block: SubstrateBlock): boolean => {
const blockPeriodStart = getPeriodStart(block.timestamp)
Expand All @@ -29,8 +24,7 @@ export class TimekeeperService {
return isNewPeriod
}
public update = async (blockPeriodStart: Date) => {
const timekeeper = new Timekeeper('global')
timekeeper.lastPeriodStart = blockPeriodStart
const timekeeper = new Timekeeper('global', blockPeriodStart)
await timekeeper.save()
}
}
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export * from './mappings/handlers/loansHandlers'
export * from './mappings/handlers/proxyHandlers'
export * from './mappings/handlers/ormlTokensHandlers'
export * from './mappings/handlers/logHandlers'
export * from './mappings/handlers/ethHandlers'
7 changes: 7 additions & 0 deletions src/mappings/handlers/ethHandlers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { SubstrateEvent } from '@subql/types'
import { errorHandler } from '../../helpers/errorHandler'

export const ethLogger = errorHandler(_ethLogger)
async function _ethLogger(event: SubstrateEvent): Promise<void> {
logger.info(JSON.stringify(event))
}
16 changes: 7 additions & 9 deletions src/mappings/handlers/proxyHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ export async function handleProxyAdded(event: SubstrateEvent): Promise<void> {

const [delegator, delegatee, proxyType] = event.event.data //delay is the fourth element

const proxy = new Proxy(`${delegator.toString()}-${delegatee.toString()}-${proxyType.toString()}}`)
proxy.delegator = delegator.toString()
proxy.delegatee = delegatee.toString()
const proxy = new Proxy(
`${delegator.toString()}-${delegatee.toString()}-${proxyType.toString()}}`,
delegator.toString(),
delegatee.toString()
)
proxy.proxyType = proxyType.toString()
// TODO: store delay
await proxy.save()
Expand All @@ -23,15 +25,11 @@ export async function handleProxyPureCreated(event: SubstrateEvent): Promise<voi
const account = await AccountService.getOrInit(address.toString())
const createdBy = await AccountService.getOrInit(createdByAddress.toString())

const pureProxy = new PureProxy(`${account.toString()}`)
pureProxy.accountId = account.id
pureProxy.createdBy = createdBy.id
const pureProxy = new PureProxy(`${account.toString()}`, account.id, createdBy.id)
pureProxy.proxyType = proxyType.toString()
await pureProxy.save()

const proxy = new Proxy(`${account.id}-${createdBy.id}-${proxyType.toString()}}`)
proxy.delegator = account.id
proxy.delegatee = createdBy.id
const proxy = new Proxy(`${account.id}-${createdBy.id}-${proxyType.toString()}}`, account.id, createdBy.id)
proxy.proxyType = proxyType.toString()
await proxy.save()
}
Expand Down
20 changes: 11 additions & 9 deletions src/mappings/services/borrowerTransactionService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,18 @@ export interface BorrowerTransactionData {

export class BorrowerTransactionService extends BorrowerTransaction {
static init = (data: BorrowerTransactionData, type: BorrowerTransactionType) => {
const tx = new BorrowerTransactionService(`${data.hash}-${data.epochNumber.toString()}-${type.toString()}`)
tx.poolId = data.poolId.toString()
tx.epochNumber = data.epochNumber
tx.accountId = data.address
tx.hash = data.hash
tx.timestamp = data.timestamp
const tx = new BorrowerTransactionService(
`${data.hash}-${data.epochNumber.toString()}-${type.toString()}`,
data.timestamp,
data.poolId.toString(),
data.hash,
data.address,
data.epochNumber,
`${data.poolId}-${data.epochNumber.toString()}`,
`${data.poolId}-${data.loanId}`,
type
)

tx.epochId = `${data.poolId}-${data.epochNumber.toString()}`
tx.loanId = `${data.poolId}-${data.loanId}`
tx.type = type
tx.amount = data.amount ?? null
tx.principalAmount = data.principalAmount ?? null
tx.interestAmount = data.interestAmount ?? null
Expand Down
5 changes: 1 addition & 4 deletions src/mappings/services/currencyBalance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ import { CurrencyBalance } from '../../types/models/CurrencyBalance'
export class CurrencyBalanceService extends CurrencyBalance {
static init(address: string, currency: string) {
logger.info(`Initialising new CurrencyBalance: ${address}-${currency}`)
const currencyBalance = new this(`${address}-${currency}`)
currencyBalance.accountId = address
currencyBalance.currencyId = currency
currencyBalance.amount = BigInt(0)
const currencyBalance = new this(`${address}-${currency}`, address, currency, BigInt(0))
return currencyBalance
}

Expand Down
3 changes: 1 addition & 2 deletions src/mappings/services/currencyService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import { Currency } from '../../types/models/Currency'
export class CurrencyService extends Currency {
static init(ticker: string, decimals: number) {
logger.info(`Initialising new currency ${ticker} with ${decimals} decimals`)
const currency = new this(ticker)
currency.decimals = decimals
const currency = new this(ticker, decimals)
return currency
}

Expand Down
47 changes: 29 additions & 18 deletions src/mappings/services/epochService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,42 @@ import { Epoch, EpochState } from '../../types'
export class EpochService extends Epoch {
readonly states: EpochState[]

constructor(id) {
super(id)
constructor(
id: string,
poolId: string,
index: number,
openedAt: Date,
sumBorrowedAmount: bigint,
sumRepaidAmount: bigint,
sumInvestedAmount: bigint,
sumRedeemedAmount: bigint
) {
super(id, poolId, index, openedAt, sumBorrowedAmount, sumRepaidAmount, sumInvestedAmount, sumRedeemedAmount)
this.states = []
}

static async init(poolId: string, epochNr: number, trancheIds: string[], timestamp: Date) {
logger.info(`Initialising epoch ${epochNr} for pool ${poolId}`)
const epoch = new this(`${poolId}-${epochNr.toString()}`)

epoch.index = epochNr
epoch.poolId = poolId
epoch.openedAt = timestamp

epoch.sumBorrowedAmount = BigInt(0)
epoch.sumRepaidAmount = BigInt(0)
epoch.sumInvestedAmount = BigInt(0)
epoch.sumRedeemedAmount = BigInt(0)
const epoch = new this(
`${poolId}-${epochNr.toString()}`,
poolId,
epochNr,
timestamp,
BigInt(0),
BigInt(0),
BigInt(0),
BigInt(0)
)

for (const trancheId of trancheIds) {
const epochState = new EpochState(`${poolId}-${epochNr}-${trancheId}`)
epochState.epochId = epoch.id
epochState.trancheId = trancheId
epochState.sumOutstandingInvestOrders = BigInt(0)
epochState.sumOutstandingRedeemOrders = BigInt(0)
epochState.sumOutstandingRedeemOrdersCurrency = BigInt(0)
const epochState = new EpochState(
`${poolId}-${epochNr}-${trancheId}`,
epoch.id,
trancheId,
BigInt(0),
BigInt(0),
BigInt(0)
)
epoch.states.push(epochState)
}
return epoch
Expand Down
21 changes: 11 additions & 10 deletions src/mappings/services/investorTransactionService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,20 @@ export interface InvestorTransactionData {

export class InvestorTransactionService extends InvestorTransaction {
static init(data: InvestorTransactionData, type: InvestorTransactionType) {
const tx = new this(`${data.hash}-${data.epochNumber.toString()}-${type.toString()}`)
tx.poolId = data.poolId.toString()
tx.trancheId = `${data.poolId}-${data.trancheId}`
tx.epochNumber = data.epochNumber
tx.accountId = data.address
tx.hash = data.hash
tx.timestamp = data.timestamp
const tx = new this(
`${data.hash}-${data.epochNumber.toString()}-${type.toString()}`,
data.hash,
data.address,
data.poolId.toString(),
`${data.poolId}-${data.trancheId}`,
data.epochNumber,
data.timestamp,
`${data.poolId}-${data.epochNumber.toString()}`,
type
)
tx.tokenPrice = data.price
tx.transactionFee = data.fee

tx.epochId = `${data.poolId}-${data.epochNumber.toString()}`
tx.type = type

tx.currencyAmount = currencyTypes.includes(type) ? data.amount : this.computeCurrencyAmount(data)
tx.tokenAmount = tokenTypes.includes(type) ? data.amount : this.computeTokenAmount(data)

Expand Down
10 changes: 2 additions & 8 deletions src/mappings/services/loanService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,8 @@ const SECONDS_PER_YEAR = bnToBn('3600').muln(24).muln(365)
export class LoanService extends Loan {
static init(poolId: string, loanId: string, nftClassId: bigint, nftItemId: bigint, timestamp: Date) {
logger.info(`Initialising loan ${loanId} for pool ${poolId}`)
const loan = new this(`${poolId}-${loanId}`)

loan.createdAt = timestamp
loan.poolId = poolId
loan.collateralNftClassId = nftClassId
loan.collateralNftItemId = nftItemId
loan.isActive = false
loan.status = LoanStatus.CREATED
const loan = new this(`${poolId}-${loanId}`, timestamp, nftClassId, nftItemId, poolId, false, LoanStatus.CREATED)

loan.outstandingDebt = BigInt(0)
loan.borrowedAmountByPeriod = BigInt(0)
loan.repaidAmountByPeriod = BigInt(0)
Expand Down
19 changes: 11 additions & 8 deletions src/mappings/services/outstandingOrderService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ import { InvestorTransactionData } from './investorTransactionService'

export class OutstandingOrderService extends OutstandingOrder {
static init(data: InvestorTransactionData, investAmount: bigint, redeemAmount: bigint) {
const oo = new this(`${data.poolId}-${data.trancheId}-${data.address}`)
oo.hash = data.hash
oo.accountId = data.address
oo.poolId = data.poolId
oo.trancheId = `${data.poolId}-${data.trancheId}`
oo.epochNumber = data.epochNumber
oo.timestamp = data.timestamp

const oo = new this(
`${data.poolId}-${data.trancheId}-${data.address}`,
data.hash,
data.address,
data.poolId,
`${data.poolId}-${data.trancheId}`,
data.epochNumber,
data.timestamp,
investAmount,
redeemAmount
)
oo.investAmount = investAmount
oo.redeemAmount = redeemAmount
return oo
Expand Down
Loading

0 comments on commit f8702fc

Please sign in to comment.