From 90a011c67d42639a0f3f4d1002417313e00d0e2b Mon Sep 17 00:00:00 2001 From: Mononaut Date: Sun, 22 Jun 2025 12:45:35 +0000 Subject: [PATCH 1/4] fix sub-1 sat/vb colors --- frontend/src/app/app.constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/app.constants.ts b/frontend/src/app/app.constants.ts index 0fe519a01..b20ac3067 100644 --- a/frontend/src/app/app.constants.ts +++ b/frontend/src/app/app.constants.ts @@ -125,7 +125,7 @@ export const poolsColor = { 'unknown': '#FDD835', }; -export const feeLevels = [1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100, 125, 150, 175, 200, +export const feeLevels = [0, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100, 125, 150, 175, 200, 250, 300, 350, 400, 500, 600, 700, 800, 900, 1000, 1200, 1400, 1600, 1800, 2000]; export interface Language { From 2c27941bf2abdb7d670fe9cf3332c49398f67327 Mon Sep 17 00:00:00 2001 From: Mononaut Date: Mon, 23 Jun 2025 03:22:47 +0000 Subject: [PATCH 2/4] fix sub sat charts --- frontend/src/app/app.constants.ts | 5 ++++- .../accelerator-dashboard/accelerator-dashboard.component.ts | 2 +- frontend/src/app/components/block-overview-graph/utils.ts | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/app.constants.ts b/frontend/src/app/app.constants.ts index b20ac3067..bf0b45c06 100644 --- a/frontend/src/app/app.constants.ts +++ b/frontend/src/app/app.constants.ts @@ -1,4 +1,5 @@ export const defaultMempoolFeeColors = [ + '557d00', '557d00', '5d7d01', '637d02', @@ -40,6 +41,7 @@ export const defaultMempoolFeeColors = [ ]; export const contrastMempoolFeeColors = [ + '0082e6', '0082e6', '0984df', '1285d9', @@ -81,6 +83,7 @@ export const contrastMempoolFeeColors = [ ]; export const chartColors = [ + "#D81B60", "#D81B60", "#8E24AA", "#5E35B1", @@ -125,7 +128,7 @@ export const poolsColor = { 'unknown': '#FDD835', }; -export const feeLevels = [0, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100, 125, 150, 175, 200, +export const feeLevels = [0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100, 125, 150, 175, 200, 250, 300, 350, 400, 500, 600, 700, 800, 900, 1000, 1200, 1400, 1600, 1800, 2000]; export interface Language { diff --git a/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.ts b/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.ts index ab7d9122e..2e6e9c402 100644 --- a/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.ts +++ b/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.ts @@ -153,7 +153,7 @@ export class AcceleratorDashboardComponent implements OnInit, OnDestroy { return acceleratedColor; } else { const rate = tx.fee / tx.vsize; // color by simple single-tx fee rate - const feeLevelIndex = feeLevels.findIndex((feeLvl) => Math.max(1, rate) < feeLvl) - 1; + const feeLevelIndex = feeLevels.findIndex((feeLvl) => Math.max(0, rate) < feeLvl) - 1; return this.theme.theme === 'contrast' || this.theme.theme === 'bukele' ? contrastColors[feeLevelIndex] || contrastColors[contrastColors.length - 1] : normalColors[feeLevelIndex] || normalColors[normalColors.length - 1]; } } diff --git a/frontend/src/app/components/block-overview-graph/utils.ts b/frontend/src/app/components/block-overview-graph/utils.ts index 94ab9b686..985751b4a 100644 --- a/frontend/src/app/components/block-overview-graph/utils.ts +++ b/frontend/src/app/components/block-overview-graph/utils.ts @@ -65,7 +65,7 @@ const defaultColors: { [key: string]: ColorPalette } = { base: defaultMempoolFeeColors.map(hexToColor), audit: [], marginal: [], - baseLevel: (tx: TxView, rate: number) => feeLevels.findIndex((feeLvl) => Math.max(1, rate) < feeLvl) - 1 + baseLevel: (tx: TxView, rate: number) => feeLevels.findIndex((feeLvl) => Math.max(0, rate) < feeLvl) - 1 }, } for (const key in defaultColors) { @@ -96,7 +96,7 @@ const contrastColors: { [key: string]: ColorPalette } = { base: contrastMempoolFeeColors.map(hexToColor), audit: [], marginal: [], - baseLevel: (tx: TxView, rate: number) => feeLevels.findIndex((feeLvl) => Math.max(1, rate) < feeLvl) - 1 + baseLevel: (tx: TxView, rate: number) => feeLevels.findIndex((feeLvl) => Math.max(0, rate) < feeLvl) - 1 }, } for (const key in contrastColors) { From bee74460e0bf8401aa40cfef5dc4a19169d9a85c Mon Sep 17 00:00:00 2001 From: Mononaut Date: Mon, 23 Jun 2025 03:48:09 +0000 Subject: [PATCH 3/4] support sub 1 sat rates in stats chart --- backend/src/api/database-migration.ts | 8 +- backend/src/api/statistics/statistics-api.ts | 87 ++++++++++--------- backend/src/api/statistics/statistics.ts | 3 +- backend/src/mempool.interfaces.ts | 1 + frontend/src/app/app.constants.ts | 2 +- .../mempool-graph/mempool-graph.component.ts | 2 +- .../statistics/statistics.component.ts | 4 +- 7 files changed, 61 insertions(+), 46 deletions(-) diff --git a/backend/src/api/database-migration.ts b/backend/src/api/database-migration.ts index fbaf05658..99af80a0e 100644 --- a/backend/src/api/database-migration.ts +++ b/backend/src/api/database-migration.ts @@ -7,7 +7,7 @@ import cpfpRepository from '../repositories/CpfpRepository'; import { RowDataPacket } from 'mysql2'; class DatabaseMigration { - private static currentVersion = 98; + private static currentVersion = 99; private queryTimeout = 3600_000; private statisticsAddedIndexed = false; private uniqueLogs: string[] = []; @@ -1154,6 +1154,12 @@ class DatabaseMigration { await this.$executeQuery('UPDATE blocks_summaries SET version = 0 WHERE height >= 896070;'); await this.updateToSchemaVersion(98); } + + // Add vsize_0 to statistics table + if (databaseSchemaVersion < 99) { + await this.$executeQuery('ALTER TABLE statistics ADD COLUMN vsize_0 int(11) NOT NULL DEFAULT 0'); + await this.updateToSchemaVersion(99); + } } /** diff --git a/backend/src/api/statistics/statistics-api.ts b/backend/src/api/statistics/statistics-api.ts index 2d66d69d9..a8cc7470a 100644 --- a/backend/src/api/statistics/statistics-api.ts +++ b/backend/src/api/statistics/statistics-api.ts @@ -16,6 +16,7 @@ class StatisticsApi { fee_data, total_fee, min_fee, + vsize_0, vsize_1, vsize_2, vsize_3, @@ -55,7 +56,7 @@ class StatisticsApi { vsize_1800, vsize_2000 ) - VALUES (NOW(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + VALUES (NOW(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)`; const [result]: any = await DB.query(query); return result.insertId; @@ -75,6 +76,7 @@ class StatisticsApi { fee_data, total_fee, min_fee, + vsize_0, vsize_1, vsize_2, vsize_3, @@ -115,7 +117,7 @@ class StatisticsApi { vsize_2000 ) VALUES (${convertToDatetime ? `FROM_UNIXTIME(${statistics.added})` : statistics.added}, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, - ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`; + ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`; const params: (string | number)[] = [ statistics.unconfirmed_transactions, @@ -125,6 +127,7 @@ class StatisticsApi { statistics.fee_data, statistics.total_fee, statistics.min_fee, + statistics.vsize_0, statistics.vsize_1, statistics.vsize_2, statistics.vsize_3, @@ -177,6 +180,7 @@ class StatisticsApi { CAST(avg(unconfirmed_transactions) as DOUBLE) as unconfirmed_transactions, CAST(avg(vbytes_per_second) as DOUBLE) as vbytes_per_second, CAST(avg(min_fee) as DOUBLE) as min_fee, + CAST(avg(vsize_0) as DOUBLE) as vsize_0, CAST(avg(vsize_1) as DOUBLE) as vsize_1, CAST(avg(vsize_2) as DOUBLE) as vsize_2, CAST(avg(vsize_3) as DOUBLE) as vsize_3, @@ -227,6 +231,7 @@ class StatisticsApi { CAST(avg(unconfirmed_transactions) as DOUBLE) as unconfirmed_transactions, CAST(avg(vbytes_per_second) as DOUBLE) as vbytes_per_second, CAST(avg(min_fee) as DOUBLE) as min_fee, + vsize_0, vsize_1, vsize_2, vsize_3, @@ -414,6 +419,7 @@ class StatisticsApi { total_fee: s.total_fee, min_fee: s.min_fee, vsizes: [ + s.vsize_0, s.vsize_1, s.vsize_2, s.vsize_3, @@ -468,44 +474,45 @@ class StatisticsApi { total_fee: s.total_fee || 0, min_fee: s.min_fee, fee_data: '', - vsize_1: s.vsizes[0], - vsize_2: s.vsizes[1], - vsize_3: s.vsizes[2], - vsize_4: s.vsizes[3], - vsize_5: s.vsizes[4], - vsize_6: s.vsizes[5], - vsize_8: s.vsizes[6], - vsize_10: s.vsizes[7], - vsize_12: s.vsizes[8], - vsize_15: s.vsizes[9], - vsize_20: s.vsizes[10], - vsize_30: s.vsizes[11], - vsize_40: s.vsizes[12], - vsize_50: s.vsizes[13], - vsize_60: s.vsizes[14], - vsize_70: s.vsizes[15], - vsize_80: s.vsizes[16], - vsize_90: s.vsizes[17], - vsize_100: s.vsizes[18], - vsize_125: s.vsizes[19], - vsize_150: s.vsizes[20], - vsize_175: s.vsizes[21], - vsize_200: s.vsizes[22], - vsize_250: s.vsizes[23], - vsize_300: s.vsizes[24], - vsize_350: s.vsizes[25], - vsize_400: s.vsizes[26], - vsize_500: s.vsizes[27], - vsize_600: s.vsizes[28], - vsize_700: s.vsizes[29], - vsize_800: s.vsizes[30], - vsize_900: s.vsizes[31], - vsize_1000: s.vsizes[32], - vsize_1200: s.vsizes[33], - vsize_1400: s.vsizes[34], - vsize_1600: s.vsizes[35], - vsize_1800: s.vsizes[36], - vsize_2000: s.vsizes[37], + vsize_0: s.vsizes[0], + vsize_1: s.vsizes[1], + vsize_2: s.vsizes[2], + vsize_3: s.vsizes[3], + vsize_4: s.vsizes[4], + vsize_5: s.vsizes[5], + vsize_6: s.vsizes[6], + vsize_8: s.vsizes[7], + vsize_10: s.vsizes[8], + vsize_12: s.vsizes[9], + vsize_15: s.vsizes[10], + vsize_20: s.vsizes[11], + vsize_30: s.vsizes[12], + vsize_40: s.vsizes[13], + vsize_50: s.vsizes[14], + vsize_60: s.vsizes[15], + vsize_70: s.vsizes[16], + vsize_80: s.vsizes[17], + vsize_90: s.vsizes[18], + vsize_100: s.vsizes[19], + vsize_125: s.vsizes[20], + vsize_150: s.vsizes[21], + vsize_175: s.vsizes[22], + vsize_200: s.vsizes[23], + vsize_250: s.vsizes[24], + vsize_300: s.vsizes[25], + vsize_350: s.vsizes[26], + vsize_400: s.vsizes[27], + vsize_500: s.vsizes[28], + vsize_600: s.vsizes[29], + vsize_700: s.vsizes[30], + vsize_800: s.vsizes[31], + vsize_900: s.vsizes[32], + vsize_1000: s.vsizes[33], + vsize_1200: s.vsizes[34], + vsize_1400: s.vsizes[35], + vsize_1600: s.vsizes[36], + vsize_1800: s.vsizes[37], + vsize_2000: s.vsizes[38], } }); } diff --git a/backend/src/api/statistics/statistics.ts b/backend/src/api/statistics/statistics.ts index 2926a4b17..62dff3d66 100644 --- a/backend/src/api/statistics/statistics.ts +++ b/backend/src/api/statistics/statistics.ts @@ -73,7 +73,7 @@ class Statistics { const totalWeight = memPoolArray.map((tx) => tx.vsize).reduce((acc, curr) => acc + curr) * 4; const totalFee = memPoolArray.map((tx) => tx.fee).reduce((acc, curr) => acc + curr); - const logFees = [1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100, 125, 150, 175, 200, + const logFees = [0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100, 125, 150, 175, 200, 250, 300, 350, 400, 500, 600, 700, 800, 900, 1000, 1200, 1400, 1600, 1800, 2000]; const weightVsizeFees: { [feePerWU: number]: number } = {}; @@ -109,6 +109,7 @@ class Statistics { total_fee: totalFee, fee_data: '', min_fee: minFee, + vsize_0: weightVsizeFees['0'] || 0, vsize_1: weightVsizeFees['1'] || 0, vsize_2: weightVsizeFees['2'] || 0, vsize_3: weightVsizeFees['3'] || 0, diff --git a/backend/src/mempool.interfaces.ts b/backend/src/mempool.interfaces.ts index 7059eb936..7808fec7f 100644 --- a/backend/src/mempool.interfaces.ts +++ b/backend/src/mempool.interfaces.ts @@ -406,6 +406,7 @@ export interface Statistic { fee_data: string; min_fee: number; + vsize_0: number; vsize_1: number; vsize_2: number; vsize_3: number; diff --git a/frontend/src/app/app.constants.ts b/frontend/src/app/app.constants.ts index bf0b45c06..85a4d35d8 100644 --- a/frontend/src/app/app.constants.ts +++ b/frontend/src/app/app.constants.ts @@ -83,7 +83,7 @@ export const contrastMempoolFeeColors = [ ]; export const chartColors = [ - "#D81B60", + "#A81524", "#D81B60", "#8E24AA", "#5E35B1", diff --git a/frontend/src/app/components/mempool-graph/mempool-graph.component.ts b/frontend/src/app/components/mempool-graph/mempool-graph.component.ts index 15e6c6f7a..3de592cc2 100644 --- a/frontend/src/app/components/mempool-graph/mempool-graph.component.ts +++ b/frontend/src/app/components/mempool-graph/mempool-graph.component.ts @@ -117,7 +117,7 @@ export class MempoolGraphComponent implements OnInit, OnChanges { let feesArray: number[][] = []; let maxTier = 0; - for (let index = 37; index > -1; index--) { + for (let index = 38; index > -1; index--) { feesArray = []; mempoolStats.forEach((stats) => { if (stats.vsizes[index] >= this.filterSize) { diff --git a/frontend/src/app/components/statistics/statistics.component.ts b/frontend/src/app/components/statistics/statistics.component.ts index 9dda3c496..80f92705b 100644 --- a/frontend/src/app/components/statistics/statistics.component.ts +++ b/frontend/src/app/components/statistics/statistics.component.ts @@ -30,7 +30,7 @@ export class StatisticsComponent implements OnInit { feeLevels = feeLevels; chartColors = chartColors; filterSize = 100000; - filterFeeIndex = 1; + filterFeeIndex = 0; showCount = false; maxFeeIndex: number; dropDownOpen = false; @@ -146,7 +146,7 @@ export class StatisticsComponent implements OnInit { const labels = mempoolStats.map(stats => stats.added); let maxTier = 0; - for (let index = 37; index > -1; index--) { + for (let index = 38; index > -1; index--) { mempoolStats.forEach((stats) => { if (stats.vsizes[index] >= this.filterSize) { maxTier = Math.max(maxTier, index); From 9430d3ea0612963e360837bf599c956a5196d2d8 Mon Sep 17 00:00:00 2001 From: Mononaut Date: Mon, 23 Jun 2025 06:14:53 +0000 Subject: [PATCH 4/4] Fix vsize_0 handling in statistics replication --- backend/src/api/statistics/statistics-api.ts | 79 ++++++++++---------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/backend/src/api/statistics/statistics-api.ts b/backend/src/api/statistics/statistics-api.ts index a8cc7470a..fa13b60b9 100644 --- a/backend/src/api/statistics/statistics-api.ts +++ b/backend/src/api/statistics/statistics-api.ts @@ -465,6 +465,7 @@ class StatisticsApi { public mapOptimizedStatisticToStatistic(statistic: OptimizedStatistic[]): Statistic[] { return statistic.map((s) => { + const completeVsizes = s.vsizes.length === 37 ? [0, ...s.vsizes] : s.vsizes; return { added: s.added, unconfirmed_transactions: s.count, @@ -474,45 +475,45 @@ class StatisticsApi { total_fee: s.total_fee || 0, min_fee: s.min_fee, fee_data: '', - vsize_0: s.vsizes[0], - vsize_1: s.vsizes[1], - vsize_2: s.vsizes[2], - vsize_3: s.vsizes[3], - vsize_4: s.vsizes[4], - vsize_5: s.vsizes[5], - vsize_6: s.vsizes[6], - vsize_8: s.vsizes[7], - vsize_10: s.vsizes[8], - vsize_12: s.vsizes[9], - vsize_15: s.vsizes[10], - vsize_20: s.vsizes[11], - vsize_30: s.vsizes[12], - vsize_40: s.vsizes[13], - vsize_50: s.vsizes[14], - vsize_60: s.vsizes[15], - vsize_70: s.vsizes[16], - vsize_80: s.vsizes[17], - vsize_90: s.vsizes[18], - vsize_100: s.vsizes[19], - vsize_125: s.vsizes[20], - vsize_150: s.vsizes[21], - vsize_175: s.vsizes[22], - vsize_200: s.vsizes[23], - vsize_250: s.vsizes[24], - vsize_300: s.vsizes[25], - vsize_350: s.vsizes[26], - vsize_400: s.vsizes[27], - vsize_500: s.vsizes[28], - vsize_600: s.vsizes[29], - vsize_700: s.vsizes[30], - vsize_800: s.vsizes[31], - vsize_900: s.vsizes[32], - vsize_1000: s.vsizes[33], - vsize_1200: s.vsizes[34], - vsize_1400: s.vsizes[35], - vsize_1600: s.vsizes[36], - vsize_1800: s.vsizes[37], - vsize_2000: s.vsizes[38], + vsize_0: completeVsizes[0], + vsize_1: completeVsizes[1], + vsize_2: completeVsizes[2], + vsize_3: completeVsizes[3], + vsize_4: completeVsizes[4], + vsize_5: completeVsizes[5], + vsize_6: completeVsizes[6], + vsize_8: completeVsizes[7], + vsize_10: completeVsizes[8], + vsize_12: completeVsizes[9], + vsize_15: completeVsizes[10], + vsize_20: completeVsizes[11], + vsize_30: completeVsizes[12], + vsize_40: completeVsizes[13], + vsize_50: completeVsizes[14], + vsize_60: completeVsizes[15], + vsize_70: completeVsizes[16], + vsize_80: completeVsizes[17], + vsize_90: completeVsizes[18], + vsize_100: completeVsizes[19], + vsize_125: completeVsizes[20], + vsize_150: completeVsizes[21], + vsize_175: completeVsizes[22], + vsize_200: completeVsizes[23], + vsize_250: completeVsizes[24], + vsize_300: completeVsizes[25], + vsize_350: completeVsizes[26], + vsize_400: completeVsizes[27], + vsize_500: completeVsizes[28], + vsize_600: completeVsizes[29], + vsize_700: completeVsizes[30], + vsize_800: completeVsizes[31], + vsize_900: completeVsizes[32], + vsize_1000: completeVsizes[33], + vsize_1200: completeVsizes[34], + vsize_1400: completeVsizes[35], + vsize_1600: completeVsizes[36], + vsize_1800: completeVsizes[37], + vsize_2000: completeVsizes[38], } }); }