Merge branch 'master' into mononaut/sliding-difficulty
This commit is contained in:
@@ -398,39 +398,24 @@ class ElementsParser {
|
||||
return rows;
|
||||
}
|
||||
|
||||
// Get all of the federation addresses one month ago, most balances first
|
||||
public async $getFederationAddressesOneMonthAgo(): Promise<any> {
|
||||
const query = `
|
||||
SELECT COUNT(*) AS addresses_count_one_month FROM (
|
||||
SELECT bitcoinaddress, SUM(amount) AS balance
|
||||
FROM federation_txos
|
||||
WHERE
|
||||
(blocktime < UNIX_TIMESTAMP(TIMESTAMPADD(DAY, -30, CURRENT_TIMESTAMP())))
|
||||
AND
|
||||
((unspent = 1) OR (unspent = 0 AND lasttimeupdate > UNIX_TIMESTAMP(TIMESTAMPADD(DAY, -30, CURRENT_TIMESTAMP()))))
|
||||
GROUP BY bitcoinaddress
|
||||
) AS result;`;
|
||||
// Get the total number of federation addresses
|
||||
public async $getFederationAddressesNumber(): Promise<any> {
|
||||
const query = `SELECT COUNT(DISTINCT bitcoinaddress) AS address_count FROM federation_txos WHERE unspent = 1;`;
|
||||
const [rows] = await DB.query(query);
|
||||
return rows[0];
|
||||
}
|
||||
|
||||
// Get all of the UTXOs held by the federation one month ago, most recent first
|
||||
public async $getFederationUtxosOneMonthAgo(): Promise<any> {
|
||||
const query = `
|
||||
SELECT COUNT(*) AS utxos_count_one_month FROM federation_txos
|
||||
WHERE
|
||||
(blocktime < UNIX_TIMESTAMP(TIMESTAMPADD(DAY, -30, CURRENT_TIMESTAMP())))
|
||||
AND
|
||||
((unspent = 1) OR (unspent = 0 AND lasttimeupdate > UNIX_TIMESTAMP(TIMESTAMPADD(DAY, -30, CURRENT_TIMESTAMP()))))
|
||||
ORDER BY blocktime DESC;`;
|
||||
// Get the total number of federation utxos
|
||||
public async $getFederationUtxosNumber(): Promise<any> {
|
||||
const query = `SELECT COUNT(*) AS utxo_count FROM federation_txos WHERE unspent = 1;`;
|
||||
const [rows] = await DB.query(query);
|
||||
return rows[0];
|
||||
}
|
||||
|
||||
// Get recent pegouts from the federation (3 months old)
|
||||
public async $getRecentPegouts(): Promise<any> {
|
||||
const query = `SELECT txid, txindex, amount, bitcoinaddress, bitcointxid, bitcoinindex, datetime AS blocktime FROM elements_pegs WHERE amount < 0 AND datetime > UNIX_TIMESTAMP(TIMESTAMPADD(DAY, -90, CURRENT_TIMESTAMP())) ORDER BY blocktime;`;
|
||||
const [rows] = await DB.query(query);
|
||||
// Get recent pegs in / out
|
||||
public async $getPegsList(count: number = 0): Promise<any> {
|
||||
const query = `SELECT txid, txindex, amount, bitcoinaddress, bitcointxid, bitcoinindex, datetime AS blocktime FROM elements_pegs ORDER BY block DESC LIMIT 15 OFFSET ?;`;
|
||||
const [rows] = await DB.query(query, [count]);
|
||||
return rows;
|
||||
}
|
||||
|
||||
@@ -443,6 +428,12 @@ class ElementsParser {
|
||||
pegOutQuery[0][0]
|
||||
];
|
||||
}
|
||||
|
||||
// Get the total pegs number
|
||||
public async $getPegsCount(): Promise<any> {
|
||||
const [rows] = await DB.query(`SELECT COUNT(*) AS pegs_count FROM elements_pegs;`);
|
||||
return rows[0];
|
||||
}
|
||||
}
|
||||
|
||||
export default new ElementsParser();
|
||||
|
||||
@@ -17,14 +17,15 @@ class LiquidRoutes {
|
||||
app
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'liquid/pegs', this.$getElementsPegs)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'liquid/pegs/month', this.$getElementsPegsByMonth)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'liquid/pegs/list/:count', this.$getPegsList)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'liquid/pegs/volume', this.$getPegsVolumeDaily)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'liquid/pegs/count', this.$getPegsCount)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'liquid/reserves', this.$getFederationReserves)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'liquid/reserves/month', this.$getFederationReservesByMonth)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'liquid/pegouts', this.$getPegOuts)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'liquid/reserves/addresses', this.$getFederationAddresses)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'liquid/reserves/addresses/previous-month', this.$getFederationAddressesOneMonthAgo)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'liquid/reserves/addresses/total', this.$getFederationAddressesNumber)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'liquid/reserves/utxos', this.$getFederationUtxos)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'liquid/reserves/utxos/previous-month', this.$getFederationUtxosOneMonthAgo)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'liquid/reserves/utxos/total', this.$getFederationUtxosNumber)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'liquid/reserves/status', this.$getFederationAuditStatus)
|
||||
;
|
||||
}
|
||||
@@ -142,12 +143,12 @@ class LiquidRoutes {
|
||||
}
|
||||
}
|
||||
|
||||
private async $getFederationAddressesOneMonthAgo(req: Request, res: Response) {
|
||||
private async $getFederationAddressesNumber(req: Request, res: Response) {
|
||||
try {
|
||||
const federationAddresses = await elementsParser.$getFederationAddressesOneMonthAgo();
|
||||
const federationAddresses = await elementsParser.$getFederationAddressesNumber();
|
||||
res.header('Pragma', 'public');
|
||||
res.header('Cache-control', 'public');
|
||||
res.setHeader('Expires', new Date(Date.now() + 1000 * 60 * 60 * 24).toUTCString());
|
||||
res.setHeader('Expires', new Date(Date.now() + 1000 * 30).toUTCString());
|
||||
res.json(federationAddresses);
|
||||
} catch (e) {
|
||||
res.status(500).send(e instanceof Error ? e.message : e);
|
||||
@@ -166,25 +167,25 @@ class LiquidRoutes {
|
||||
}
|
||||
}
|
||||
|
||||
private async $getFederationUtxosOneMonthAgo(req: Request, res: Response) {
|
||||
private async $getFederationUtxosNumber(req: Request, res: Response) {
|
||||
try {
|
||||
const federationUtxos = await elementsParser.$getFederationUtxosOneMonthAgo();
|
||||
const federationUtxos = await elementsParser.$getFederationUtxosNumber();
|
||||
res.header('Pragma', 'public');
|
||||
res.header('Cache-control', 'public');
|
||||
res.setHeader('Expires', new Date(Date.now() + 1000 * 60 * 60 * 24).toUTCString());
|
||||
res.setHeader('Expires', new Date(Date.now() + 1000 * 30).toUTCString());
|
||||
res.json(federationUtxos);
|
||||
} catch (e) {
|
||||
res.status(500).send(e instanceof Error ? e.message : e);
|
||||
}
|
||||
}
|
||||
|
||||
private async $getPegOuts(req: Request, res: Response) {
|
||||
private async $getPegsList(req: Request, res: Response) {
|
||||
try {
|
||||
const recentPegOuts = await elementsParser.$getRecentPegouts();
|
||||
const recentPegs = await elementsParser.$getPegsList(parseInt(req.params?.count));
|
||||
res.header('Pragma', 'public');
|
||||
res.header('Cache-control', 'public');
|
||||
res.setHeader('Expires', new Date(Date.now() + 1000 * 30).toUTCString());
|
||||
res.json(recentPegOuts);
|
||||
res.json(recentPegs);
|
||||
} catch (e) {
|
||||
res.status(500).send(e instanceof Error ? e.message : e);
|
||||
}
|
||||
@@ -202,6 +203,18 @@ class LiquidRoutes {
|
||||
}
|
||||
}
|
||||
|
||||
private async $getPegsCount(req: Request, res: Response) {
|
||||
try {
|
||||
const pegsCount = await elementsParser.$getPegsCount();
|
||||
res.header('Pragma', 'public');
|
||||
res.header('Cache-control', 'public');
|
||||
res.setHeader('Expires', new Date(Date.now() + 1000 * 30).toUTCString());
|
||||
res.json(pegsCount);
|
||||
} catch (e) {
|
||||
res.status(500).send(e instanceof Error ? e.message : e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default new LiquidRoutes();
|
||||
|
||||
@@ -285,7 +285,7 @@ class StatisticsApi {
|
||||
|
||||
public async $list2H(): Promise<OptimizedStatistic[]> {
|
||||
try {
|
||||
const query = `SELECT *, UNIX_TIMESTAMP(added) as added FROM statistics ORDER BY statistics.added DESC LIMIT 120`;
|
||||
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`;
|
||||
const [rows] = await DB.query({ sql: query, timeout: this.queryTimeout });
|
||||
return this.mapStatisticToOptimizedStatistic(rows as Statistic[]);
|
||||
} catch (e) {
|
||||
@@ -296,7 +296,7 @@ class StatisticsApi {
|
||||
|
||||
public async $list24H(): Promise<OptimizedStatistic[]> {
|
||||
try {
|
||||
const query = `SELECT *, UNIX_TIMESTAMP(added) as added FROM statistics ORDER BY statistics.added DESC LIMIT 1440`;
|
||||
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`;
|
||||
const [rows] = await DB.query({ sql: query, timeout: this.queryTimeout });
|
||||
return this.mapStatisticToOptimizedStatistic(rows as Statistic[]);
|
||||
} catch (e) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import statisticsApi from './statistics-api';
|
||||
|
||||
class Statistics {
|
||||
protected intervalTimer: NodeJS.Timer | undefined;
|
||||
protected lastRun: number = 0;
|
||||
protected newStatisticsEntryCallback: ((stats: OptimizedStatistic) => void) | undefined;
|
||||
|
||||
public setNewStatisticsEntryCallback(fn: (stats: OptimizedStatistic) => void) {
|
||||
@@ -23,15 +24,21 @@ class Statistics {
|
||||
setTimeout(() => {
|
||||
this.runStatistics();
|
||||
this.intervalTimer = setInterval(() => {
|
||||
this.runStatistics();
|
||||
this.runStatistics(true);
|
||||
}, 1 * 60 * 1000);
|
||||
}, difference);
|
||||
}
|
||||
|
||||
private async runStatistics(): Promise<void> {
|
||||
public async runStatistics(skipIfRecent = false): Promise<void> {
|
||||
if (!memPool.isInSync()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (skipIfRecent && new Date().getTime() / 1000 - this.lastRun < 30) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.lastRun = new Date().getTime() / 1000;
|
||||
const currentMempool = memPool.getMempool();
|
||||
const txPerSecond = memPool.getTxPerSecond();
|
||||
const vBytesPerSecond = memPool.getVBytesPerSecond();
|
||||
|
||||
@@ -23,6 +23,7 @@ import priceUpdater from '../tasks/price-updater';
|
||||
import { ApiPrice } from '../repositories/PricesRepository';
|
||||
import accelerationApi from './services/acceleration';
|
||||
import mempool from './mempool';
|
||||
import statistics from './statistics/statistics';
|
||||
|
||||
interface AddressTransactions {
|
||||
mempool: MempoolTransactionExtended[],
|
||||
@@ -723,6 +724,7 @@ class WebsocketHandler {
|
||||
}
|
||||
|
||||
this.printLogs();
|
||||
await statistics.runStatistics();
|
||||
|
||||
const _memPool = memPool.getMempool();
|
||||
|
||||
@@ -1014,6 +1016,8 @@ class WebsocketHandler {
|
||||
client.send(this.serializeResponse(response));
|
||||
}
|
||||
});
|
||||
|
||||
await statistics.runStatistics();
|
||||
}
|
||||
|
||||
// takes a dictionary of JSON serialized values
|
||||
|
||||
Reference in New Issue
Block a user