import { CronJob } from './CronJob' import { DBClient } from '../singletons' import { Account, TaskStatus } from '@prisma/client' import { ChainId } from '../config/chain' export class CreateBridgeTaskJob extends CronJob { constructor() { super('CreateTask') } protected async run(): Promise { // find all eligible accounts that is not in the middle of a task and not at ZKSync const eligibleAccounts = await DBClient.instance.account.findMany({ where: { currentChainId: { not: ChainId.ZKSYNC, }, Task: { none: { status: { in: [TaskStatus.AWAITING, TaskStatus.IN_PROGRESS], }, }, }, }, }) // create a task for each eligible account for (const account of eligibleAccounts) { await DBClient.instance.account.update({ where: { address: account.address, }, data: { Task: { create: { scheduleTime: this.getRandomTime(30), fromChain: account.currentChainId, toChain: this.getRandomDestination(account), status: TaskStatus.AWAITING, }, }, }, }) } } private getRandomTime(hours: number) { const timespan = hours * 60 * 60 * 1000 const randomMilliseconds = Math.floor(Math.random() * timespan) return new Date(Date.now() + randomMilliseconds) } private getRandomDestination(account: Account) { let toZkSync = false if (account.bridgeCount > 7 && account.bridgeCount < 10) { toZkSync = Math.random() > 0.5 } else if (account.bridgeCount >= 10) { toZkSync = true } if (toZkSync) return ChainId.ZKSYNC const chainIds = Object.values(ChainId).filter( (value): value is number => typeof value === 'number' && value !== account.currentChainId && value !== ChainId.ZKSYNC, ) return chainIds[Math.floor(Math.random() * chainIds.length)] } }