From fd1897db2c2e505fb7359c849ba022ff3eb30a0f Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Fri, 27 Jun 2025 13:37:44 +0200 Subject: [PATCH 1/2] fix: Handle scheduled events close to current time gracefully --- .../src/cronjob/CronjobController.test.ts | 48 +++++++++++++++++++ .../src/cronjob/CronjobController.ts | 7 +++ 2 files changed, 55 insertions(+) diff --git a/packages/snaps-controllers/src/cronjob/CronjobController.test.ts b/packages/snaps-controllers/src/cronjob/CronjobController.test.ts index 767b72b04b..80b58d4827 100644 --- a/packages/snaps-controllers/src/cronjob/CronjobController.test.ts +++ b/packages/snaps-controllers/src/cronjob/CronjobController.test.ts @@ -443,6 +443,54 @@ describe('CronjobController', () => { cronjobController.destroy(); }); + it('handles scheduled event close to current time gracefully', () => { + const rootMessenger = getRootCronjobControllerMessenger(); + const controllerMessenger = + getRestrictedCronjobControllerMessenger(rootMessenger); + + const cronjobController = new CronjobController({ + messenger: controllerMessenger, + state: { + events: { + foo: { + id: 'foo', + recurring: false, + date: '2022-01-01T00:00:01.000Z', + schedule: '2022-01-01T00:00:01.000Z', + scheduledAt: new Date().toISOString(), + snapId: MOCK_SNAP_ID, + request: { + method: 'handleEvent', + params: ['p1'], + }, + }, + }, + }, + }); + + rootMessenger.subscribe('CronjobController:stateChange', () => { + jest.advanceTimersByTime(inMilliseconds(2, Duration.Second)); + }); + + cronjobController.init(); + + expect(rootMessenger.call).toHaveBeenNthCalledWith( + 1, + 'SnapController:handleRequest', + { + snapId: MOCK_SNAP_ID, + origin: METAMASK_ORIGIN, + handler: HandlerType.OnCronjob, + request: { + method: 'handleEvent', + params: ['p1'], + }, + }, + ); + + cronjobController.destroy(); + }); + it('handles the `snapInstalled` event', () => { const rootMessenger = getRootCronjobControllerMessenger(); const controllerMessenger = diff --git a/packages/snaps-controllers/src/cronjob/CronjobController.ts b/packages/snaps-controllers/src/cronjob/CronjobController.ts index f967a33e6f..0c68aa615d 100644 --- a/packages/snaps-controllers/src/cronjob/CronjobController.ts +++ b/packages/snaps-controllers/src/cronjob/CronjobController.ts @@ -415,6 +415,13 @@ export class CronjobController extends BaseController< return; } + // When an event is supposed to be scheduled close to the current time + // we may end up needing to execute immediately instead. + if (ms < 0) { + this.#execute(event); + return; + } + const timer = new Timer(ms); timer.start(() => { this.#execute(event); From 75d6586fc96991331f3c372e15433feff7313f7f Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Fri, 27 Jun 2025 13:49:21 +0200 Subject: [PATCH 2/2] Update packages/snaps-controllers/src/cronjob/CronjobController.ts Co-authored-by: Maarten Zuidhoorn --- packages/snaps-controllers/src/cronjob/CronjobController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/snaps-controllers/src/cronjob/CronjobController.ts b/packages/snaps-controllers/src/cronjob/CronjobController.ts index 0c68aa615d..15c9a97c8b 100644 --- a/packages/snaps-controllers/src/cronjob/CronjobController.ts +++ b/packages/snaps-controllers/src/cronjob/CronjobController.ts @@ -417,7 +417,7 @@ export class CronjobController extends BaseController< // When an event is supposed to be scheduled close to the current time // we may end up needing to execute immediately instead. - if (ms < 0) { + if (ms <= 0) { this.#execute(event); return; }