2022-07-11 19:15:28 +02:00
import DB from '../../database' ;
import logger from '../../logger' ;
import { Statistic , OptimizedStatistic } from '../../mempool.interfaces' ;
2019-07-21 17:59:47 +03:00
2022-07-11 19:15:28 +02:00
class StatisticsApi {
2021-01-30 19:20:52 +07:00
protected queryTimeout = 120000 ;
2019-07-26 12:48:32 +03:00
2022-07-11 19:15:28 +02:00
public async $createZeroedStatistic ( ) : Promise < number | undefined > {
2022-01-16 16:20:45 +09:00
try {
const query = ` INSERT INTO statistics(
added ,
unconfirmed_transactions ,
tx_per_second ,
vbytes_per_second ,
mempool_byte_weight ,
fee_data ,
total_fee ,
2023-08-15 20:54:03 +09:00
min_fee ,
2022-01-16 16:20:45 +09:00
vsize_1 ,
vsize_2 ,
vsize_3 ,
vsize_4 ,
vsize_5 ,
vsize_6 ,
vsize_8 ,
vsize_10 ,
vsize_12 ,
vsize_15 ,
vsize_20 ,
vsize_30 ,
vsize_40 ,
vsize_50 ,
vsize_60 ,
vsize_70 ,
vsize_80 ,
vsize_90 ,
vsize_100 ,
vsize_125 ,
vsize_150 ,
vsize_175 ,
vsize_200 ,
vsize_250 ,
vsize_300 ,
vsize_350 ,
vsize_400 ,
vsize_500 ,
vsize_600 ,
vsize_700 ,
vsize_800 ,
vsize_900 ,
vsize_1000 ,
vsize_1200 ,
vsize_1400 ,
vsize_1600 ,
vsize_1800 ,
vsize_2000
)
2023-08-15 20:54:03 +09:00
VALUES ( NOW ( ) , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
2022-01-16 16:20:45 +09:00
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 ) ` ;
2022-04-12 15:15:57 +09:00
const [ result ] : any = await DB . query ( query ) ;
2022-01-16 16:20:45 +09:00
return result . insertId ;
} catch ( e ) {
logger . err ( '$create() error' + ( e instanceof Error ? e.message : e ) ) ;
}
}
2022-07-11 19:15:28 +02:00
public async $create ( statistics : Statistic ) : Promise < number | undefined > {
2019-07-21 17:59:47 +03:00
try {
const query = ` INSERT INTO statistics(
added ,
unconfirmed_transactions ,
tx_per_second ,
vbytes_per_second ,
mempool_byte_weight ,
fee_data ,
total_fee ,
2023-08-15 20:54:03 +09:00
min_fee ,
2019-07-21 17:59:47 +03:00
vsize_1 ,
vsize_2 ,
vsize_3 ,
vsize_4 ,
vsize_5 ,
vsize_6 ,
vsize_8 ,
vsize_10 ,
vsize_12 ,
vsize_15 ,
vsize_20 ,
vsize_30 ,
vsize_40 ,
vsize_50 ,
vsize_60 ,
vsize_70 ,
vsize_80 ,
vsize_90 ,
vsize_100 ,
vsize_125 ,
vsize_150 ,
vsize_175 ,
vsize_200 ,
vsize_250 ,
vsize_300 ,
vsize_350 ,
vsize_400 ,
vsize_500 ,
vsize_600 ,
vsize_700 ,
vsize_800 ,
vsize_900 ,
vsize_1000 ,
vsize_1200 ,
vsize_1400 ,
vsize_1600 ,
vsize_1800 ,
vsize_2000
)
2023-08-15 20:54:03 +09:00
VALUES ( $ { statistics . added } , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? ,
2019-07-21 17:59:47 +03:00
? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? ) ` ;
const params : ( string | number ) [ ] = [
statistics . unconfirmed_transactions ,
statistics . tx_per_second ,
statistics . vbytes_per_second ,
statistics . mempool_byte_weight ,
statistics . fee_data ,
statistics . total_fee ,
2023-08-15 20:54:03 +09:00
statistics . min_fee ,
2019-07-21 17:59:47 +03:00
statistics . vsize_1 ,
statistics . vsize_2 ,
statistics . vsize_3 ,
statistics . vsize_4 ,
statistics . vsize_5 ,
statistics . vsize_6 ,
statistics . vsize_8 ,
statistics . vsize_10 ,
statistics . vsize_12 ,
statistics . vsize_15 ,
statistics . vsize_20 ,
statistics . vsize_30 ,
statistics . vsize_40 ,
statistics . vsize_50 ,
statistics . vsize_60 ,
statistics . vsize_70 ,
statistics . vsize_80 ,
statistics . vsize_90 ,
statistics . vsize_100 ,
statistics . vsize_125 ,
statistics . vsize_150 ,
statistics . vsize_175 ,
statistics . vsize_200 ,
statistics . vsize_250 ,
statistics . vsize_300 ,
statistics . vsize_350 ,
statistics . vsize_400 ,
statistics . vsize_500 ,
statistics . vsize_600 ,
statistics . vsize_700 ,
statistics . vsize_800 ,
statistics . vsize_900 ,
statistics . vsize_1000 ,
statistics . vsize_1200 ,
statistics . vsize_1400 ,
statistics . vsize_1600 ,
statistics . vsize_1800 ,
statistics . vsize_2000 ,
] ;
2022-04-12 15:15:57 +09:00
const [ result ] : any = await DB . query ( query , params ) ;
2019-07-26 12:48:32 +03:00
return result . insertId ;
2019-07-21 17:59:47 +03:00
} catch ( e ) {
2021-08-31 15:09:33 +03:00
logger . err ( '$create() error' + ( e instanceof Error ? e.message : e ) ) ;
2019-07-21 17:59:47 +03:00
}
}
2021-12-11 19:15:20 +09:00
private getQueryForDaysAvg ( div : number , interval : string ) {
2022-01-14 19:21:54 +09:00
return ` SELECT
UNIX_TIMESTAMP ( added ) as added ,
2023-09-06 08:19:41 +09:00
CAST ( avg ( unconfirmed_transactions ) as DOUBLE ) as unconfirmed_transactions ,
2022-01-12 14:51:16 +09:00
CAST ( avg ( vbytes_per_second ) as DOUBLE ) as vbytes_per_second ,
2023-08-15 20:54:03 +09:00
CAST ( avg ( min_fee ) as DOUBLE ) as min_fee ,
2022-01-12 14:51:16 +09:00
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 ,
CAST ( avg ( vsize_4 ) as DOUBLE ) as vsize_4 ,
CAST ( avg ( vsize_5 ) as DOUBLE ) as vsize_5 ,
CAST ( avg ( vsize_6 ) as DOUBLE ) as vsize_6 ,
CAST ( avg ( vsize_8 ) as DOUBLE ) as vsize_8 ,
CAST ( avg ( vsize_10 ) as DOUBLE ) as vsize_10 ,
CAST ( avg ( vsize_12 ) as DOUBLE ) as vsize_12 ,
CAST ( avg ( vsize_15 ) as DOUBLE ) as vsize_15 ,
CAST ( avg ( vsize_20 ) as DOUBLE ) as vsize_20 ,
CAST ( avg ( vsize_30 ) as DOUBLE ) as vsize_30 ,
CAST ( avg ( vsize_40 ) as DOUBLE ) as vsize_40 ,
CAST ( avg ( vsize_50 ) as DOUBLE ) as vsize_50 ,
CAST ( avg ( vsize_60 ) as DOUBLE ) as vsize_60 ,
CAST ( avg ( vsize_70 ) as DOUBLE ) as vsize_70 ,
CAST ( avg ( vsize_80 ) as DOUBLE ) as vsize_80 ,
CAST ( avg ( vsize_90 ) as DOUBLE ) as vsize_90 ,
CAST ( avg ( vsize_100 ) as DOUBLE ) as vsize_100 ,
CAST ( avg ( vsize_125 ) as DOUBLE ) as vsize_125 ,
CAST ( avg ( vsize_150 ) as DOUBLE ) as vsize_150 ,
CAST ( avg ( vsize_175 ) as DOUBLE ) as vsize_175 ,
CAST ( avg ( vsize_200 ) as DOUBLE ) as vsize_200 ,
CAST ( avg ( vsize_250 ) as DOUBLE ) as vsize_250 ,
CAST ( avg ( vsize_300 ) as DOUBLE ) as vsize_300 ,
CAST ( avg ( vsize_350 ) as DOUBLE ) as vsize_350 ,
CAST ( avg ( vsize_400 ) as DOUBLE ) as vsize_400 ,
CAST ( avg ( vsize_500 ) as DOUBLE ) as vsize_500 ,
CAST ( avg ( vsize_600 ) as DOUBLE ) as vsize_600 ,
CAST ( avg ( vsize_700 ) as DOUBLE ) as vsize_700 ,
CAST ( avg ( vsize_800 ) as DOUBLE ) as vsize_800 ,
CAST ( avg ( vsize_900 ) as DOUBLE ) as vsize_900 ,
CAST ( avg ( vsize_1000 ) as DOUBLE ) as vsize_1000 ,
CAST ( avg ( vsize_1200 ) as DOUBLE ) as vsize_1200 ,
CAST ( avg ( vsize_1400 ) as DOUBLE ) as vsize_1400 ,
CAST ( avg ( vsize_1600 ) as DOUBLE ) as vsize_1600 ,
CAST ( avg ( vsize_1800 ) as DOUBLE ) as vsize_1800 ,
CAST ( avg ( vsize_2000 ) as DOUBLE ) as vsize_2000 \
2021-12-11 19:15:20 +09:00
FROM statistics \
2023-06-21 18:14:32 +02:00
$ { interval === 'all' ? '' : ` WHERE added BETWEEN DATE_SUB(NOW(), INTERVAL ${ interval } ) AND NOW() ` } \
2021-12-11 19:15:20 +09:00
GROUP BY UNIX_TIMESTAMP ( added ) DIV $ { div } \
2022-01-14 18:13:34 +09:00
ORDER BY statistics . added DESC ; ` ;
2021-12-11 19:15:20 +09:00
}
2021-12-11 15:26:02 +09:00
private getQueryForDays ( div : number , interval : string ) {
2022-01-14 19:21:54 +09:00
return ` SELECT
UNIX_TIMESTAMP ( added ) as added ,
2023-09-18 21:07:24 +00:00
CAST ( avg ( unconfirmed_transactions ) as DOUBLE ) as unconfirmed_transactions ,
2022-01-12 14:51:16 +09:00
CAST ( avg ( vbytes_per_second ) as DOUBLE ) as vbytes_per_second ,
2023-08-15 20:54:03 +09:00
CAST ( avg ( min_fee ) as DOUBLE ) as min_fee ,
2020-10-26 01:00:21 +07:00
vsize_1 ,
vsize_2 ,
vsize_3 ,
vsize_4 ,
vsize_5 ,
vsize_6 ,
vsize_8 ,
vsize_10 ,
vsize_12 ,
vsize_15 ,
vsize_20 ,
vsize_30 ,
vsize_40 ,
vsize_50 ,
vsize_60 ,
vsize_70 ,
vsize_80 ,
vsize_90 ,
vsize_100 ,
vsize_125 ,
vsize_150 ,
vsize_175 ,
vsize_200 ,
vsize_250 ,
vsize_300 ,
vsize_350 ,
vsize_400 ,
vsize_500 ,
vsize_600 ,
vsize_700 ,
vsize_800 ,
vsize_900 ,
vsize_1000 ,
vsize_1200 ,
vsize_1400 ,
vsize_1600 ,
vsize_1800 ,
2021-12-11 15:26:02 +09:00
vsize_2000 \
FROM statistics \
2023-06-21 18:14:32 +02:00
$ { interval === 'all' ? '' : ` WHERE added BETWEEN DATE_SUB(NOW(), INTERVAL ${ interval } ) AND NOW() ` } \
2021-12-11 15:26:02 +09:00
GROUP BY UNIX_TIMESTAMP ( added ) DIV $ { div } \
2022-01-14 18:13:34 +09:00
ORDER BY statistics . added DESC ; ` ;
2019-07-21 17:59:47 +03:00
}
2022-07-11 19:15:28 +02:00
public async $get ( id : number ) : Promise < OptimizedStatistic | undefined > {
2019-07-26 12:48:32 +03:00
try {
2021-12-11 00:04:20 +09:00
const query = ` SELECT *, UNIX_TIMESTAMP(added) as added FROM statistics WHERE id = ? ` ;
2022-04-12 15:15:57 +09:00
const [ rows ] = await DB . query ( query , [ id ] ) ;
2020-02-17 00:26:57 +07:00
if ( rows [ 0 ] ) {
return this . mapStatisticToOptimizedStatistic ( [ rows [ 0 ] ] ) [ 0 ] ;
}
2019-07-26 12:48:32 +03:00
} catch ( e ) {
2021-08-31 15:09:33 +03:00
logger . err ( '$list2H() error' + ( e instanceof Error ? e.message : e ) ) ;
2019-07-26 12:48:32 +03:00
}
}
2020-02-17 00:26:57 +07:00
public async $list2H ( ) : Promise < OptimizedStatistic [ ] > {
2019-07-21 17:59:47 +03:00
try {
2024-02-12 00:53:53 +00:00
const query = ` SELECT *, UNIX_TIMESTAMP(added) as added FROM statistics WHERE added BETWEEN DATE_SUB(NOW(), INTERVAL 2 HOUR) AND NOW() ORDER BY statistics.added DESC ` ;
2022-04-12 15:15:57 +09:00
const [ rows ] = await DB . query ( { sql : query , timeout : this.queryTimeout } ) ;
return this . mapStatisticToOptimizedStatistic ( rows as Statistic [ ] ) ;
2019-07-21 17:59:47 +03:00
} catch ( e ) {
2021-08-31 15:09:33 +03:00
logger . err ( '$list2H() error' + ( e instanceof Error ? e.message : e ) ) ;
2019-07-21 17:59:47 +03:00
return [ ] ;
}
}
2020-02-17 00:26:57 +07:00
public async $list24H ( ) : Promise < OptimizedStatistic [ ] > {
2019-07-21 17:59:47 +03:00
try {
2024-02-12 00:53:53 +00:00
const query = ` SELECT *, UNIX_TIMESTAMP(added) as added FROM statistics WHERE added BETWEEN DATE_SUB(NOW(), INTERVAL 24 HOUR) AND NOW() ORDER BY statistics.added DESC ` ;
2022-04-12 15:15:57 +09:00
const [ rows ] = await DB . query ( { sql : query , timeout : this.queryTimeout } ) ;
return this . mapStatisticToOptimizedStatistic ( rows as Statistic [ ] ) ;
2019-07-21 17:59:47 +03:00
} catch ( e ) {
2021-08-31 15:09:33 +03:00
logger . err ( '$list24h() error' + ( e instanceof Error ? e.message : e ) ) ;
2019-07-21 17:59:47 +03:00
return [ ] ;
}
}
2020-02-17 00:26:57 +07:00
public async $list1W ( ) : Promise < OptimizedStatistic [ ] > {
2019-07-21 17:59:47 +03:00
try {
2021-12-26 17:51:38 +09:00
const query = this . getQueryForDaysAvg ( 300 , '1 WEEK' ) ; // 5m interval
2022-04-12 15:15:57 +09:00
const [ rows ] = await DB . query ( { sql : query , timeout : this.queryTimeout } ) ;
return this . mapStatisticToOptimizedStatistic ( rows as Statistic [ ] ) ;
2019-07-21 17:59:47 +03:00
} catch ( e ) {
2021-08-31 15:09:33 +03:00
logger . err ( '$list1W() error' + ( e instanceof Error ? e.message : e ) ) ;
2019-07-21 17:59:47 +03:00
return [ ] ;
}
}
2020-02-17 00:26:57 +07:00
public async $list1M ( ) : Promise < OptimizedStatistic [ ] > {
2019-07-21 17:59:47 +03:00
try {
2021-12-26 17:51:38 +09:00
const query = this . getQueryForDaysAvg ( 1800 , '1 MONTH' ) ; // 30m interval
2022-04-12 15:15:57 +09:00
const [ rows ] = await DB . query ( { sql : query , timeout : this.queryTimeout } ) ;
return this . mapStatisticToOptimizedStatistic ( rows as Statistic [ ] ) ;
2019-07-21 17:59:47 +03:00
} catch ( e ) {
2021-08-31 15:09:33 +03:00
logger . err ( '$list1M() error' + ( e instanceof Error ? e.message : e ) ) ;
2019-07-21 17:59:47 +03:00
return [ ] ;
}
}
2020-02-17 00:26:57 +07:00
public async $list3M ( ) : Promise < OptimizedStatistic [ ] > {
2019-07-21 17:59:47 +03:00
try {
2021-12-26 17:51:38 +09:00
const query = this . getQueryForDaysAvg ( 7200 , '3 MONTH' ) ; // 2h interval
2022-04-12 15:15:57 +09:00
const [ rows ] = await DB . query ( { sql : query , timeout : this.queryTimeout } ) ;
return this . mapStatisticToOptimizedStatistic ( rows as Statistic [ ] ) ;
2019-07-21 17:59:47 +03:00
} catch ( e ) {
2021-08-31 15:09:33 +03:00
logger . err ( '$list3M() error' + ( e instanceof Error ? e.message : e ) ) ;
2019-07-21 17:59:47 +03:00
return [ ] ;
}
}
2020-02-17 00:26:57 +07:00
public async $list6M ( ) : Promise < OptimizedStatistic [ ] > {
2019-07-21 17:59:47 +03:00
try {
2022-04-12 15:15:57 +09:00
const query = this . getQueryForDaysAvg ( 10800 , '6 MONTH' ) ; // 3h interval
const [ rows ] = await DB . query ( { sql : query , timeout : this.queryTimeout } ) ;
return this . mapStatisticToOptimizedStatistic ( rows as Statistic [ ] ) ;
2019-07-21 17:59:47 +03:00
} catch ( e ) {
2021-08-31 15:09:33 +03:00
logger . err ( '$list6M() error' + ( e instanceof Error ? e.message : e ) ) ;
2019-07-21 17:59:47 +03:00
return [ ] ;
}
}
2020-02-17 00:26:57 +07:00
public async $list1Y ( ) : Promise < OptimizedStatistic [ ] > {
try {
2021-12-26 17:51:38 +09:00
const query = this . getQueryForDays ( 28800 , '1 YEAR' ) ; // 8h interval
2022-04-12 15:15:57 +09:00
const [ rows ] = await DB . query ( { sql : query , timeout : this.queryTimeout } ) ;
return this . mapStatisticToOptimizedStatistic ( rows as Statistic [ ] ) ;
2020-02-17 00:26:57 +07:00
} catch ( e ) {
2021-11-01 22:06:10 -03:00
logger . err ( '$list1Y() error' + ( e instanceof Error ? e.message : e ) ) ;
return [ ] ;
}
}
public async $list2Y ( ) : Promise < OptimizedStatistic [ ] > {
try {
2022-04-12 15:15:57 +09:00
const query = this . getQueryForDays ( 28800 , '2 YEAR' ) ; // 8h interval
const [ rows ] = await DB . query ( { sql : query , timeout : this.queryTimeout } ) ;
return this . mapStatisticToOptimizedStatistic ( rows as Statistic [ ] ) ;
2021-11-01 22:06:10 -03:00
} catch ( e ) {
logger . err ( '$list2Y() error' + ( e instanceof Error ? e.message : e ) ) ;
2020-02-17 00:26:57 +07:00
return [ ] ;
}
}
2021-11-01 22:06:10 -03:00
public async $list3Y ( ) : Promise < OptimizedStatistic [ ] > {
try {
2022-04-12 15:15:57 +09:00
const query = this . getQueryForDays ( 43200 , '3 YEAR' ) ; // 12h interval
const [ rows ] = await DB . query ( { sql : query , timeout : this.queryTimeout } ) ;
return this . mapStatisticToOptimizedStatistic ( rows as Statistic [ ] ) ;
2021-11-01 22:06:10 -03:00
} catch ( e ) {
logger . err ( '$list3Y() error' + ( e instanceof Error ? e.message : e ) ) ;
return [ ] ;
}
}
2023-03-04 18:48:16 +09:00
public async $list4Y ( ) : Promise < OptimizedStatistic [ ] > {
try {
const query = this . getQueryForDays ( 43200 , '4 YEAR' ) ; // 12h interval
const [ rows ] = await DB . query ( { sql : query , timeout : this.queryTimeout } ) ;
return this . mapStatisticToOptimizedStatistic ( rows as Statistic [ ] ) ;
} catch ( e ) {
logger . err ( '$list4Y() error' + ( e instanceof Error ? e.message : e ) ) ;
return [ ] ;
}
}
2023-06-19 12:46:10 -04:00
public async $listAll ( ) : Promise < OptimizedStatistic [ ] > {
try {
2023-06-21 18:14:32 +02:00
const query = this . getQueryForDays ( 43200 , 'all' ) ; // 12h interval
2023-06-19 12:46:10 -04:00
const [ rows ] = await DB . query ( { sql : query , timeout : this.queryTimeout } ) ;
return this . mapStatisticToOptimizedStatistic ( rows as Statistic [ ] ) ;
} catch ( e ) {
logger . err ( '$listAll() error' + ( e instanceof Error ? e.message : e ) ) ;
return [ ] ;
}
}
2020-02-17 00:26:57 +07:00
private mapStatisticToOptimizedStatistic ( statistic : Statistic [ ] ) : OptimizedStatistic [ ] {
return statistic . map ( ( s ) = > {
return {
added : s.added ,
2023-09-06 08:19:41 +09:00
count : s.unconfirmed_transactions ,
2020-02-17 00:26:57 +07:00
vbytes_per_second : s.vbytes_per_second ,
mempool_byte_weight : s.mempool_byte_weight ,
total_fee : s.total_fee ,
2023-08-15 20:54:03 +09:00
min_fee : s.min_fee ,
2020-02-17 00:26:57 +07:00
vsizes : [
s . vsize_1 ,
s . vsize_2 ,
s . vsize_3 ,
s . vsize_4 ,
s . vsize_5 ,
s . vsize_6 ,
s . vsize_8 ,
s . vsize_10 ,
s . vsize_12 ,
s . vsize_15 ,
s . vsize_20 ,
s . vsize_30 ,
s . vsize_40 ,
s . vsize_50 ,
s . vsize_60 ,
s . vsize_70 ,
s . vsize_80 ,
s . vsize_90 ,
s . vsize_100 ,
s . vsize_125 ,
s . vsize_150 ,
s . vsize_175 ,
s . vsize_200 ,
s . vsize_250 ,
s . vsize_300 ,
s . vsize_350 ,
s . vsize_400 ,
s . vsize_500 ,
s . vsize_600 ,
s . vsize_700 ,
s . vsize_800 ,
s . vsize_900 ,
s . vsize_1000 ,
s . vsize_1200 ,
s . vsize_1400 ,
s . vsize_1600 ,
s . vsize_1800 ,
s . vsize_2000 ,
]
} ;
} ) ;
}
2019-07-21 17:59:47 +03:00
}
2022-07-11 19:15:28 +02:00
export default new StatisticsApi ( ) ;