diff --git a/apps/randomness/src/index.ts b/apps/randomness/src/index.ts index 30640d8fea..90ac84ff04 100644 --- a/apps/randomness/src/index.ts +++ b/apps/randomness/src/index.ts @@ -29,30 +29,31 @@ class RandomnessService { async start() { await Promise.all([this.txm.start(), this.randomnessRepository.start()]) - this.txm.addHook(this.onTransactionStatusChange.bind(this), TxmHookType.TransactionStatusChanged) + this.txm.addHook(TxmHookType.TransactionStatusChanged, this.onTransactionStatusChange.bind(this)) + this.txm.addHook(TxmHookType.NewBlock, this.onNewBlock.bind(this)) } - private onTransactionStatusChange(payload: { transaction: Transaction }) { - const randomness = this.randomnessRepository.getRandomnessForIntentId(payload.transaction.intentId) + private onTransactionStatusChange(transaction: Transaction) { + const randomness = this.randomnessRepository.getRandomnessForIntentId(transaction.intentId) if (!randomness) { - console.warn("Couldn't find randomness with intentId", payload.transaction.intentId) + console.warn("Couldn't find randomness with intentId", transaction.intentId) return } - if (payload.transaction.status === TransactionStatus.Success) { - if (randomness.commitmentTransactionIntentId === payload.transaction.intentId) { + if (transaction.status === TransactionStatus.Success) { + if (randomness.commitmentTransactionIntentId === transaction.intentId) { randomness.commitmentExecuted() - } else if (randomness.revealTransactionIntentId === payload.transaction.intentId) { + } else if (randomness.revealTransactionIntentId === transaction.intentId) { randomness.revealExecuted() } } else if ( - payload.transaction.status === TransactionStatus.Failed || - payload.transaction.status === TransactionStatus.Expired + transaction.status === TransactionStatus.Failed || + transaction.status === TransactionStatus.Expired ) { - if (randomness.commitmentTransactionIntentId === payload.transaction.intentId) { + if (randomness.commitmentTransactionIntentId === transaction.intentId) { randomness.commitmentFailed() - } else if (randomness.revealTransactionIntentId === payload.transaction.intentId) { + } else if (randomness.revealTransactionIntentId === transaction.intentId) { randomness.revealFailed() } } @@ -64,6 +65,15 @@ class RandomnessService { }) } + private async onNewBlock(block: LatestBlock) { + this.handleRevealNotSubmittedOnTime(block) + this.randomnessRepository.pruneRandomnesses(block.timestamp).then((result) => { + if (result.isErr()) { + console.error("Failed to prune commitments", result.error) + } + }) + } + private async handleRevealNotSubmittedOnTime(block: LatestBlock) { const randomnesses = this.randomnessRepository.getRandomnessInStatus(RandomnessStatus.COMMITMENT_EXECUTED) @@ -142,13 +152,6 @@ class RandomnessService { } }) - // We don't await for pruning, because we don't want to block the transaction collection - this.randomnessRepository.pruneRandomnesses(block.timestamp).then((result) => { - if (result.isErr()) { - console.error("Failed to prune commitments", result.error) - } - }) - return transactions } } diff --git a/packages/txm/lib/HookManager.ts b/packages/txm/lib/HookManager.ts index bc71b89c3d..720faf982e 100644 --- a/packages/txm/lib/HookManager.ts +++ b/packages/txm/lib/HookManager.ts @@ -1,3 +1,4 @@ +import type { LatestBlock } from "./BlockMonitor" import { Topics, eventBus } from "./EventBus.js" import type { Transaction } from "./Transaction.js" @@ -5,15 +6,32 @@ export enum TxmHookType { All = "All", TransactionStatusChanged = "TransactionStatusChanged", TransactionSaveFailed = "TransactionSaveFailed", + NewBlock = "NewBlock", } -export type TxmHookPayload = { - type: TxmHookType +export type TxmTransactionStatusChangedHookPayload = { + type: TxmHookType.TransactionStatusChanged transaction: Transaction } -export type TxmHookHandler = (event: TxmHookPayload) => void +export type TxmNewBlockHookPayload = { + type: TxmHookType.NewBlock + block: LatestBlock +} + +export type TxmTransactionSaveFailedHookPayload = { + type: TxmHookType.TransactionSaveFailed + transaction: Transaction +} +export type TxmHooksRecord = { + [TxmHookType.All]: ((event: { payload: LatestBlock | Transaction; type: TxmHookType }) => void)[] + [TxmHookType.TransactionStatusChanged]: ((transaction: Transaction) => void)[] + [TxmHookType.TransactionSaveFailed]: ((transaction: Transaction) => void)[] + [TxmHookType.NewBlock]: ((block: LatestBlock) => void)[] +} + +export type TxmHookHandler = TxmHooksRecord[T][number] /** * This module manages the hooks system. A hook in the transaction manager is a callback function that * executes when specific events occur, such as when a transaction's status changes. @@ -25,32 +43,36 @@ export type TxmHookHandler = (event: TxmHookPayload) => void * - The callback function that executes when the event occurs. */ export class HookManager { - private hooks: Record + private hooks: { + [T in TxmHookType]: TxmHookHandler[] + } constructor() { this.hooks = { [TxmHookType.All]: [], [TxmHookType.TransactionStatusChanged]: [], [TxmHookType.TransactionSaveFailed]: [], + [TxmHookType.NewBlock]: [], } eventBus.on(Topics.TransactionStatusChanged, this.onTransactionStatusChanged.bind(this)) eventBus.on(Topics.TransactionSaveFailed, this.onTransactionSaveFailed.bind(this)) + eventBus.on(Topics.NewBlock, this.onNewBlock.bind(this)) } - public async addHook(handler: TxmHookHandler, type: TxmHookType): Promise { + public async addHook(type: T, handler: TxmHookHandler): Promise { if (!this.hooks[type]) { this.hooks[type] = [] } this.hooks[type].push(handler) } - private async onTransactionStatusChanged(payload: { - transaction: Transaction - }): Promise { - this.hooks[TxmHookType.TransactionStatusChanged].concat(this.hooks[TxmHookType.All]).map((h) => - h({ + private async onTransactionStatusChanged(payload: { transaction: Transaction }): Promise { + this.hooks[TxmHookType.TransactionStatusChanged].forEach((handler) => handler(payload.transaction)) + + this.hooks[TxmHookType.All].forEach((handler) => + handler({ type: TxmHookType.TransactionStatusChanged, - transaction: payload.transaction, + payload: payload.transaction, }), ) } @@ -58,10 +80,23 @@ export class HookManager { private async onTransactionSaveFailed(payload: { transaction: Transaction }): Promise { - this.hooks[TxmHookType.TransactionSaveFailed].concat(this.hooks[TxmHookType.All]).map((h) => - h({ + this.hooks[TxmHookType.TransactionSaveFailed].forEach((handler) => handler(payload.transaction)) + + this.hooks[TxmHookType.All].forEach((handler) => + handler({ type: TxmHookType.TransactionSaveFailed, - transaction: payload.transaction, + payload: payload.transaction, + }), + ) + } + + private async onNewBlock(block: LatestBlock): Promise { + this.hooks[TxmHookType.NewBlock].forEach((handler) => handler(block)) + + this.hooks[TxmHookType.All].forEach((handler) => + handler({ + type: TxmHookType.NewBlock, + payload: block, }), ) } diff --git a/packages/txm/lib/TransactionManager.ts b/packages/txm/lib/TransactionManager.ts index 29ab15edd9..25915a3d18 100644 --- a/packages/txm/lib/TransactionManager.ts +++ b/packages/txm/lib/TransactionManager.ts @@ -264,8 +264,8 @@ export class TransactionManager { * @param type - The type of hook to add. * @param handler - The handler function to add. */ - public async addHook(handler: TxmHookHandler, type: TxmHookType): Promise { - await this.hookManager.addHook(handler, type) + public async addHook(type: T, handler: TxmHookHandler): Promise { + await this.hookManager.addHook(type, handler) } public async getTransaction(txIntentId: UUID): Promise {