From 7b1e8525385bb723c613973b817d54c7fd37ae1f Mon Sep 17 00:00:00 2001 From: Caesar Mukama Date: Tue, 28 Apr 2026 12:41:17 +0300 Subject: [PATCH] fix: processBlockData parses HISTORICAL_BLOCKSIZES flat-array shape The mempool worker's getWrkExtData returns a flat array of block records [{ts, blockSize, blockReward, blockTotalFees}, ...], but processBlockData only handled nested .data/.blocks wrappers - it iterated entry's own field names, Number('ts') returned NaN, and produced an empty daily map. The SubsidyFee page then rendered "No data available". Detect the flat shape (entry has .ts/.timestamp/.time) and process it directly. Also surface blockSize on getSubsidyFees and getRevenueSummary log entries (and totalBlockSize/avgBlockSize on the summary) - needed for SubsidyFee's "Avg Fees in Sats/vByte" chart to render after this fix. --- tests/unit/handlers/finance.handlers.test.js | 6 ++++-- tests/unit/handlers/finance.utils.test.js | 19 ++++++++++++++++++- .../lib/server/handlers/finance.handlers.js | 15 +++++++++++---- workers/lib/server/handlers/finance.utils.js | 16 ++++++++++------ 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/tests/unit/handlers/finance.handlers.test.js b/tests/unit/handlers/finance.handlers.test.js index 0127a15..7a7a6a7 100644 --- a/tests/unit/handlers/finance.handlers.test.js +++ b/tests/unit/handlers/finance.handlers.test.js @@ -569,16 +569,18 @@ test('getSubsidyFees - empty ork results', async (t) => { test('calculateSubsidyFeesSummary - calculates from log entries', (t) => { const log = [ - { blockReward: 6.25, blockTotalFees: 0.5 }, - { blockReward: 6.25, blockTotalFees: 0.3 } + { blockReward: 6.25, blockTotalFees: 0.5, blockSize: 1500000 }, + { blockReward: 6.25, blockTotalFees: 0.3, blockSize: 1300000 } ] const summary = calculateSubsidyFeesSummary(log) t.is(summary.totalBlockReward, 12.5, 'should sum block rewards') t.is(summary.totalBlockTotalFees, 0.8, 'should sum block fees') + t.is(summary.totalBlockSize, 2800000, 'should sum block sizes') t.ok(summary.avgBlockReward !== null, 'should calculate avg block reward') t.is(summary.avgBlockReward, 6.25, 'should calculate correct avg block reward') t.ok(summary.avgBlockTotalFees !== null, 'should calculate avg block fees') + t.is(summary.avgBlockSize, 1400000, 'should calculate correct avg block size') t.pass() }) diff --git a/tests/unit/handlers/finance.utils.test.js b/tests/unit/handlers/finance.utils.test.js index b82f793..65a0adb 100644 --- a/tests/unit/handlers/finance.utils.test.js +++ b/tests/unit/handlers/finance.utils.test.js @@ -205,7 +205,8 @@ test('processBlockData - array items', (t) => { blocks: [{ ts: 1700006400000, blockReward: 6.25, - blockTotalFees: 0.5 + blockTotalFees: 0.5, + blockSize: 1500000 }] }] ] @@ -213,6 +214,22 @@ test('processBlockData - array items', (t) => { const key = Object.keys(daily)[0] t.is(daily[key].blockReward, 6.25, 'should extract blockReward') t.is(daily[key].blockTotalFees, 0.5, 'should extract blockTotalFees') + t.is(daily[key].blockSize, 1500000, 'should extract blockSize') + t.pass() +}) + +test('processBlockData - flat per-ork items (production shape)', (t) => { + const results = [ + [ + { ts: 1700006400000, blockSize: 1500000, blockHash: 'abc', blockReward: 6.25, blockTotalFees: 0.5 }, + { ts: 1700006400000, blockSize: 1200000, blockHash: 'def', blockReward: 6.25, blockTotalFees: 0.3 } + ] + ] + const daily = processBlockData(results) + const key = Object.keys(daily)[0] + t.is(daily[key].blockReward, 12.5, 'should sum blockReward across same-day items') + t.is(daily[key].blockTotalFees, 0.8, 'should sum blockTotalFees across same-day items') + t.is(daily[key].blockSize, 2700000, 'should sum blockSize across same-day items') t.pass() }) diff --git a/workers/lib/server/handlers/finance.handlers.js b/workers/lib/server/handlers/finance.handlers.js index 444e90d..7cb3457 100644 --- a/workers/lib/server/handlers/finance.handlers.js +++ b/workers/lib/server/handlers/finance.handlers.js @@ -628,7 +628,8 @@ async function getSubsidyFees (ctx, req) { log.push({ ts, blockReward: block.blockReward, - blockTotalFees: block.blockTotalFees + blockTotalFees: block.blockTotalFees, + blockSize: block.blockSize }) } @@ -643,22 +644,27 @@ function calculateSubsidyFeesSummary (log) { return { totalBlockReward: 0, totalBlockTotalFees: 0, + totalBlockSize: 0, avgBlockReward: null, - avgBlockTotalFees: null + avgBlockTotalFees: null, + avgBlockSize: null } } const totals = log.reduce((acc, entry) => { acc.blockReward += entry.blockReward || 0 acc.blockTotalFees += entry.blockTotalFees || 0 + acc.blockSize += entry.blockSize || 0 return acc - }, { blockReward: 0, blockTotalFees: 0 }) + }, { blockReward: 0, blockTotalFees: 0, blockSize: 0 }) return { totalBlockReward: totals.blockReward, totalBlockTotalFees: totals.blockTotalFees, + totalBlockSize: totals.blockSize, avgBlockReward: safeDiv(totals.blockReward, log.length), - avgBlockTotalFees: safeDiv(totals.blockTotalFees, log.length) + avgBlockTotalFees: safeDiv(totals.blockTotalFees, log.length), + avgBlockSize: safeDiv(totals.blockSize, log.length) } } @@ -879,6 +885,7 @@ async function getRevenueSummary (ctx, req) { hashRevenueUSDPerPHsPerDay: safeDiv(revenueUSD, hashratePhs), blockReward: block.blockReward || 0, blockTotalFees: block.blockTotalFees || 0, + blockSize: block.blockSize || 0, curtailmentMWh, curtailmentRate, operationalIssuesRate, diff --git a/workers/lib/server/handlers/finance.utils.js b/workers/lib/server/handlers/finance.utils.js index 8b6746c..3ca98f4 100644 --- a/workers/lib/server/handlers/finance.utils.js +++ b/workers/lib/server/handlers/finance.utils.js @@ -94,25 +94,29 @@ function processBlockData (results) { if (!Array.isArray(data)) continue for (const entry of data) { if (!entry) continue - const items = entry.data || entry.blocks || entry + // mempool returns a flat array of block records; entry IS the item. + const rawTs = entry.ts || entry.timestamp || entry.time + const items = rawTs ? [entry] : (entry.data || entry.blocks || entry) if (Array.isArray(items)) { for (const item of items) { if (!item) continue - const rawTs = item.ts || item.timestamp || item.time - const ts = getStartOfDay(normalizeTimestampMs(rawTs)) + const itemTs = item.ts || item.timestamp || item.time + const ts = getStartOfDay(normalizeTimestampMs(itemTs)) if (!ts) continue - if (!daily[ts]) daily[ts] = { blockReward: 0, blockTotalFees: 0 } + if (!daily[ts]) daily[ts] = { blockReward: 0, blockTotalFees: 0, blockSize: 0 } daily[ts].blockReward += (item.blockReward || item.block_reward || item.subsidy || 0) daily[ts].blockTotalFees += (item.blockTotalFees || item.block_total_fees || item.totalFees || item.total_fees || 0) + daily[ts].blockSize += (item.blockSize || item.block_size || item.size || 0) } - } else if (typeof items === 'object' && !Array.isArray(items)) { + } else if (typeof items === 'object') { for (const [key, val] of Object.entries(items)) { const ts = getStartOfDay(Number(key)) if (!ts) continue - if (!daily[ts]) daily[ts] = { blockReward: 0, blockTotalFees: 0 } + if (!daily[ts]) daily[ts] = { blockReward: 0, blockTotalFees: 0, blockSize: 0 } if (typeof val === 'object') { daily[ts].blockReward += (val.blockReward || val.block_reward || val.subsidy || 0) daily[ts].blockTotalFees += (val.blockTotalFees || val.block_total_fees || val.totalFees || val.total_fees || 0) + daily[ts].blockSize += (val.blockSize || val.block_size || val.size || 0) } } }