From 86871044eeb95a99e9039d0262b1c29d8b8dc846 Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Tue, 7 Jan 2025 20:10:36 +0100 Subject: [PATCH 01/15] add: metric for successful http retrievals --- lib/retrieval-stats.js | 8 +++++++- test/evaluate.js | 2 ++ test/retrieval-stats.test.js | 10 +++++++--- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/retrieval-stats.js b/lib/retrieval-stats.js index 3db4e8a9..265e5b84 100644 --- a/lib/retrieval-stats.js +++ b/lib/retrieval-stats.js @@ -58,6 +58,7 @@ export const buildRetrievalStats = (measurements, telemetryPoint) => { const ttfbValues = [] const durationValues = [] const sizeValues = [] + let httpSuccesses = 0 for (const m of measurements) { // `retrievalResult` should be always set by lib/preprocess.js, so we should never encounter @@ -99,11 +100,16 @@ export const buildRetrievalStats = (measurements, telemetryPoint) => { const taskId = getTaskId(m) if (m.indexerResult) tasksWithIndexerResults.add(taskId) if (m.indexerResult === 'OK') tasksWithHttpAdvertisement.add(taskId) + + // A successful HTTP response is a response with status code 200 and the protocol being used is set to HTTP. + if (m.retrievalResult === 'OK' && m.protocol.toLowerCase() === 'http') { httpSuccesses++ } } const successRate = resultBreakdown.OK / totalCount - + const successRateHttp = httpSuccesses / totalCount + console.log('successRateHttp', successRateHttp) telemetryPoint.intField('unique_tasks', uniqueTasksCount) telemetryPoint.floatField('success_rate', successRate) + telemetryPoint.floatField('success_rate_http', successRateHttp) telemetryPoint.intField('participants', participants.size) telemetryPoint.intField('inet_groups', inetGroups.size) telemetryPoint.intField('measurements', totalCount) diff --git a/test/evaluate.js b/test/evaluate.js index 52825a7d..8068044c 100644 --- a/test/evaluate.js +++ b/test/evaluate.js @@ -322,6 +322,7 @@ describe('evaluate', async function () { assertPointFieldValue(point, 'measurements', '1i') assertPointFieldValue(point, 'unique_tasks', '1i') assertPointFieldValue(point, 'success_rate', '1') + assertPointFieldValue(point, 'success_rate_http', '0') point = telemetry.find(p => p.name === 'retrieval_stats_all') assert(!!point, @@ -329,6 +330,7 @@ describe('evaluate', async function () { assertPointFieldValue(point, 'measurements', '10i') assertPointFieldValue(point, 'unique_tasks', '2i') assertPointFieldValue(point, 'success_rate', '0.5') + assertPointFieldValue(point, 'success_rate_http', '0') }) it('prepares provider retrieval result stats', async () => { diff --git a/test/retrieval-stats.test.js b/test/retrieval-stats.test.js index 20d5c60a..46f4ed2b 100644 --- a/test/retrieval-stats.test.js +++ b/test/retrieval-stats.test.js @@ -19,7 +19,8 @@ describe('retrieval statistics', () => { /** @type {Measurement[]} */ const measurements = [ { - ...VALID_MEASUREMENT + ...VALID_MEASUREMENT, + protocol: 'http' }, { ...VALID_MEASUREMENT, @@ -31,7 +32,8 @@ describe('retrieval statistics', () => { first_byte_at: new Date('2023-11-01T09:00:10.000Z').getTime(), end_at: new Date('2023-11-01T09:00:50.000Z').getTime(), finished_at: new Date('2023-11-01T09:00:30.000Z').getTime(), - byte_length: 2048 + byte_length: 2048, + protocol: 'http' }, { ...VALID_MEASUREMENT, @@ -57,7 +59,7 @@ describe('retrieval statistics', () => { // invalid task cid: 'bafyinvalid', provider_address: '/dns4/production-ipfs-peer.pinata.cloud/tcp/3000/ws/p2p/Qma8ddFEQWEU8ijWvdxXm3nxU7oHsRtCykAaVz8WUYhiKn', - protocol: 'bitswap' + protocol: 'http' } ] @@ -68,6 +70,8 @@ describe('retrieval statistics', () => { assertPointFieldValue(point, 'measurements', '4i') assertPointFieldValue(point, 'unique_tasks', '3i') assertPointFieldValue(point, 'success_rate', '0.25') + assertPointFieldValue(point, 'success_rate_http', '0.25') + assertPointFieldValue(point, 'participants', '2i') assertPointFieldValue(point, 'participants', '2i') assertPointFieldValue(point, 'inet_groups', '2i') assertPointFieldValue(point, 'download_bandwidth', '209718272i') From bfd8bb5ef5096f1a56e6c86b6ec5ce8e6b8a4547 Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Wed, 8 Jan 2025 08:37:40 +0100 Subject: [PATCH 02/15] add: metric for successful http retrievals daily --- lib/provider-retrieval-result-stats.js | 10 +++++++--- lib/public-stats.js | 13 ++++++++----- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/provider-retrieval-result-stats.js b/lib/provider-retrieval-result-stats.js index 02e00108..2e12f63c 100644 --- a/lib/provider-retrieval-result-stats.js +++ b/lib/provider-retrieval-result-stats.js @@ -16,15 +16,19 @@ const withPgClient = fn => async ({ createPgClient, ...args }) => { } export const build = committees => { - /** @type {Map} */ + /** @type {Map} */ const providerRetrievalResultStats = new Map() for (const c of committees) { // IMPORTANT: include minority results in the calculation for (const m of c.measurements) { const minerId = m.minerId - const retrievalStats = providerRetrievalResultStats.get(minerId) ?? { total: 0, successful: 0 } + const retrievalStats = providerRetrievalResultStats.get(minerId) ?? { total: 0, successful: 0 , successful_http: 0} retrievalStats.total++ - if (m.retrievalResult === 'OK') retrievalStats.successful++ + if (m.retrievalResult === 'OK') {retrievalStats.successful++ + if (m.protocol.toLowerCase() === 'http') { + retrievalStats.successful_http++ + } + } providerRetrievalResultStats.set(minerId, retrievalStats) } } diff --git a/lib/public-stats.js b/lib/public-stats.js index 40ffdf2c..8eeb9aa7 100644 --- a/lib/public-stats.js +++ b/lib/public-stats.js @@ -38,21 +38,24 @@ export const updatePublicStats = async ({ createPgClient, committees, honestMeas * @param {object} stats * @param {number} stats.total * @param {number} stats.successful + * @param {number} stats.successful_http */ -const updateRetrievalStats = async (pgClient, minerId, { total, successful }) => { - debug('Updating public retrieval stats for miner %s: total += %s successful += %s', minerId, total, successful) +const updateRetrievalStats = async (pgClient, minerId, { total, successful, successful_http}) => { + debug('Updating public retrieval stats for miner %s: total += %s successful += %s, sucessful_http += %s', minerId, total, successful, successful_http) await pgClient.query(` INSERT INTO retrieval_stats - (day, miner_id, total, successful) + (day, miner_id, total, successful, successful_http) VALUES - (now(), $1, $2, $3) + (now(), $1, $2, $3, $4) ON CONFLICT(day, miner_id) DO UPDATE SET total = retrieval_stats.total + $2, successful = retrieval_stats.successful + $3 + sucessful_http = retrieval_stats.successful_http + $4 `, [ minerId, total, - successful + successful, + successful_http ]) } From 42deb6ee0786a10d92bb2a597abeca3c85fc1303 Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Wed, 8 Jan 2025 08:42:08 +0100 Subject: [PATCH 03/15] formatting --- lib/retrieval-stats.js | 3 +-- test/evaluate.js | 1 + test/retrieval-stats.test.js | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/retrieval-stats.js b/lib/retrieval-stats.js index 265e5b84..ef2d4d37 100644 --- a/lib/retrieval-stats.js +++ b/lib/retrieval-stats.js @@ -101,12 +101,11 @@ export const buildRetrievalStats = (measurements, telemetryPoint) => { if (m.indexerResult) tasksWithIndexerResults.add(taskId) if (m.indexerResult === 'OK') tasksWithHttpAdvertisement.add(taskId) - // A successful HTTP response is a response with status code 200 and the protocol being used is set to HTTP. + // A successful HTTP response is a response with result breakdown set to OK and the protocol being used is set to HTTP. if (m.retrievalResult === 'OK' && m.protocol.toLowerCase() === 'http') { httpSuccesses++ } } const successRate = resultBreakdown.OK / totalCount const successRateHttp = httpSuccesses / totalCount - console.log('successRateHttp', successRateHttp) telemetryPoint.intField('unique_tasks', uniqueTasksCount) telemetryPoint.floatField('success_rate', successRate) telemetryPoint.floatField('success_rate_http', successRateHttp) diff --git a/test/evaluate.js b/test/evaluate.js index 8068044c..2e01baee 100644 --- a/test/evaluate.js +++ b/test/evaluate.js @@ -322,6 +322,7 @@ describe('evaluate', async function () { assertPointFieldValue(point, 'measurements', '1i') assertPointFieldValue(point, 'unique_tasks', '1i') assertPointFieldValue(point, 'success_rate', '1') + // The default protocol is not http. While the overall success rate is 1, we expect the http success rate to be 0. assertPointFieldValue(point, 'success_rate_http', '0') point = telemetry.find(p => p.name === 'retrieval_stats_all') diff --git a/test/retrieval-stats.test.js b/test/retrieval-stats.test.js index 46f4ed2b..02c307c0 100644 --- a/test/retrieval-stats.test.js +++ b/test/retrieval-stats.test.js @@ -59,6 +59,7 @@ describe('retrieval statistics', () => { // invalid task cid: 'bafyinvalid', provider_address: '/dns4/production-ipfs-peer.pinata.cloud/tcp/3000/ws/p2p/Qma8ddFEQWEU8ijWvdxXm3nxU7oHsRtCykAaVz8WUYhiKn', + // Check that the task is ignored if the retrieval result is not OK protocol: 'http' } ] From fd9ae49ca5480662527aa44b29923722fed528e6 Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Wed, 8 Jan 2025 09:38:23 +0100 Subject: [PATCH 04/15] add: test for successful http retrievals --- test/retrieval-stats.test.js | 43 ++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/test/retrieval-stats.test.js b/test/retrieval-stats.test.js index 02c307c0..d4cb8d9e 100644 --- a/test/retrieval-stats.test.js +++ b/test/retrieval-stats.test.js @@ -19,8 +19,7 @@ describe('retrieval statistics', () => { /** @type {Measurement[]} */ const measurements = [ { - ...VALID_MEASUREMENT, - protocol: 'http' + ...VALID_MEASUREMENT }, { ...VALID_MEASUREMENT, @@ -32,8 +31,7 @@ describe('retrieval statistics', () => { first_byte_at: new Date('2023-11-01T09:00:10.000Z').getTime(), end_at: new Date('2023-11-01T09:00:50.000Z').getTime(), finished_at: new Date('2023-11-01T09:00:30.000Z').getTime(), - byte_length: 2048, - protocol: 'http' + byte_length: 2048 }, { ...VALID_MEASUREMENT, @@ -58,9 +56,8 @@ describe('retrieval statistics', () => { // invalid task cid: 'bafyinvalid', - provider_address: '/dns4/production-ipfs-peer.pinata.cloud/tcp/3000/ws/p2p/Qma8ddFEQWEU8ijWvdxXm3nxU7oHsRtCykAaVz8WUYhiKn', + provider_address: '/dns4/production-ipfs-peer.pinata.cloud/tcp/3000/ws/p2p/Qma8ddFEQWEU8ijWvdxXm3nxU7oHsRtCykAaVz8WUYhiKn' // Check that the task is ignored if the retrieval result is not OK - protocol: 'http' } ] @@ -71,7 +68,6 @@ describe('retrieval statistics', () => { assertPointFieldValue(point, 'measurements', '4i') assertPointFieldValue(point, 'unique_tasks', '3i') assertPointFieldValue(point, 'success_rate', '0.25') - assertPointFieldValue(point, 'success_rate_http', '0.25') assertPointFieldValue(point, 'participants', '2i') assertPointFieldValue(point, 'participants', '2i') assertPointFieldValue(point, 'inet_groups', '2i') @@ -213,6 +209,39 @@ describe('retrieval statistics', () => { assertPointFieldValue(point, 'nano_score_per_inet_group_p50', '333333333i' /* =2/6 */) assertPointFieldValue(point, 'nano_score_per_inet_group_max', '500000000i' /* =3/6 */) }) + + it('records successful http rate', async () => { + /** @type {Measurement[]} */ + const measurements = [ + { + // Standard measurement, no http protocol used + ...VALID_MEASUREMENT + }, + { + // A successful http measurement + ...VALID_MEASUREMENT, + protocol: 'http' + }, + { + ...VALID_MEASUREMENT, + retrievalResult: 'HTTP_500' + }, + { + ...VALID_MEASUREMENT, + // Should not be picked up, as the retrieval timed out + retrievalResult: 'TIMEOUT', + protocol: 'http' + } + ] + + const point = new Point('stats') + buildRetrievalStats(measurements, point) + debug('stats', point.fields) + + assertPointFieldValue(point, 'success_rate', '0.5') + // Only one of the successful measurements used http + assertPointFieldValue(point, 'success_rate_http', '0.25') + }) }) describe('getValueAtPercentile', () => { From beda7a0bd1a6d1e7aec36a87f5fd39171352bc35 Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Wed, 8 Jan 2025 09:40:02 +0100 Subject: [PATCH 05/15] formatting --- test/retrieval-stats.test.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/retrieval-stats.test.js b/test/retrieval-stats.test.js index d4cb8d9e..bee3ab5a 100644 --- a/test/retrieval-stats.test.js +++ b/test/retrieval-stats.test.js @@ -56,8 +56,8 @@ describe('retrieval statistics', () => { // invalid task cid: 'bafyinvalid', - provider_address: '/dns4/production-ipfs-peer.pinata.cloud/tcp/3000/ws/p2p/Qma8ddFEQWEU8ijWvdxXm3nxU7oHsRtCykAaVz8WUYhiKn' - // Check that the task is ignored if the retrieval result is not OK + provider_address: '/dns4/production-ipfs-peer.pinata.cloud/tcp/3000/ws/p2p/Qma8ddFEQWEU8ijWvdxXm3nxU7oHsRtCykAaVz8WUYhiKn', + protocol: 'bitswap' } ] @@ -69,7 +69,6 @@ describe('retrieval statistics', () => { assertPointFieldValue(point, 'unique_tasks', '3i') assertPointFieldValue(point, 'success_rate', '0.25') assertPointFieldValue(point, 'participants', '2i') - assertPointFieldValue(point, 'participants', '2i') assertPointFieldValue(point, 'inet_groups', '2i') assertPointFieldValue(point, 'download_bandwidth', '209718272i') From 06895febeefeb2f0819329802b79024973419059 Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Wed, 8 Jan 2025 11:34:00 +0100 Subject: [PATCH 06/15] add: test for successful http retrievals daily --- lib/provider-retrieval-result-stats.js | 9 +-- lib/public-stats.js | 12 ++-- migrations/001.do.retrieval-stats.sql | 3 +- test/evaluate.js | 5 +- test/provider-retrieval-result-stats.test.js | 32 +++++++---- test/public-stats.test.js | 60 +++++++++++++++++--- 6 files changed, 88 insertions(+), 33 deletions(-) diff --git a/lib/provider-retrieval-result-stats.js b/lib/provider-retrieval-result-stats.js index 2e12f63c..fb93b559 100644 --- a/lib/provider-retrieval-result-stats.js +++ b/lib/provider-retrieval-result-stats.js @@ -16,17 +16,18 @@ const withPgClient = fn => async ({ createPgClient, ...args }) => { } export const build = committees => { - /** @type {Map} */ + /** @type {Map} */ const providerRetrievalResultStats = new Map() for (const c of committees) { // IMPORTANT: include minority results in the calculation for (const m of c.measurements) { const minerId = m.minerId - const retrievalStats = providerRetrievalResultStats.get(minerId) ?? { total: 0, successful: 0 , successful_http: 0} + const retrievalStats = providerRetrievalResultStats.get(minerId) ?? { total: 0, successful: 0, successfulHttp: 0 } retrievalStats.total++ - if (m.retrievalResult === 'OK') {retrievalStats.successful++ + if (m.retrievalResult === 'OK') { + retrievalStats.successful++ if (m.protocol.toLowerCase() === 'http') { - retrievalStats.successful_http++ + retrievalStats.successfulHttp++ } } providerRetrievalResultStats.set(minerId, retrievalStats) diff --git a/lib/public-stats.js b/lib/public-stats.js index 8eeb9aa7..44bb7dc9 100644 --- a/lib/public-stats.js +++ b/lib/public-stats.js @@ -38,10 +38,10 @@ export const updatePublicStats = async ({ createPgClient, committees, honestMeas * @param {object} stats * @param {number} stats.total * @param {number} stats.successful - * @param {number} stats.successful_http + * @param {number} stats.successfulHttp */ -const updateRetrievalStats = async (pgClient, minerId, { total, successful, successful_http}) => { - debug('Updating public retrieval stats for miner %s: total += %s successful += %s, sucessful_http += %s', minerId, total, successful, successful_http) +const updateRetrievalStats = async (pgClient, minerId, { total, successful, successfulHttp }) => { + debug('Updating public retrieval stats for miner %s: total += %s successful += %s, successful_http += %s', minerId, total, successful, successfulHttp) await pgClient.query(` INSERT INTO retrieval_stats (day, miner_id, total, successful, successful_http) @@ -49,13 +49,13 @@ const updateRetrievalStats = async (pgClient, minerId, { total, successful, succ (now(), $1, $2, $3, $4) ON CONFLICT(day, miner_id) DO UPDATE SET total = retrieval_stats.total + $2, - successful = retrieval_stats.successful + $3 - sucessful_http = retrieval_stats.successful_http + $4 + successful = retrieval_stats.successful + $3, + successful_http = retrieval_stats.successful_http + $4 `, [ minerId, total, successful, - successful_http + successfulHttp ]) } diff --git a/migrations/001.do.retrieval-stats.sql b/migrations/001.do.retrieval-stats.sql index cbb71ca7..b4f90dd0 100644 --- a/migrations/001.do.retrieval-stats.sql +++ b/migrations/001.do.retrieval-stats.sql @@ -1,5 +1,6 @@ CREATE TABLE retrieval_stats ( day DATE NOT NULL PRIMARY KEY, total INT NOT NULL, - successful INT NOT NULL + successful INT NOT NULL, + successful_http INT NOT NULL ); diff --git a/test/evaluate.js b/test/evaluate.js index 2e01baee..2adf8f92 100644 --- a/test/evaluate.js +++ b/test/evaluate.js @@ -96,10 +96,11 @@ describe('evaluate', async function () { day: today(), miner_id: VALID_TASK.minerId, total: 1, - successful: 1 + successful: 1, + // None of the measurments use http + successful_http: 0 }]) }) - it('handles empty rounds', async () => { const round = new RoundData(0n) const setScoresCalls = [] diff --git a/test/provider-retrieval-result-stats.test.js b/test/provider-retrieval-result-stats.test.js index 2ee0a415..aa8db7fc 100644 --- a/test/provider-retrieval-result-stats.test.js +++ b/test/provider-retrieval-result-stats.test.js @@ -37,29 +37,33 @@ describe('Provider Retrieval Result Stats', () => { measurements: [ { minerId: '0', - retrievalResult: 'OK' + retrievalResult: 'OK', + protocol: 'http' }, { minerId: '1', - retrievalResult: 'TIMEOUT' + retrievalResult: 'TIMEOUT', + protocol: 'http' } ] }, { measurements: [ { minerId: '0', - retrievalResult: 'OK' + retrievalResult: 'OK', + protocol: 'bitswap' }, { minerId: '1', - retrievalResult: 'TIMEOUT' + retrievalResult: 'TIMEOUT', + protocol: 'bitswap' } ] } ]) assert.deepStrictEqual(stats, new Map([ - ['0', { total: 2, successful: 2 }], - ['1', { total: 2, successful: 0 }] + ['0', { total: 2, successful: 2, successfulHttp: 1 }], + ['1', { total: 2, successful: 0, successfulHttp: 0 }] ])) }) }) @@ -137,22 +141,26 @@ describe('Provider Retrieval Result Stats', () => { measurements: [ { minerId: '0', - retrievalResult: 'OK' + retrievalResult: 'OK', + protocol: 'http' }, { minerId: '1', - retrievalResult: 'TIMEOUT' + retrievalResult: 'TIMEOUT', + protocol: 'http' } ] }, { measurements: [ { minerId: '0', - retrievalResult: 'OK' + retrievalResult: 'OK', + protocol: 'bitswap' }, { minerId: '1', - retrievalResult: 'TIMEOUT' + retrievalResult: 'TIMEOUT', + protocol: 'bitswap' } ] } @@ -168,8 +176,8 @@ describe('Provider Retrieval Result Stats', () => { contract_address: ieContractAddress, measurement_batches: round.measurementBatches, provider_retrieval_result_stats: { - 0: { successful: 2, total: 2 }, - 1: { successful: 0, total: 2 } + 0: { successful: 2, total: 2, successfulHttp: 1 }, + 1: { successful: 0, total: 2, successfulHttp: 0 } }, round_details: 'baguqeerawg5jfpiy2g5xp5d422uwa3mpyzkmiguoeecesds7q65mn2hdoa4q', round_index: String(round.index), diff --git a/test/public-stats.test.js b/test/public-stats.test.js index 2354ab45..4787c002 100644 --- a/test/public-stats.test.js +++ b/test/public-stats.test.js @@ -87,6 +87,50 @@ describe('public-stats', () => { { day: today, total: 2 + 3, successful: 1 + 1 } ]) }) + it('calculates successful http retrievals correctly', async () => { + /** @type {Measurement[]} */ + const honestMeasurements = [ + { ...VALID_MEASUREMENT, protocol: 'http', retrievalResult: 'OK' }, + { ...VALID_MEASUREMENT, protocol: 'graphsync', retrievalResult: 'OK' }, + { ...VALID_MEASUREMENT, protocol: 'http', retrievalResult: 'HTTP_500' }, + { ...VALID_MEASUREMENT, protocol: 'graphsync', retrievalResult: 'LASSIE_500' } + ] + const allMeasurements = honestMeasurements + let committees = buildEvaluatedCommitteesFromMeasurements(honestMeasurements) + + await updatePublicStats({ + createPgClient, + committees, + honestMeasurements, + allMeasurements, + findDealClients: (_minerId, _cid) => ['f0client'] + }) + + const { rows: created } = await pgClient.query( + 'SELECT day::TEXT, total, successful, successful_http FROM retrieval_stats' + ) + assert.deepStrictEqual(created, [ + { day: today, total: 4, successful: 2, successful_http: 1 } + ]) + + // Let's add another successful http retrieval to make sure the updating process works as expected + honestMeasurements.push({ ...VALID_MEASUREMENT, retrievalResult: 'OK', protocol: 'http' }) + committees = buildEvaluatedCommitteesFromMeasurements(honestMeasurements) + await updatePublicStats({ + createPgClient, + committees, + honestMeasurements, + allMeasurements, + findDealClients: (_minerId, _cid) => ['f0client'] + }) + + const { rows: updated } = await pgClient.query( + 'SELECT day::TEXT, total, successful, successful_http FROM retrieval_stats' + ) + assert.deepStrictEqual(updated, [ + { day: today, total: 4 + 5, successful: 2 + 3, successful_http: 1 + 2 } + ]) + }) it('creates or updates the row for today - multiple miners', async () => { /** @type {Measurement[]} */ @@ -107,11 +151,11 @@ describe('public-stats', () => { findDealClients: (_minerId, _cid) => ['f0client'] }) const { rows: created } = await pgClient.query( - 'SELECT day::TEXT, miner_id, total, successful FROM retrieval_stats' + 'SELECT day::TEXT, miner_id, total, successful, successful_http FROM retrieval_stats' ) assert.deepStrictEqual(created, [ - { day: today, miner_id: 'f1first', total: 2, successful: 1 }, - { day: today, miner_id: 'f1second', total: 1, successful: 1 } + { day: today, miner_id: 'f1first', total: 2, successful: 1, successful_http: 0 }, + { day: today, miner_id: 'f1second', total: 1, successful: 1, successful_http: 0 } ]) honestMeasurements.push({ ...VALID_MEASUREMENT, minerId: 'f1first', retrievalResult: 'UNKNOWN_ERROR' }) @@ -127,11 +171,11 @@ describe('public-stats', () => { }) const { rows: updated } = await pgClient.query( - 'SELECT day::TEXT, miner_id, total, successful FROM retrieval_stats' + 'SELECT day::TEXT, miner_id, total, successful, successful_http FROM retrieval_stats' ) assert.deepStrictEqual(updated, [ - { day: today, miner_id: 'f1first', total: 2 + 3, successful: 1 + 1 }, - { day: today, miner_id: 'f1second', total: 1 + 2, successful: 1 + 1 } + { day: today, miner_id: 'f1first', total: 2 + 3, successful: 1 + 1, successful_http: 0 }, + { day: today, miner_id: 'f1second', total: 1 + 2, successful: 1 + 1, successful_http: 0 } ]) }) @@ -164,10 +208,10 @@ describe('public-stats', () => { }) const { rows: created } = await pgClient.query( - 'SELECT day::TEXT, total, successful FROM retrieval_stats' + 'SELECT day::TEXT, total, successful, successful_http FROM retrieval_stats' ) assert.deepStrictEqual(created, [ - { day: today, total: 3, successful: 2 } + { day: today, total: 3, successful: 2, successful_http: 0 } ]) }) }) From f8d4e80e8af4ca11b5c63d918ab2e5e39725caf6 Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Wed, 8 Jan 2025 14:20:50 +0100 Subject: [PATCH 07/15] remove redundant tests --- lib/provider-retrieval-result-stats.js | 2 +- test/public-stats.test.js | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/provider-retrieval-result-stats.js b/lib/provider-retrieval-result-stats.js index fb93b559..6bcc4692 100644 --- a/lib/provider-retrieval-result-stats.js +++ b/lib/provider-retrieval-result-stats.js @@ -26,7 +26,7 @@ export const build = committees => { retrievalStats.total++ if (m.retrievalResult === 'OK') { retrievalStats.successful++ - if (m.protocol.toLowerCase() === 'http') { + if (m.protocol && m.protocol.toLowerCase() === 'http') { retrievalStats.successfulHttp++ } } diff --git a/test/public-stats.test.js b/test/public-stats.test.js index 4787c002..d344a69f 100644 --- a/test/public-stats.test.js +++ b/test/public-stats.test.js @@ -151,11 +151,11 @@ describe('public-stats', () => { findDealClients: (_minerId, _cid) => ['f0client'] }) const { rows: created } = await pgClient.query( - 'SELECT day::TEXT, miner_id, total, successful, successful_http FROM retrieval_stats' + 'SELECT day::TEXT, miner_id, total, successful FROM retrieval_stats' ) assert.deepStrictEqual(created, [ - { day: today, miner_id: 'f1first', total: 2, successful: 1, successful_http: 0 }, - { day: today, miner_id: 'f1second', total: 1, successful: 1, successful_http: 0 } + { day: today, miner_id: 'f1first', total: 2, successful: 1 }, + { day: today, miner_id: 'f1second', total: 1, successful: 1 } ]) honestMeasurements.push({ ...VALID_MEASUREMENT, minerId: 'f1first', retrievalResult: 'UNKNOWN_ERROR' }) @@ -171,11 +171,11 @@ describe('public-stats', () => { }) const { rows: updated } = await pgClient.query( - 'SELECT day::TEXT, miner_id, total, successful, successful_http FROM retrieval_stats' + 'SELECT day::TEXT, miner_id, total, successful FROM retrieval_stats' ) assert.deepStrictEqual(updated, [ - { day: today, miner_id: 'f1first', total: 2 + 3, successful: 1 + 1, successful_http: 0 }, - { day: today, miner_id: 'f1second', total: 1 + 2, successful: 1 + 1, successful_http: 0 } + { day: today, miner_id: 'f1first', total: 2 + 3, successful: 1 + 1 }, + { day: today, miner_id: 'f1second', total: 1 + 2, successful: 1 + 1 } ]) }) From 21134f4fb159226dc81b778a7a836227078898ab Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Wed, 8 Jan 2025 14:22:52 +0100 Subject: [PATCH 08/15] add check for undefined protocol --- test/provider-retrieval-result-stats.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/provider-retrieval-result-stats.test.js b/test/provider-retrieval-result-stats.test.js index aa8db7fc..35e4fd62 100644 --- a/test/provider-retrieval-result-stats.test.js +++ b/test/provider-retrieval-result-stats.test.js @@ -54,9 +54,9 @@ describe('Provider Retrieval Result Stats', () => { protocol: 'bitswap' }, { + // Should be able to handle and reject undefined protocol minerId: '1', - retrievalResult: 'TIMEOUT', - protocol: 'bitswap' + retrievalResult: 'TIMEOUT' } ] } From e8436781c52a72a044e350b1193d6596334b80b6 Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl <113891786+NikolasHaimerl@users.noreply.github.com> Date: Wed, 8 Jan 2025 14:52:04 +0100 Subject: [PATCH 09/15] Update test/evaluate.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Miroslav Bajtoš --- test/evaluate.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/evaluate.js b/test/evaluate.js index 2adf8f92..ae7c3d9a 100644 --- a/test/evaluate.js +++ b/test/evaluate.js @@ -97,7 +97,7 @@ describe('evaluate', async function () { miner_id: VALID_TASK.minerId, total: 1, successful: 1, - // None of the measurments use http + // None of the measurements use http successful_http: 0 }]) }) From 5517422113467a92860fa5bebc27403248b759f7 Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Wed, 8 Jan 2025 15:11:27 +0100 Subject: [PATCH 10/15] use pointerize --- lib/preprocess.js | 2 +- lib/provider-retrieval-result-stats.js | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/preprocess.js b/lib/preprocess.js index 9a166ed4..36fcffb7 100644 --- a/lib/preprocess.js +++ b/lib/preprocess.js @@ -27,7 +27,7 @@ export class Measurement { this.inet_group = pointerize(m.inet_group) this.finished_at = parseDateTime(m.finished_at) this.provider_address = pointerize(m.provider_address) - this.protocol = pointerize(m.protocol) + this.protocol = pointerize(m.protocol?.toLowerCase()) this.byte_length = m.byte_length this.start_at = parseDateTime(m.start_at) this.first_byte_at = parseDateTime(m.first_byte_at) diff --git a/lib/provider-retrieval-result-stats.js b/lib/provider-retrieval-result-stats.js index 6bcc4692..69f66ee7 100644 --- a/lib/provider-retrieval-result-stats.js +++ b/lib/provider-retrieval-result-stats.js @@ -26,9 +26,7 @@ export const build = committees => { retrievalStats.total++ if (m.retrievalResult === 'OK') { retrievalStats.successful++ - if (m.protocol && m.protocol.toLowerCase() === 'http') { - retrievalStats.successfulHttp++ - } + if (m.protocol && m.protocol === 'http') { retrievalStats.successfulHttp++ } } providerRetrievalResultStats.set(minerId, retrievalStats) } From b4b919e5cc6969fcdd3d4268b9f426a066be35a2 Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Wed, 8 Jan 2025 15:27:24 +0100 Subject: [PATCH 11/15] add column migration --- migrations/001.do.retrieval-stats.sql | 3 +-- migrations/021.do.sucessful-http-retrieval-stats.sql | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 migrations/021.do.sucessful-http-retrieval-stats.sql diff --git a/migrations/001.do.retrieval-stats.sql b/migrations/001.do.retrieval-stats.sql index b4f90dd0..cbb71ca7 100644 --- a/migrations/001.do.retrieval-stats.sql +++ b/migrations/001.do.retrieval-stats.sql @@ -1,6 +1,5 @@ CREATE TABLE retrieval_stats ( day DATE NOT NULL PRIMARY KEY, total INT NOT NULL, - successful INT NOT NULL, - successful_http INT NOT NULL + successful INT NOT NULL ); diff --git a/migrations/021.do.sucessful-http-retrieval-stats.sql b/migrations/021.do.sucessful-http-retrieval-stats.sql new file mode 100644 index 00000000..4cfe82b7 --- /dev/null +++ b/migrations/021.do.sucessful-http-retrieval-stats.sql @@ -0,0 +1,2 @@ +ALTER TABLE retrieval_stats +ADD COLUMN IF NOT EXISTS successful_http INT NOT NULL DEFAULT 0 \ No newline at end of file From 2573399aee10f5af15f39bf2a4e812307e3f95c5 Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Wed, 8 Jan 2025 16:07:41 +0100 Subject: [PATCH 12/15] add EOF --- migrations/021.do.sucessful-http-retrieval-stats.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/021.do.sucessful-http-retrieval-stats.sql b/migrations/021.do.sucessful-http-retrieval-stats.sql index 4cfe82b7..0c1e7be2 100644 --- a/migrations/021.do.sucessful-http-retrieval-stats.sql +++ b/migrations/021.do.sucessful-http-retrieval-stats.sql @@ -1,2 +1,2 @@ ALTER TABLE retrieval_stats -ADD COLUMN IF NOT EXISTS successful_http INT NOT NULL DEFAULT 0 \ No newline at end of file +ADD COLUMN IF NOT EXISTS successful_http INT NOT NULL DEFAULT 0 From 02fa8dea8cef26497442041bbbfd24ea9341e9b8 Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Wed, 8 Jan 2025 16:08:06 +0100 Subject: [PATCH 13/15] add EOF --- migrations/021.do.sucessful-http-retrieval-stats.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/021.do.sucessful-http-retrieval-stats.sql b/migrations/021.do.sucessful-http-retrieval-stats.sql index 0c1e7be2..b3a7ab1f 100644 --- a/migrations/021.do.sucessful-http-retrieval-stats.sql +++ b/migrations/021.do.sucessful-http-retrieval-stats.sql @@ -1,2 +1,2 @@ ALTER TABLE retrieval_stats -ADD COLUMN IF NOT EXISTS successful_http INT NOT NULL DEFAULT 0 +ADD COLUMN IF NOT EXISTS successful_http INT NOT NULL DEFAULT 0; From bb351e646e08366ec0a25c0950f5e568a388cee2 Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Wed, 8 Jan 2025 16:14:04 +0100 Subject: [PATCH 14/15] remove NL --- migrations/021.do.sucessful-http-retrieval-stats.sql | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/migrations/021.do.sucessful-http-retrieval-stats.sql b/migrations/021.do.sucessful-http-retrieval-stats.sql index b3a7ab1f..e2bb0087 100644 --- a/migrations/021.do.sucessful-http-retrieval-stats.sql +++ b/migrations/021.do.sucessful-http-retrieval-stats.sql @@ -1,2 +1 @@ -ALTER TABLE retrieval_stats -ADD COLUMN IF NOT EXISTS successful_http INT NOT NULL DEFAULT 0; +ALTER TABLE retrieval_stats ADD COLUMN IF NOT EXISTS successful_http INT NOT NULL DEFAULT 0; From b64c5e09ede62a3171983742c94f5e1ef9dba7d9 Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Wed, 8 Jan 2025 22:05:30 +0100 Subject: [PATCH 15/15] make column nullable --- migrations/021.do.sucessful-http-retrieval-stats.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/021.do.sucessful-http-retrieval-stats.sql b/migrations/021.do.sucessful-http-retrieval-stats.sql index e2bb0087..a95de3e0 100644 --- a/migrations/021.do.sucessful-http-retrieval-stats.sql +++ b/migrations/021.do.sucessful-http-retrieval-stats.sql @@ -1 +1 @@ -ALTER TABLE retrieval_stats ADD COLUMN IF NOT EXISTS successful_http INT NOT NULL DEFAULT 0; +ALTER TABLE retrieval_stats ADD COLUMN IF NOT EXISTS successful_http INT;