Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: upgrade handlers for latest subql multi-chain #74

Merged
merged 1 commit into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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