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

feat: set up remark handler #273

Merged
merged 13 commits into from
Jan 22, 2025
7 changes: 6 additions & 1 deletion chains-cfg/_root.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,9 @@ dataSources:
kind: substrate/EventHandler
filter:
module: uniques
method: MetadataSet
method: MetadataSet
- handler: handleRemark
kind: substrate/EventHandler
filter:
module: remarks
method: Remark
11 changes: 11 additions & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -691,4 +691,15 @@ type PoolFeeTransaction @entity {
epoch: Epoch!

amount: BigInt
}

type Attestation @entity {
id: ID! # extrinsicHash

pool: Pool!
timestamp: Date!

account: Account! @index

data: String
}
28 changes: 27 additions & 1 deletion src/helpers/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
//find out types: const a = createType(api.registry, '[u8;32]', 18)
import { AugmentedCall, AugmentedRpc, PromiseRpcResult } from '@polkadot/api/types'
import { Enum, Null, Struct, u128, u32, u64, U8aFixed, Option, Vec, Bytes, Result, bool } from '@polkadot/types'
import {
Enum,
Null,
Struct,
u128,
u32,
u64,
U8aFixed,
Option,
Vec,
Bytes,
Result,
bool,
GenericCall,
} from '@polkadot/types'
import { AccountId32, Perquintill, Balance } from '@polkadot/types/interfaces'
import { ITuple, Observable } from '@polkadot/types/types'

Expand Down Expand Up @@ -469,6 +483,16 @@ export type InvestOrdersCollectedEvent = ITuple<
]
>

export interface RemarksRemark extends Enum {
readonly isIpfsHash: boolean
readonly asIpfsHash: Bytes
readonly isNamed: boolean
readonly asNamed: Bytes
readonly isLoan: boolean
readonly asLoan: ITuple<[u64, u64]>
readonly type: 'IpfsHash' | 'Named' | 'Loan'
}

export type RedeemOrdersCollectedEvent = ITuple<
[
investmentId: TrancheCurrency | TrancheCurrencyBefore1400,
Expand Down Expand Up @@ -503,6 +527,8 @@ export type PoolFeesList = Vec<PoolFeesOfBucket>

export type OracleFedEvent = ITuple<[feeder: DevelopmentRuntimeOriginCaller, key: OracleKey, value: u128]>

export type RemarkEvent = ITuple<[remarks: Vec<RemarksRemark>, call: GenericCall]>

export type ExtendedRpc = {
pools: {
trancheTokenPrice: PromiseRpcResult<
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ export * from './mappings/handlers/ethHandlers'
export * from './mappings/handlers/poolFeesHandlers'
export * from './mappings/handlers/oracleHandlers'
export * from './mappings/handlers/uniquesHandlers'
export * from './mappings/handlers/remarkHandlers'
9 changes: 7 additions & 2 deletions src/mappings/handlers/blockHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,13 @@ async function _handleBlock(block: SubstrateBlock): Promise<void> {
// Update Pool States
const pools = await PoolService.getCfgActivePools()
for (const pool of pools) {
const currency = (await CurrencyService.getByPoolId(pool.id, { limit: 1 })).pop()
logger.info(` ## Updating pool ${pool.id} states...`)
if (!pool.currencyId) {
logger.error(`Pool currencyId not set for ${pool.id}, skipping...`)
continue
}
const [chainId, currencyType, currencyValue] = pool.currencyId.split('-')
const currency = await CurrencyService.getOrInit(chainId, currencyType, currencyValue)

if (!pool.currentEpoch) {
logger.error(`Pool currentEpoch not set for ${pool.id}, skipping...`)
Expand Down Expand Up @@ -185,7 +190,7 @@ async function _handleBlock(block: SubstrateBlock): Promise<void> {
const accruedFees = await pool.getAccruedFees()
for (const accruals of accruedFees) {
const [feeId, pending, disbursement] = accruals
const poolFee = poolFees.find( fee => fee.id === `${pool.id}-${feeId}`)
const poolFee = poolFees.find((fee) => fee.id === `${pool.id}-${feeId}`)
if (!poolFee) {
logger.error(`Unable to retrieve PoolFee ${pool.id}-${feeId}, skipping accruals!`)
continue
Expand Down
2 changes: 2 additions & 0 deletions src/mappings/handlers/poolsHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ async function _handlePoolCreated(event: SubstrateEvent<PoolCreatedEvent>): Prom
const [, , poolId, essence] = event.event.data
const timestamp = event.block.timestamp
if (!timestamp) throw new Error(`Block ${event.block.block.header.number.toString()} has no timestamp`)

const formattedCurrency =
`${LOCAL_CHAIN_ID}-${essence.currency.type}-` +
`${currencyFormatters[essence.currency.type](essence.currency.value).join('-')}`

logger.info(
`Creating Pool ${poolId.toString()} with currency: ${formattedCurrency} ` +
`in block ${event.block.block.header.number}`
Expand Down
30 changes: 30 additions & 0 deletions src/mappings/handlers/remarkHandlers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { SubstrateEvent } from '@subql/types'
import { errorHandler } from '../../helpers/errorHandler'
import { RemarkEvent } from '../../helpers/types'
import { AttestationService } from '../services/attestationService'
import { AccountService } from '../services/accountService'

export const handleRemark = errorHandler(_handleRemark)
async function _handleRemark(event: SubstrateEvent<RemarkEvent>) {
const [remarks, _call] = event.event.data
if (!event.extrinsic) throw new Error('Missing event extrinsic!')
const account = await AccountService.getOrInit(event.extrinsic.extrinsic.signer.toHex())
logger.info(`Remark event fired for ${event.hash.toString()} at block ${event.block.block.header.number.toNumber()}`)
const namedRemarks = remarks.filter((remark) => remark.isNamed)

for (const namedRemark of namedRemarks) {
const namedRemarkData = namedRemark.asNamed.toUtf8()
const [type, poolId, attestationData] = namedRemarkData.split(':')
logger.info(`Named remark with data: ${namedRemarkData}`)
if (type === 'attestation') {
const attestation = await AttestationService.init(
poolId,
event.hash.toString(),
event.block.timestamp!,
account.id,
attestationData
)
await attestation.save()
}
}
}
11 changes: 11 additions & 0 deletions src/mappings/services/attestationService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Attestation } from '../../types/models/Attestation'

export class AttestationService extends Attestation {
static init(poolId: string, hash: string, timestamp: Date, accountId: string, data: string) {
const id = `${poolId}-${hash}`
logger.info(`Initialising new attestation ${id} with data: ${data}`)
const attestation = new this(id, poolId, timestamp, accountId)
attestation.data = data
return attestation
}
}
15 changes: 11 additions & 4 deletions src/mappings/services/epochService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ export class EpochService extends Epoch {
epoch.sumPoolFeesPaidAmount = BigInt(0)

epoch.states = trancheIds.map((trancheId) => {
const epochState = new EpochState(`${poolId}-${epochNr}-${trancheId}`, epoch.id, trancheId)
const epochStateId = `${poolId}-${epochNr.toString(10)}-${trancheId}`
logger.info(`Initialising epoch state ${epochStateId}`)
const epochState = new EpochState(epochStateId, epoch.id, trancheId)
epochState.sumOutstandingInvestOrders = BigInt(0)
epochState.sumOutstandingRedeemOrders = BigInt(0)
epochState.sumOutstandingRedeemOrdersCurrency = BigInt(0)
Expand All @@ -50,9 +52,14 @@ export class EpochService extends Epoch {
return epoch
}

async saveWithStates() {
await this.save()
return Promise.all(this.states.map((epochState) => epochState.save()))
public async saveWithStates() {
const epochStatesSaves = this.states.map((epochState) => epochState.save())
await Promise.all(epochStatesSaves)

const epochSave = this.save()
await epochSave

return this
}

public getStates() {
Expand Down
Loading
Loading