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 wasm codes #9

Merged
merged 15 commits into from
Jun 12, 2024
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
Loading