Skip to content

Commit

Permalink
Refactor wasm codes (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
rumgrum authored Jun 12, 2024
1 parent 9b74a33 commit 083f996
Show file tree
Hide file tree
Showing 31 changed files with 713 additions and 88 deletions.
8 changes: 0 additions & 8 deletions src/core/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,3 @@ export const loadConfig = (configOverride?: string) => {

return config
}

/**
* Get code IDs for a list of keys in the config.
*/
export const getCodeIdsForKeys = (...keys: string[]) => {
const config = loadConfig()
return keys.flatMap((key) => config.codeIds?.[key] ?? [])
}
11 changes: 5 additions & 6 deletions src/core/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import {
WasmTxEvent,
loadDb,
} from '@/db'
import { WasmCodeService } from '@/services/wasm-codes'

import { getCodeIdsForKeys, loadConfig } from './config'
import {
Cache,
DbType,
Expand Down Expand Up @@ -897,13 +897,15 @@ export const getEnv = ({
return contract?.json
}

const getCodeIdsForKeys = (...keys: string[]): number[] =>
WasmCodeService.getInstance().findWasmCodeIdsByKeys(...keys)

const contractMatchesCodeIdKeys: FormulaContractMatchesCodeIdKeysGetter =
async (contractAddress, ...keys) => {
const codeId = (await getContract(contractAddress))?.codeId
return codeId !== undefined && getCodeIdsForKeys(...keys).includes(codeId)
}

const config = loadConfig()
// Tries to find the code ID of this contract in the code ID keys and returns
// the first match.
const getCodeIdKeyForContract: FormulaCodeIdKeyForContractGetter = async (
Expand All @@ -914,10 +916,7 @@ export const getEnv = ({
return
}

const codeIdKeys = Object.entries(config.codeIds ?? {}).flatMap(
([key, value]) => (value?.includes(codeId) ? [key] : [])
)
return codeIdKeys[0]
return WasmCodeService.getInstance().findWasmCodeKeysById(codeId)[0]
}

const getSlashEvents: FormulaSlashEventsGetter = async (
Expand Down
3 changes: 2 additions & 1 deletion src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ export type Config = {
apiKey?: string
}
// Map some arbitary string to a list of code IDs.
codeIds?: Record<string, number[] | undefined>
codeIds?: Partial<Record<string, number[]>>

// If present, sets up Sentry error reporting.
sentryDsn?: string
// Payment info.
Expand Down
13 changes: 9 additions & 4 deletions src/data/meilisearch/daos.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Op, Sequelize } from 'sequelize'

import { getEnv } from '@/core'
import { getCodeIdsForKeys } from '@/core/config'
import {
ContractEnv,
FormulaType,
MeilisearchIndexUpdate,
MeilisearchIndexer,
} from '@/core/types'
import { Contract, WasmStateEvent, WasmStateEventTransformation } from '@/db'
import { WasmCodeService } from '@/services/wasm-codes'

import { getDaoAddressForProposalModule } from '../webhooks/utils'

Expand Down Expand Up @@ -60,7 +60,8 @@ export const daos: MeilisearchIndexer = {
)
},
getBulkUpdates: async () => {
const codeIds = getCodeIdsForKeys('dao-core')
const codeIds =
WasmCodeService.getInstance().findWasmCodeIdsByKeys('dao-core')
if (!codeIds.length) {
return []
}
Expand Down Expand Up @@ -136,8 +137,12 @@ export const daoProposals: MeilisearchIndexer = {
)
},
getBulkUpdates: async () => {
const singleCodeIds = getCodeIdsForKeys('dao-proposal-single')
const multipleCodeIds = getCodeIdsForKeys('dao-proposal-multiple')
const singleCodeIds = WasmCodeService.getInstance().findWasmCodeIdsByKeys(
'dao-proposal-single'
)
const multipleCodeIds = WasmCodeService.getInstance().findWasmCodeIdsByKeys(
'dao-proposal-multiple'
)
if (singleCodeIds.length + multipleCodeIds.length === 0) {
return []
}
Expand Down
75 changes: 37 additions & 38 deletions src/data/transformers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Transformer,
TransformerMaker,
} from '@/core'
import { WasmCodeService } from '@/services/wasm-codes'

import common from './common'
import dao from './dao'
Expand Down Expand Up @@ -42,51 +43,49 @@ export const getProcessedTransformers = (
...transformerMakers.map((maker) => maker(config)),
]

processedTransformers = _transformers.map(({ filter, ...webhook }) => {
const allCodeIds = filter.codeIdsKeys?.flatMap(
(key) => config.codeIds?.[key] ?? []
)
processedTransformers = _transformers.map(({ filter, ...webhook }) => ({
...webhook,
filter: (event) => {
let match = true

return {
...webhook,
filter: (event) => {
let match = true
const allCodeIds = WasmCodeService.getInstance().findWasmCodeIdsByKeys(
...(filter.codeIdsKeys ?? [])
)

if (allCodeIds?.length) {
match &&= allCodeIds.includes(event.codeId)
}
if (allCodeIds.length) {
match &&= allCodeIds.includes(event.codeId)
}

if (match && filter.contractAddresses?.length) {
match &&= filter.contractAddresses.includes(event.contractAddress)
}
if (match && filter.contractAddresses?.length) {
match &&= filter.contractAddresses.includes(event.contractAddress)
}

if (match && filter.matches) {
// Wrap in try/catch in case a transformer errors. Don't want to
// prevent other events from transforming.
try {
match &&= filter.matches(event)
} catch (error) {
console.error(
`Error matching transformer for event ${event.blockHeight}/${event.contractAddress}/${event.key}: ${error}`
)
Sentry.captureException(error, {
tags: {
type: 'failed-transformer-match',
},
extra: {
event,
},
})
if (match && filter.matches) {
// Wrap in try/catch in case a transformer errors. Don't want to
// prevent other events from transforming.
try {
match &&= filter.matches(event)
} catch (error) {
console.error(
`Error matching transformer for event ${event.blockHeight}/${event.contractAddress}/${event.key}: ${error}`
)
Sentry.captureException(error, {
tags: {
type: 'failed-transformer-match',
},
extra: {
event,
},
})

// On error, do not match.
match = false
}
// On error, do not match.
match = false
}
}

return match
},
}
})
return match
},
}))
}

return processedTransformers
Expand Down
5 changes: 3 additions & 2 deletions src/data/webhooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as Sentry from '@sentry/node'

import { Config, ProcessedWebhook, Webhook, WebhookMaker } from '@/core'
import { State, WasmStateEvent } from '@/db'
import { WasmCodeService } from '@/services/wasm-codes'

import { makeProposalCreated } from './discordNotifier'
import { makeIndexerCwReceiptPaid } from './indexerCwReceipt'
Expand Down Expand Up @@ -59,8 +60,8 @@ export const getProcessedWebhooks = (
.filter((webhook): webhook is Webhook => !!webhook)

processedWebhooks = _webhooks.map(({ filter, ...webhook }) => {
const allCodeIds = filter.codeIdsKeys?.flatMap(
(key) => config.codeIds?.[key] ?? []
const allCodeIds = WasmCodeService.getInstance().findWasmCodeIdsByKeys(
...(filter.codeIdsKeys ?? [])
)

return {
Expand Down
4 changes: 4 additions & 0 deletions src/db/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {
StakingSlashEvent,
State,
Validator,
WasmCodeKey,
WasmCodeKeyId,
WasmStateEvent,
WasmStateEventTransformation,
WasmTxEvent,
Expand All @@ -47,6 +49,8 @@ const getModelsForType = (type: DbType): SequelizeOptions['models'] =>
StakingSlashEvent,
State,
Validator,
WasmCodeKey,
WasmCodeKeyId,
WasmStateEvent,
WasmStateEventTransformation,
WasmTxEvent,
Expand Down
35 changes: 35 additions & 0 deletions src/db/migrations/20240521012355-create-wasm-code-key.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { QueryInterface, fn } from 'sequelize'
import { DataType } from 'sequelize-typescript'

module.exports = {
async up(queryInterface: QueryInterface) {
await queryInterface.createTable('WasmCodeKeys', {
codeKey: {
primaryKey: true,
allowNull: false,
type: DataType.STRING,
},
description: {
allowNull: true,
type: DataType.TEXT,
},
createdAt: {
allowNull: false,
type: DataType.DATE,
defaultValue: fn('NOW'),
},
updatedAt: {
allowNull: false,
type: DataType.DATE,
defaultValue: fn('NOW'),
},
})
await queryInterface.addIndex('WasmCodeKeys', {
unique: true,
fields: ['codeKey'],
})
},
async down(queryInterface: QueryInterface) {
await queryInterface.dropTable('WasmCodeKeys')
},
}
47 changes: 47 additions & 0 deletions src/db/migrations/20240521022046-create-wasm-code-key-id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { QueryInterface, fn } from 'sequelize'
import { DataType } from 'sequelize-typescript'

module.exports = {
async up(queryInterface: QueryInterface) {
await queryInterface.createTable('WasmCodeKeyIds', {
id: {
primaryKey: true,
autoIncrement: true,
type: DataType.INTEGER,
},
codeKey: {
allowNull: false,
type: DataType.STRING,
references: {
model: 'WasmCodeKeys',
key: 'codeKey',
},
},
codeKeyId: {
allowNull: false,
type: DataType.INTEGER,
},
description: {
allowNull: true,
type: DataType.TEXT,
},
createdAt: {
allowNull: false,
type: DataType.DATE,
defaultValue: fn('NOW'),
},
updatedAt: {
allowNull: false,
type: DataType.DATE,
defaultValue: fn('NOW'),
},
})
await queryInterface.addIndex('WasmCodeKeyIds', {
unique: true,
fields: ['codeKey', 'codeKeyId'],
})
},
async down(queryInterface: QueryInterface) {
await queryInterface.dropTable('WasmCodeKeyIds')
},
}
28 changes: 28 additions & 0 deletions src/db/migrations/20240612062819-seed-wasm-codes-from-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { QueryInterface } from 'sequelize'

import { WasmCodeService } from '@/services/wasm-codes'

module.exports = {
async up(queryInterface: QueryInterface) {
// loads from config automatically
const codes = (await WasmCodeService.setUpInstance()).getWasmCodes()

await queryInterface.bulkInsert(
'WasmCodeKeys',
codes.map(({ codeKey }) => ({ codeKey }))
)
await queryInterface.bulkInsert(
'WasmCodeKeyIds',
codes.flatMap(({ codeKey, codeIds }) =>
codeIds.map((codeKeyId) => ({
codeKey,
codeKeyId,
}))
)
)
},
async down(queryInterface: QueryInterface) {
await queryInterface.bulkDelete('WasmCodeKeyIds', {})
await queryInterface.bulkDelete('WasmCodeKeys', {})
},
}
6 changes: 3 additions & 3 deletions src/db/models/Contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import {
Table,
} from 'sequelize-typescript'

import { loadConfig } from '@/core/config'
import { ContractJson } from '@/core/types'
import { WasmCodeService } from '@/services/wasm-codes'

@Table({
timestamps: true,
Expand Down Expand Up @@ -53,8 +53,8 @@ export class Contract extends Model {
* from the config.
*/
matchesCodeIdKeys(...keys: string[]): boolean {
const config = loadConfig()
const codeIds = keys.flatMap((key) => config.codeIds?.[key] ?? [])
const codeIds =
WasmCodeService.getInstance().findWasmCodeIdsByKeys(...keys) ?? []
return codeIds.includes(this.codeId)
}
}
Loading

0 comments on commit 083f996

Please sign in to comment.