statistics: class incoming transactions by fee rate

This commit is contained in:
natsoni 2024-09-07 17:49:21 +02:00
parent 07fd3d3409
commit ae9125d316
No known key found for this signature in database
GPG Key ID: C65917583181743B
5 changed files with 475 additions and 58 deletions

View File

@ -7,7 +7,7 @@ import cpfpRepository from '../repositories/CpfpRepository';
import { RowDataPacket } from 'mysql2'; import { RowDataPacket } from 'mysql2';
class DatabaseMigration { class DatabaseMigration {
private static currentVersion = 82; private static currentVersion = 83;
private queryTimeout = 3600_000; private queryTimeout = 3600_000;
private statisticsAddedIndexed = false; private statisticsAddedIndexed = false;
private uniqueLogs: string[] = []; private uniqueLogs: string[] = [];
@ -705,6 +705,11 @@ class DatabaseMigration {
await this.$fixBadV1AuditBlocks(); await this.$fixBadV1AuditBlocks();
await this.updateToSchemaVersion(82); await this.updateToSchemaVersion(82);
} }
if (databaseSchemaVersion < 83) {
await this.$addPerSecondVsizeToStatistics();
await this.updateToSchemaVersion(83);
}
} }
/** /**
@ -1341,6 +1346,47 @@ class DatabaseMigration {
} }
} }
} }
private async $addPerSecondVsizeToStatistics(): Promise<void> {
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_1` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_2` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_3` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_4` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_5` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_6` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_8` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_10` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_12` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_15` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_20` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_30` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_40` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_50` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_60` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_70` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_80` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_90` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_100` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_125` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_150` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_175` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_200` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_250` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_300` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_350` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_400` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_500` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_600` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_700` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_800` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_900` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_1000` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_1200` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_1400` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_1600` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_1800` int(11) NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `statistics` ADD `vsize_ps_2000` int(11) NOT NULL DEFAULT 0');
}
} }
export default new DatabaseMigration(); export default new DatabaseMigration();

View File

@ -12,6 +12,7 @@ import rbfCache from './rbf-cache';
import { Acceleration } from './services/acceleration'; import { Acceleration } from './services/acceleration';
import redisCache from './redis-cache'; import redisCache from './redis-cache';
import blocks from './blocks'; import blocks from './blocks';
import { logFees } from './statistics/statistics';
class Mempool { class Mempool {
private inSync: boolean = false; private inSync: boolean = false;
@ -34,6 +35,7 @@ class Mempool {
private vBytesPerSecondArray: VbytesPerSecond[] = []; private vBytesPerSecondArray: VbytesPerSecond[] = [];
private vBytesPerSecond: number = 0; private vBytesPerSecond: number = 0;
private vBytesPerSecondByFeeRate: { [feePerWU: number]: number } = {};
private mempoolProtection = 0; private mempoolProtection = 0;
private latestTransactions: any[] = []; private latestTransactions: any[] = [];
@ -193,6 +195,10 @@ class Mempool {
return this.vBytesPerSecond; return this.vBytesPerSecond;
} }
public getVBytesPerSecondByFeeRate(): { [feePerWU: number]: number } {
return this.vBytesPerSecondByFeeRate;
}
public getFirstSeenForTransactions(txIds: string[]): number[] { public getFirstSeenForTransactions(txIds: string[]): number[] {
const txTimes: number[] = []; const txTimes: number[] = [];
txIds.forEach((txId: string) => { txIds.forEach((txId: string) => {
@ -270,6 +276,7 @@ class Mempool {
this.vBytesPerSecondArray.push({ this.vBytesPerSecondArray.push({
unixTime: new Date().getTime(), unixTime: new Date().getTime(),
vSize: transaction.vsize, vSize: transaction.vsize,
effectiveFeePerVsize: transaction.effectiveFeePerVsize
}); });
} }
hasChange = true; hasChange = true;
@ -588,6 +595,21 @@ class Mempool {
this.vBytesPerSecond = Math.round( this.vBytesPerSecond = Math.round(
this.vBytesPerSecondArray.map((data) => data.vSize).reduce((a, b) => a + b) / config.STATISTICS.TX_PER_SECOND_SAMPLE_PERIOD this.vBytesPerSecondArray.map((data) => data.vSize).reduce((a, b) => a + b) / config.STATISTICS.TX_PER_SECOND_SAMPLE_PERIOD
); );
if (!Common.isLiquid()) {
this.vBytesPerSecondByFeeRate = {};
for (const tx of this.vBytesPerSecondArray) {
for (let i = 0; i < logFees.length; i++) {
if (tx.effectiveFeePerVsize < logFees[i + 1] || i === logFees.length - 1) {
this.vBytesPerSecondByFeeRate[logFees[i]] = (this.vBytesPerSecondByFeeRate[logFees[i]] || 0) + tx.vSize;
break;
}
}
}
for (const feeRate of Object.keys(this.vBytesPerSecondByFeeRate)) {
this.vBytesPerSecondByFeeRate[feeRate] = Math.round(this.vBytesPerSecondByFeeRate[feeRate] / config.STATISTICS.TX_PER_SECOND_SAMPLE_PERIOD);
}
}
} }
} }

View File

@ -53,7 +53,45 @@ class StatisticsApi {
vsize_1400, vsize_1400,
vsize_1600, vsize_1600,
vsize_1800, vsize_1800,
vsize_2000 vsize_2000,
vsize_ps_1,
vsize_ps_2,
vsize_ps_3,
vsize_ps_4,
vsize_ps_5,
vsize_ps_6,
vsize_ps_8,
vsize_ps_10,
vsize_ps_12,
vsize_ps_15,
vsize_ps_20,
vsize_ps_30,
vsize_ps_40,
vsize_ps_50,
vsize_ps_60,
vsize_ps_70,
vsize_ps_80,
vsize_ps_90,
vsize_ps_100,
vsize_ps_125,
vsize_ps_150,
vsize_ps_175,
vsize_ps_200,
vsize_ps_250,
vsize_ps_300,
vsize_ps_350,
vsize_ps_400,
vsize_ps_500,
vsize_ps_600,
vsize_ps_700,
vsize_ps_800,
vsize_ps_900,
vsize_ps_1000,
vsize_ps_1200,
vsize_ps_1400,
vsize_ps_1600,
vsize_ps_1800,
vsize_ps_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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)`;
@ -112,10 +150,48 @@ class StatisticsApi {
vsize_1400, vsize_1400,
vsize_1600, vsize_1600,
vsize_1800, vsize_1800,
vsize_2000 vsize_2000,
vsize_ps_1,
vsize_ps_2,
vsize_ps_3,
vsize_ps_4,
vsize_ps_5,
vsize_ps_6,
vsize_ps_8,
vsize_ps_10,
vsize_ps_12,
vsize_ps_15,
vsize_ps_20,
vsize_ps_30,
vsize_ps_40,
vsize_ps_50,
vsize_ps_60,
vsize_ps_70,
vsize_ps_80,
vsize_ps_90,
vsize_ps_100,
vsize_ps_125,
vsize_ps_150,
vsize_ps_175,
vsize_ps_200,
vsize_ps_250,
vsize_ps_300,
vsize_ps_350,
vsize_ps_400,
vsize_ps_500,
vsize_ps_600,
vsize_ps_700,
vsize_ps_800,
vsize_ps_900,
vsize_ps_1000,
vsize_ps_1200,
vsize_ps_1400,
vsize_ps_1600,
vsize_ps_1800,
vsize_ps_2000
) )
VALUES (${convertToDatetime ? `FROM_UNIXTIME(${statistics.added})` : statistics.added}, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, VALUES (${convertToDatetime ? `FROM_UNIXTIME(${statistics.added})` : statistics.added}, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`; ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;
const params: (string | number)[] = [ const params: (string | number)[] = [
statistics.unconfirmed_transactions, statistics.unconfirmed_transactions,
@ -163,6 +239,44 @@ class StatisticsApi {
statistics.vsize_1600, statistics.vsize_1600,
statistics.vsize_1800, statistics.vsize_1800,
statistics.vsize_2000, statistics.vsize_2000,
statistics.vsize_ps_1,
statistics.vsize_ps_2,
statistics.vsize_ps_3,
statistics.vsize_ps_4,
statistics.vsize_ps_5,
statistics.vsize_ps_6,
statistics.vsize_ps_8,
statistics.vsize_ps_10,
statistics.vsize_ps_12,
statistics.vsize_ps_15,
statistics.vsize_ps_20,
statistics.vsize_ps_30,
statistics.vsize_ps_40,
statistics.vsize_ps_50,
statistics.vsize_ps_60,
statistics.vsize_ps_70,
statistics.vsize_ps_80,
statistics.vsize_ps_90,
statistics.vsize_ps_100,
statistics.vsize_ps_125,
statistics.vsize_ps_150,
statistics.vsize_ps_175,
statistics.vsize_ps_200,
statistics.vsize_ps_250,
statistics.vsize_ps_300,
statistics.vsize_ps_350,
statistics.vsize_ps_400,
statistics.vsize_ps_500,
statistics.vsize_ps_600,
statistics.vsize_ps_700,
statistics.vsize_ps_800,
statistics.vsize_ps_900,
statistics.vsize_ps_1000,
statistics.vsize_ps_1200,
statistics.vsize_ps_1400,
statistics.vsize_ps_1600,
statistics.vsize_ps_1800,
statistics.vsize_ps_2000,
]; ];
const [result]: any = await DB.query(query, params); const [result]: any = await DB.query(query, params);
return result.insertId; return result.insertId;
@ -214,7 +328,45 @@ class StatisticsApi {
CAST(avg(vsize_1400) as DOUBLE) as vsize_1400, CAST(avg(vsize_1400) as DOUBLE) as vsize_1400,
CAST(avg(vsize_1600) as DOUBLE) as vsize_1600, CAST(avg(vsize_1600) as DOUBLE) as vsize_1600,
CAST(avg(vsize_1800) as DOUBLE) as vsize_1800, CAST(avg(vsize_1800) as DOUBLE) as vsize_1800,
CAST(avg(vsize_2000) as DOUBLE) as vsize_2000 \ CAST(avg(vsize_2000) as DOUBLE) as vsize_2000,
CAST(avg(vsize_ps_1) as DOUBLE) as vsize_ps_1,
CAST(avg(vsize_ps_2) as DOUBLE) as vsize_ps_2,
CAST(avg(vsize_ps_3) as DOUBLE) as vsize_ps_3,
CAST(avg(vsize_ps_4) as DOUBLE) as vsize_ps_4,
CAST(avg(vsize_ps_5) as DOUBLE) as vsize_ps_5,
CAST(avg(vsize_ps_6) as DOUBLE) as vsize_ps_6,
CAST(avg(vsize_ps_8) as DOUBLE) as vsize_ps_8,
CAST(avg(vsize_ps_10) as DOUBLE) as vsize_ps_10,
CAST(avg(vsize_ps_12) as DOUBLE) as vsize_ps_12,
CAST(avg(vsize_ps_15) as DOUBLE) as vsize_ps_15,
CAST(avg(vsize_ps_20) as DOUBLE) as vsize_ps_20,
CAST(avg(vsize_ps_30) as DOUBLE) as vsize_ps_30,
CAST(avg(vsize_ps_40) as DOUBLE) as vsize_ps_40,
CAST(avg(vsize_ps_50) as DOUBLE) as vsize_ps_50,
CAST(avg(vsize_ps_60) as DOUBLE) as vsize_ps_60,
CAST(avg(vsize_ps_70) as DOUBLE) as vsize_ps_70,
CAST(avg(vsize_ps_80) as DOUBLE) as vsize_ps_80,
CAST(avg(vsize_ps_90) as DOUBLE) as vsize_ps_90,
CAST(avg(vsize_ps_100) as DOUBLE) as vsize_ps_100,
CAST(avg(vsize_ps_125) as DOUBLE) as vsize_ps_125,
CAST(avg(vsize_ps_150) as DOUBLE) as vsize_ps_150,
CAST(avg(vsize_ps_175) as DOUBLE) as vsize_ps_175,
CAST(avg(vsize_ps_200) as DOUBLE) as vsize_ps_200,
CAST(avg(vsize_ps_250) as DOUBLE) as vsize_ps_250,
CAST(avg(vsize_ps_300) as DOUBLE) as vsize_ps_300,
CAST(avg(vsize_ps_350) as DOUBLE) as vsize_ps_350,
CAST(avg(vsize_ps_400) as DOUBLE) as vsize_ps_400,
CAST(avg(vsize_ps_500) as DOUBLE) as vsize_ps_500,
CAST(avg(vsize_ps_600) as DOUBLE) as vsize_ps_600,
CAST(avg(vsize_ps_700) as DOUBLE) as vsize_ps_700,
CAST(avg(vsize_ps_800) as DOUBLE) as vsize_ps_800,
CAST(avg(vsize_ps_900) as DOUBLE) as vsize_ps_900,
CAST(avg(vsize_ps_1000) as DOUBLE) as vsize_ps_1000,
CAST(avg(vsize_ps_1200) as DOUBLE) as vsize_ps_1200,
CAST(avg(vsize_ps_1400) as DOUBLE) as vsize_ps_1400,
CAST(avg(vsize_ps_1600) as DOUBLE) as vsize_ps_1600,
CAST(avg(vsize_ps_1800) as DOUBLE) as vsize_ps_1800,
CAST(avg(vsize_ps_2000) as DOUBLE) as vsize_ps_2000 \
FROM statistics \ FROM statistics \
${interval === 'all' ? '' : `WHERE added BETWEEN DATE_SUB(NOW(), INTERVAL ${interval}) AND NOW()`} \ ${interval === 'all' ? '' : `WHERE added BETWEEN DATE_SUB(NOW(), INTERVAL ${interval}) AND NOW()`} \
GROUP BY UNIX_TIMESTAMP(added) DIV ${div} \ GROUP BY UNIX_TIMESTAMP(added) DIV ${div} \
@ -264,7 +416,45 @@ class StatisticsApi {
vsize_1400, vsize_1400,
vsize_1600, vsize_1600,
vsize_1800, vsize_1800,
vsize_2000 \ vsize_2000,
vsize_ps_1,
vsize_ps_2,
vsize_ps_3,
vsize_ps_4,
vsize_ps_5,
vsize_ps_6,
vsize_ps_8,
vsize_ps_10,
vsize_ps_12,
vsize_ps_15,
vsize_ps_20,
vsize_ps_30,
vsize_ps_40,
vsize_ps_50,
vsize_ps_60,
vsize_ps_70,
vsize_ps_80,
vsize_ps_90,
vsize_ps_100,
vsize_ps_125,
vsize_ps_150,
vsize_ps_175,
vsize_ps_200,
vsize_ps_250,
vsize_ps_300,
vsize_ps_350,
vsize_ps_400,
vsize_ps_500,
vsize_ps_600,
vsize_ps_700,
vsize_ps_800,
vsize_ps_900,
vsize_ps_1000,
vsize_ps_1200,
vsize_ps_1400,
vsize_ps_1600,
vsize_ps_1800,
vsize_ps_2000 \
FROM statistics \ FROM statistics \
${interval === 'all' ? '' : `WHERE added BETWEEN DATE_SUB(NOW(), INTERVAL ${interval}) AND NOW()`} \ ${interval === 'all' ? '' : `WHERE added BETWEEN DATE_SUB(NOW(), INTERVAL ${interval}) AND NOW()`} \
GROUP BY UNIX_TIMESTAMP(added) DIV ${div} \ GROUP BY UNIX_TIMESTAMP(added) DIV ${div} \
@ -452,7 +642,47 @@ class StatisticsApi {
s.vsize_1600, s.vsize_1600,
s.vsize_1800, s.vsize_1800,
s.vsize_2000, s.vsize_2000,
] ],
vsizes_ps: [
s.vsize_ps_1,
s.vsize_ps_2,
s.vsize_ps_3,
s.vsize_ps_4,
s.vsize_ps_5,
s.vsize_ps_6,
s.vsize_ps_8,
s.vsize_ps_10,
s.vsize_ps_12,
s.vsize_ps_15,
s.vsize_ps_20,
s.vsize_ps_30,
s.vsize_ps_40,
s.vsize_ps_50,
s.vsize_ps_60,
s.vsize_ps_70,
s.vsize_ps_80,
s.vsize_ps_90,
s.vsize_ps_100,
s.vsize_ps_125,
s.vsize_ps_150,
s.vsize_ps_175,
s.vsize_ps_200,
s.vsize_ps_250,
s.vsize_ps_300,
s.vsize_ps_350,
s.vsize_ps_400,
s.vsize_ps_500,
s.vsize_ps_600,
s.vsize_ps_700,
s.vsize_ps_800,
s.vsize_ps_900,
s.vsize_ps_1000,
s.vsize_ps_1200,
s.vsize_ps_1400,
s.vsize_ps_1600,
s.vsize_ps_1800,
s.vsize_ps_2000,
],
}; };
}); });
} }
@ -506,6 +736,44 @@ class StatisticsApi {
vsize_1600: s.vsizes[35], vsize_1600: s.vsizes[35],
vsize_1800: s.vsizes[36], vsize_1800: s.vsizes[36],
vsize_2000: s.vsizes[37], vsize_2000: s.vsizes[37],
vsize_ps_1: s.vsizes_ps[0] || 0,
vsize_ps_2: s.vsizes_ps[1] || 0,
vsize_ps_3: s.vsizes_ps[2] || 0,
vsize_ps_4: s.vsizes_ps[3] || 0,
vsize_ps_5: s.vsizes_ps[4] || 0,
vsize_ps_6: s.vsizes_ps[5] || 0,
vsize_ps_8: s.vsizes_ps[6] || 0,
vsize_ps_10: s.vsizes_ps[7] || 0,
vsize_ps_12: s.vsizes_ps[8] || 0,
vsize_ps_15: s.vsizes_ps[9] || 0,
vsize_ps_20: s.vsizes_ps[10] || 0,
vsize_ps_30: s.vsizes_ps[11] || 0,
vsize_ps_40: s.vsizes_ps[12] || 0,
vsize_ps_50: s.vsizes_ps[13] || 0,
vsize_ps_60: s.vsizes_ps[14] || 0,
vsize_ps_70: s.vsizes_ps[15] || 0,
vsize_ps_80: s.vsizes_ps[16] || 0,
vsize_ps_90: s.vsizes_ps[17] || 0,
vsize_ps_100: s.vsizes_ps[18] || 0,
vsize_ps_125: s.vsizes_ps[19] || 0,
vsize_ps_150: s.vsizes_ps[20] || 0,
vsize_ps_175: s.vsizes_ps[21] || 0,
vsize_ps_200: s.vsizes_ps[22] || 0,
vsize_ps_250: s.vsizes_ps[23] || 0,
vsize_ps_300: s.vsizes_ps[24] || 0,
vsize_ps_350: s.vsizes_ps[25] || 0,
vsize_ps_400: s.vsizes_ps[26] || 0,
vsize_ps_500: s.vsizes_ps[27] || 0,
vsize_ps_600: s.vsizes_ps[28] || 0,
vsize_ps_700: s.vsizes_ps[29] || 0,
vsize_ps_800: s.vsizes_ps[30] || 0,
vsize_ps_900: s.vsizes_ps[31] || 0,
vsize_ps_1000: s.vsizes_ps[32] || 0,
vsize_ps_1200: s.vsizes_ps[33] || 0,
vsize_ps_1400: s.vsizes_ps[34] || 0,
vsize_ps_1600: s.vsizes_ps[35] || 0,
vsize_ps_1800: s.vsizes_ps[36] || 0,
vsize_ps_2000: s.vsizes_ps[37] || 0,
} }
}); });
} }

View File

@ -4,6 +4,9 @@ import { TransactionExtended, OptimizedStatistic } from '../../mempool.interface
import { Common } from '../common'; import { Common } from '../common';
import statisticsApi from './statistics-api'; import statisticsApi from './statistics-api';
export 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,
250, 300, 350, 400, 500, 600, 700, 800, 900, 1000, 1200, 1400, 1600, 1800, 2000];
class Statistics { class Statistics {
protected intervalTimer: NodeJS.Timer | undefined; protected intervalTimer: NodeJS.Timer | undefined;
protected lastRun: number = 0; protected lastRun: number = 0;
@ -42,6 +45,7 @@ class Statistics {
const currentMempool = memPool.getMempool(); const currentMempool = memPool.getMempool();
const txPerSecond = memPool.getTxPerSecond(); const txPerSecond = memPool.getTxPerSecond();
const vBytesPerSecond = memPool.getVBytesPerSecond(); const vBytesPerSecond = memPool.getVBytesPerSecond();
const vBytesPerSecondByFeeRate = memPool.getVBytesPerSecondByFeeRate();
logger.debug('Running statistics'); logger.debug('Running statistics');
@ -73,9 +77,6 @@ class Statistics {
const totalWeight = memPoolArray.map((tx) => tx.vsize).reduce((acc, curr) => acc + curr) * 4; 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 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,
250, 300, 350, 400, 500, 600, 700, 800, 900, 1000, 1200, 1400, 1600, 1800, 2000];
const weightVsizeFees: { [feePerWU: number]: number } = {}; const weightVsizeFees: { [feePerWU: number]: number } = {};
const lastItem = logFees.length - 1; const lastItem = logFees.length - 1;
@ -147,6 +148,44 @@ class Statistics {
vsize_1600: weightVsizeFees['1600'] || 0, vsize_1600: weightVsizeFees['1600'] || 0,
vsize_1800: weightVsizeFees['1800'] || 0, vsize_1800: weightVsizeFees['1800'] || 0,
vsize_2000: weightVsizeFees['2000'] || 0, vsize_2000: weightVsizeFees['2000'] || 0,
vsize_ps_1: vBytesPerSecondByFeeRate['1'] || 0,
vsize_ps_2: vBytesPerSecondByFeeRate['2'] || 0,
vsize_ps_3: vBytesPerSecondByFeeRate['3'] || 0,
vsize_ps_4: vBytesPerSecondByFeeRate['4'] || 0,
vsize_ps_5: vBytesPerSecondByFeeRate['5'] || 0,
vsize_ps_6: vBytesPerSecondByFeeRate['6'] || 0,
vsize_ps_8: vBytesPerSecondByFeeRate['8'] || 0,
vsize_ps_10: vBytesPerSecondByFeeRate['10'] || 0,
vsize_ps_12: vBytesPerSecondByFeeRate['12'] || 0,
vsize_ps_15: vBytesPerSecondByFeeRate['15'] || 0,
vsize_ps_20: vBytesPerSecondByFeeRate['20'] || 0,
vsize_ps_30: vBytesPerSecondByFeeRate['30'] || 0,
vsize_ps_40: vBytesPerSecondByFeeRate['40'] || 0,
vsize_ps_50: vBytesPerSecondByFeeRate['50'] || 0,
vsize_ps_60: vBytesPerSecondByFeeRate['60'] || 0,
vsize_ps_70: vBytesPerSecondByFeeRate['70'] || 0,
vsize_ps_80: vBytesPerSecondByFeeRate['80'] || 0,
vsize_ps_90: vBytesPerSecondByFeeRate['90'] || 0,
vsize_ps_100: vBytesPerSecondByFeeRate['100'] || 0,
vsize_ps_125: vBytesPerSecondByFeeRate['125'] || 0,
vsize_ps_150: vBytesPerSecondByFeeRate['150'] || 0,
vsize_ps_175: vBytesPerSecondByFeeRate['175'] || 0,
vsize_ps_200: vBytesPerSecondByFeeRate['200'] || 0,
vsize_ps_250: vBytesPerSecondByFeeRate['250'] || 0,
vsize_ps_300: vBytesPerSecondByFeeRate['300'] || 0,
vsize_ps_350: vBytesPerSecondByFeeRate['350'] || 0,
vsize_ps_400: vBytesPerSecondByFeeRate['400'] || 0,
vsize_ps_500: vBytesPerSecondByFeeRate['500'] || 0,
vsize_ps_600: vBytesPerSecondByFeeRate['600'] || 0,
vsize_ps_700: vBytesPerSecondByFeeRate['700'] || 0,
vsize_ps_800: vBytesPerSecondByFeeRate['800'] || 0,
vsize_ps_900: vBytesPerSecondByFeeRate['900'] || 0,
vsize_ps_1000: vBytesPerSecondByFeeRate['1000'] || 0,
vsize_ps_1200: vBytesPerSecondByFeeRate['1200'] || 0,
vsize_ps_1400: vBytesPerSecondByFeeRate['1400'] || 0,
vsize_ps_1600: vBytesPerSecondByFeeRate['1600'] || 0,
vsize_ps_1800: vBytesPerSecondByFeeRate['1800'] || 0,
vsize_ps_2000: vBytesPerSecondByFeeRate['2000'] || 0,
}); });
if (this.newStatisticsEntryCallback && insertId) { if (this.newStatisticsEntryCallback && insertId) {

View File

@ -439,6 +439,46 @@ export interface Statistic {
vsize_1600: number; vsize_1600: number;
vsize_1800: number; vsize_1800: number;
vsize_2000: number; vsize_2000: number;
vsize_ps_1: number;
vsize_ps_2: number;
vsize_ps_3: number;
vsize_ps_4: number;
vsize_ps_5: number;
vsize_ps_6: number;
vsize_ps_8: number;
vsize_ps_10: number;
vsize_ps_12: number;
vsize_ps_15: number;
vsize_ps_20: number;
vsize_ps_30: number;
vsize_ps_40: number;
vsize_ps_50: number;
vsize_ps_60: number;
vsize_ps_70: number;
vsize_ps_80: number;
vsize_ps_90: number;
vsize_ps_100: number;
vsize_ps_125: number;
vsize_ps_150: number;
vsize_ps_175: number;
vsize_ps_200: number;
vsize_ps_250: number;
vsize_ps_300: number;
vsize_ps_350: number;
vsize_ps_400: number;
vsize_ps_500: number;
vsize_ps_600: number;
vsize_ps_700: number;
vsize_ps_800: number;
vsize_ps_900: number;
vsize_ps_1000: number;
vsize_ps_1200: number;
vsize_ps_1400: number;
vsize_ps_1600: number;
vsize_ps_1800: number;
vsize_ps_2000: number;
} }
export interface OptimizedStatistic { export interface OptimizedStatistic {
@ -449,6 +489,7 @@ export interface OptimizedStatistic {
mempool_byte_weight: number; mempool_byte_weight: number;
min_fee: number; min_fee: number;
vsizes: number[]; vsizes: number[];
vsizes_ps: number[];
} }
export interface TxTrackingInfo { export interface TxTrackingInfo {
@ -481,6 +522,7 @@ export interface WebsocketResponse {
export interface VbytesPerSecond { export interface VbytesPerSecond {
unixTime: number; unixTime: number;
vSize: number; vSize: number;
effectiveFeePerVsize: number;
} }
export interface RequiredSpec { [name: string]: RequiredParams; } export interface RequiredSpec { [name: string]: RequiredParams; }