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..fa13b60b9 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, @@ -459,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, @@ -468,44 +475,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: 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], } }); } 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 0fe519a01..85a4d35d8 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 = [ + "#A81524", "#D81B60", "#8E24AA", "#5E35B1", @@ -125,7 +128,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, 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) { 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);