From c9f2891da1d8513f6890a77f7cba3624a3669485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Wed, 6 Aug 2025 18:13:48 +0200 Subject: [PATCH 1/2] fix: publish empty batches to avoid staled rounds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After we changed the 0k checker node to run all task as quickly as possible, we are hitting a deadlock where no measurements are reported towards the end of the round, and as a result, the round is never advanced. In this patch, I am changing the publisher to commit a CID for an empty file (bafkqaaa) when no measurements were recorded. Signed-off-by: Miroslav Bajtoš --- publish/index.js | 26 +++++++++++++++++--------- publish/test/test.js | 43 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/publish/index.js b/publish/index.js index 9f34d7d2..14a0ed94 100644 --- a/publish/index.js +++ b/publish/index.js @@ -44,8 +44,9 @@ export const publish = async ({ maxMeasurements ]) if (measurements.length === 0) { - logger.log('No measurements to publish.') - return + // IMPORTANT: We still need to publish an empty batch, + // otherwise the current round will never advance. + logger.log('WARNING: No measurements to publish. Publishing an empty batch.') } // Fetch the count of all unpublished measurements - we need this for monitoring @@ -53,18 +54,25 @@ export const publish = async ({ // measurements in between the previous and the next query. const totalCount = (await pgPool.query( 'SELECT COUNT(*) FROM measurements' - )).rows[0].count + )).rows[0]?.count || 0 logger.log(`Publishing ${measurements.length} measurements. Total unpublished: ${totalCount}. Batch size: ${maxMeasurements}.`) // Share measurements const start = new Date() - const file = new File( - [measurements.map(m => JSON.stringify(m)).join('\n')], - 'measurements.ndjson', - { type: 'application/json' } - ) - const cid = await web3Storage.uploadFile(file) + + let cid + if (measurements.length) { + const file = new File( + [measurements.map(m => JSON.stringify(m)).join('\n')], + 'measurements.ndjson', + { type: 'application/json' } + ) + cid = await web3Storage.uploadFile(file) + } else { + // bafkqaaa is a CID for an empty file + cid = 'bafkqaaa' + } const uploadMeasurementsDuration = new Date().getTime() - start.getTime() logger.log(`Measurements packaged in ${cid}`) diff --git a/publish/test/test.js b/publish/test/test.js index 000bd381..34be20c6 100644 --- a/publish/test/test.js +++ b/publish/test/test.js @@ -14,7 +14,7 @@ import { describe('unit', () => { it('publishes', async () => { - const cid = 'bafybeicmyzlxgqeg5lgjgnzducj37s7bxhxk6vywqtuym2vhqzxjtymqvm' + const cid = 'bafkqaaa' const clientStatements = [] const clientQueryParams = [] @@ -109,7 +109,7 @@ describe('unit', () => { assert.strictEqual(removeConfirmedCalls.length, 1) }) - it('noops when measurements empty', async () => { + it('publishes an empty batch with CID bafkqaaa when measurements empty', async () => { const clientStatements = [] const client = { connect () { @@ -122,9 +122,40 @@ describe('unit', () => { } } - const web3Storage = {} - const ieContract = {} - const stuckTransactionsCanceller = {} + const web3Storage = { + async uploadFile (file) { + throw new Error('web3Storage.uploadFile should not be called') + } + } + + const ieContractMeasurementCIDs = [] + const ieContract = { + async addMeasurements (cid) { + ieContractMeasurementCIDs.push(cid) + return { + async wait () { + return { + logs: [{}] + } + } + } + }, + interface: { + parseLog () { + return { + args: [ + null, + 1 + ] + } + } + } + } + + const stuckTransactionsCanceller = { + async addPending (tx) { }, + async removeConfirmed (tx) { } + } const { recordTelemetry } = createTelemetryRecorderStub() @@ -138,7 +169,7 @@ describe('unit', () => { stuckTransactionsCanceller }) - assert.strictEqual(clientStatements.length, 1) + assert.deepStrictEqual(ieContractMeasurementCIDs, ['bafkqaaa']) }) }) From 2725cd0ec03557237d078788148feb3961f085fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Wed, 6 Aug 2025 18:42:00 +0200 Subject: [PATCH 2/2] Update publish/test/test.js --- publish/test/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/publish/test/test.js b/publish/test/test.js index 34be20c6..d0dcfb37 100644 --- a/publish/test/test.js +++ b/publish/test/test.js @@ -14,7 +14,7 @@ import { describe('unit', () => { it('publishes', async () => { - const cid = 'bafkqaaa' + const cid = 'bafybeicmyzlxgqeg5lgjgnzducj37s7bxhxk6vywqtuym2vhqzxjtymqvm' const clientStatements = [] const clientQueryParams = []