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: WAPI-1175 Add fuelTank to Extrinsic model #679

Merged
merged 7 commits into from
Nov 1, 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
11 changes: 11 additions & 0 deletions db/migrations/1698043395524-Data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = class Data1698043395524 {
name = 'Data1698043395524'

async up(db) {
await db.query(`ALTER TABLE "extrinsic" ADD "fuel_tank" jsonb`)
}

async down(db) {
await db.query(`ALTER TABLE "extrinsic" DROP COLUMN "fuel_tank"`)
}
}
10 changes: 10 additions & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ type Fee {
who: Account
}

type FuelTankData {
id: String!
name: String!
ruleSetId: Int
paysRemainingFee: Boolean
useNoneOrigin: Boolean
feePaid: BigInt
}

type Extrinsic @entity {
id: ID!
hash: String! @index
Expand All @@ -46,6 +55,7 @@ type Extrinsic @entity {

# Extras
participants: [String!]!
fuelTank: FuelTankData
}

type Event @entity {
Expand Down
12 changes: 4 additions & 8 deletions src/mappings/balances/events/withdraw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@ import { BalancesWithdrawEvent } from '../../../types/generated/events'
import { Event } from '../../../types/generated/support'
import { CommonContext } from '../../types/contexts'

function getEventData(ctx: CommonContext, event: Event): bigint {
function getEventData(ctx: CommonContext, event: Event) {
const data = new BalancesWithdrawEvent(ctx, event)

if (data.isMatrixEnjinV603) {
const { amount } = data.asMatrixEnjinV603
return amount
return data.asMatrixEnjinV603
}

throw new UnknownVersionError(data.constructor.name)
Expand All @@ -20,9 +19,6 @@ export async function withdraw(
ctx: CommonContext,
block: SubstrateBlock,
item: EventItem<'Balances.Withdraw', { event: { args: true; extrinsic: true } }>
): Promise<bigint | undefined> {
const fee = getEventData(ctx, item.event)
if (!fee) return undefined

return fee
) {
return getEventData(ctx, item.event)
}
38 changes: 38 additions & 0 deletions src/mappings/fuelTanks/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import {
PermittedExtrinsics,
FuelTankRuleSet,
} from '../../model'
import { Call } from '../../types/generated/support'
import { CommonContext } from '../types/contexts'
import { FuelTanksDispatchAndTouchCall, FuelTanksDispatchCall } from '../../types/generated/calls'
import { UnknownVersionError } from '../../common/errors'

export function rulesToMap(
ruleId: string,
Expand Down Expand Up @@ -67,3 +71,37 @@ export function rulesToMap(
permittedExtrinsics,
}
}

export function getTankDataFromCall(ctx: CommonContext, call: Call) {
let data: FuelTanksDispatchCall | FuelTanksDispatchAndTouchCall
if (call.name === 'FuelTanks.dispatch') {
data = new FuelTanksDispatchCall(ctx, call)
} else {
data = new FuelTanksDispatchAndTouchCall(ctx, call)
}

if (data.isMatrixEnjinV603) {
return data.asMatrixEnjinV603
}

if (data.isV604) {
return data.asV604
}

if (data.isV602) {
return data.asV602
}

if (data.isV601) {
return data.asV601
}
if (data.isV600) {
return data.asV600
}

if (data.isV500) {
return data.asV500
}

throw new UnknownVersionError(data.constructor.name)
}
4 changes: 1 addition & 3 deletions src/mappings/multiTokens/events/minted.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,7 @@ export async function minted(
where: { id: `${u8aToHex(data.recipient)}-${data.collectionId}-${data.tokenId}` },
})

if (token.metadata?.attributes) {
computeTraits(data.collectionId.toString())
}
computeTraits(data.collectionId.toString())

token.supply += data.amount
token.nonFungible = isNonFungible(token)
Expand Down
84 changes: 84 additions & 0 deletions src/model/generated/_fuelTankData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import assert from "assert"
import * as marshal from "./marshal"

export class FuelTankData {
private _id!: string
private _name!: string
private _ruleSetId!: number | undefined | null
private _paysRemainingFee!: boolean | undefined | null
private _useNoneOrigin!: boolean | undefined | null
private _feePaid!: bigint | undefined | null

constructor(props?: Partial<Omit<FuelTankData, 'toJSON'>>, json?: any) {
Object.assign(this, props)
if (json != null) {
this._id = marshal.string.fromJSON(json.id)
this._name = marshal.string.fromJSON(json.name)
this._ruleSetId = json.ruleSetId == null ? undefined : marshal.int.fromJSON(json.ruleSetId)
this._paysRemainingFee = json.paysRemainingFee == null ? undefined : marshal.boolean.fromJSON(json.paysRemainingFee)
this._useNoneOrigin = json.useNoneOrigin == null ? undefined : marshal.boolean.fromJSON(json.useNoneOrigin)
this._feePaid = json.feePaid == null ? undefined : marshal.bigint.fromJSON(json.feePaid)
}
}

get id(): string {
assert(this._id != null, 'uninitialized access')
return this._id
}

set id(value: string) {
this._id = value
}

get name(): string {
assert(this._name != null, 'uninitialized access')
return this._name
}

set name(value: string) {
this._name = value
}

get ruleSetId(): number | undefined | null {
return this._ruleSetId
}

set ruleSetId(value: number | undefined | null) {
this._ruleSetId = value
}

get paysRemainingFee(): boolean | undefined | null {
return this._paysRemainingFee
}

set paysRemainingFee(value: boolean | undefined | null) {
this._paysRemainingFee = value
}

get useNoneOrigin(): boolean | undefined | null {
return this._useNoneOrigin
}

set useNoneOrigin(value: boolean | undefined | null) {
this._useNoneOrigin = value
}

get feePaid(): bigint | undefined | null {
return this._feePaid
}

set feePaid(value: bigint | undefined | null) {
this._feePaid = value
}

toJSON(): object {
return {
id: this.id,
name: this.name,
ruleSetId: this.ruleSetId,
paysRemainingFee: this.paysRemainingFee,
useNoneOrigin: this.useNoneOrigin,
feePaid: this.feePaid == null ? undefined : marshal.bigint.toJSON(this.feePaid),
}
}
}
4 changes: 4 additions & 0 deletions src/model/generated/extrinsic.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as marshal from "./marshal"
import {Account} from "./account.model"
import {Fee} from "./_fee"
import {Event} from "./event.model"
import {FuelTankData} from "./_fuelTankData"

@Entity_()
export class Extrinsic {
Expand Down Expand Up @@ -63,4 +64,7 @@ export class Extrinsic {

@Column_("text", {array: true, nullable: false})
participants!: (string)[]

@Column_("jsonb", {transformer: {to: obj => obj == null ? undefined : obj.toJSON(), from: obj => obj == null ? undefined : new FuelTankData(undefined, obj)}, nullable: true})
fuelTank!: FuelTankData | undefined | null
}
1 change: 1 addition & 0 deletions src/model/generated/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export * from "./chainInfo.model"
export * from "./_marketplace"
export * from "./extrinsic.model"
export * from "./_fee"
export * from "./_fuelTankData"
export * from "./event.model"
export * from "./_eventData"
export * from "./_multiTokensApproved"
Expand Down
56 changes: 49 additions & 7 deletions src/processor.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/* eslint-disable no-await-in-loop */
import { BatchContext, BatchProcessorItem, SubstrateBatchProcessor, SubstrateBlock } from '@subsquid/substrate-processor'
import { FullTypeormDatabase } from '@subsquid/typeorm-store'
import { hexStripPrefix, hexToU8a } from '@polkadot/util'
import { hexStripPrefix, hexToU8a, u8aToHex } from '@polkadot/util'
import { EntityManager } from 'typeorm'
import _ from 'lodash'
import * as Sentry from '@sentry/node'
import { RewriteFrames } from '@sentry/integrations'
import config from './config'
import { AccountTokenEvent, Event, Extrinsic, Fee, Listing } from './model'
import { AccountTokenEvent, Event, Extrinsic, Fee, FuelTank, FuelTankData, Listing } from './model'
import { createEnjToken } from './createEnjToken'
import { chainState } from './chainState'
import * as map from './mappings'
Expand All @@ -17,6 +17,7 @@ import { populateBlock } from './populateBlock'
import { updateClaimDetails } from './mappings/claims/common'
import { syncAllCollections } from './jobs/collection-stats'
import { metadataQueue } from './jobs/process-metadata'
import { getTankDataFromCall } from './mappings/fuelTanks/common'

Sentry.init({
dsn: config.sentryDsn,
Expand Down Expand Up @@ -296,6 +297,7 @@ processor.run(

let publicKey = ''
let extrinsicSignature: any = {}
let fuelTank = null

if (!signature) {
publicKey = item.call.args.dest
Expand All @@ -312,9 +314,49 @@ processor.run(
extrinsicSignature = signature
}

if (call.name === 'FuelTanks.dispatch' || call.name === 'FuelTanks.dispatch_and_touch') {
const tankData = getTankDataFromCall(ctx as unknown as CommonContext, call)
const tank = await ctx.store.findOneByOrFail(FuelTank, { id: u8aToHex(tankData.tankId.value) })

fuelTank = new FuelTankData({
id: tank.id,
name: tank.name,
feePaid: 0n,
ruleSetId: tankData.ruleSetId,
paysRemainingFee:
'settings' in tankData && tankData.settings !== undefined
? tankData.settings.paysRemainingFee
: null,
useNoneOrigin:
'settings' in tankData && tankData.settings !== undefined
? tankData.settings.useNoneOrigin
: null,
})

// eslint-disable-next-line no-restricted-syntax
for (const eventItem of block.items) {
if (eventItem.name !== 'Balances.Withdraw' || eventItem.event.extrinsic?.id !== id) {
// eslint-disable-next-line no-continue
continue
}

// eslint-disable-next-line no-await-in-loop
const transfer = await map.balances.events.withdraw(
ctx as unknown as CommonContext,
block.header,
eventItem
)

if (transfer && u8aToHex(transfer.who) === tank.id) {
fuelTank.feePaid = transfer.amount
}
}
}

// eslint-disable-next-line no-await-in-loop
const signer = await getOrCreateAccount(ctx as unknown as CommonContext, hexToU8a(publicKey)) // TODO: Get or create accounts on batches
const callName = call.name.split('.')
const txFee = (fee ?? 0n) + (fuelTank?.feePaid ?? 0n)

const extrinsic = new Extrinsic({
id,
Expand All @@ -331,9 +373,10 @@ processor.run(
tip,
error,
fee: new Fee({
amount: fee,
amount: txFee,
who: signer.id,
}),
fuelTank,
createdAt: new Date(block.header.timestamp),
participants: getParticipants(call.args, publicKey),
})
Expand All @@ -353,14 +396,14 @@ processor.run(
}

// eslint-disable-next-line no-await-in-loop
const feeAmount = await map.balances.events.withdraw(
const transfer = await map.balances.events.withdraw(
ctx as unknown as CommonContext,
block.header,
eventItem
)

if (extrinsic.fee && feeAmount) {
extrinsic.fee.amount = feeAmount
if (extrinsic.fee && transfer) {
extrinsic.fee.amount = transfer.amount
break
}
}
Expand Down Expand Up @@ -391,7 +434,6 @@ processor.run(

const lastBlock = ctx.blocks[ctx.blocks.length - 1].header
if (lastBlock.height > config.lastBlockHeight - 200) {
// import('./handleJobs')
await chainState(ctx as unknown as CommonContext, lastBlock)
}
} catch (error) {
Expand Down