mirror of
https://github.com/benjamin-wilson/public-pool.git
synced 2025-03-28 18:52:16 +01:00
data rework
This commit is contained in:
parent
d718df88cd
commit
5dd1fa3dfa
2
.gitignore
vendored
2
.gitignore
vendored
@ -37,4 +37,4 @@ settings.json
|
|||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
|
|
||||||
#DB
|
#DB
|
||||||
**.sqlite
|
**.sqlite**
|
@ -1,6 +1,5 @@
|
|||||||
import { Column, Entity, Index, PrimaryColumn } from 'typeorm';
|
import { Column, Entity, Index, PrimaryColumn } from 'typeorm';
|
||||||
|
|
||||||
import { DateTimeTransformer } from '../utils/DateTimeTransformer';
|
|
||||||
import { TrackedEntity } from '../utils/TrackedEntity.entity';
|
import { TrackedEntity } from '../utils/TrackedEntity.entity';
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
@ -9,6 +8,7 @@ export class ClientStatisticsEntity extends TrackedEntity {
|
|||||||
@PrimaryColumn({ length: 64, type: 'varchar' })
|
@PrimaryColumn({ length: 64, type: 'varchar' })
|
||||||
submissionHash: string;
|
submissionHash: string;
|
||||||
|
|
||||||
|
@Index()
|
||||||
@Column({ length: 62, type: 'varchar' })
|
@Column({ length: 62, type: 'varchar' })
|
||||||
address: string;
|
address: string;
|
||||||
|
|
||||||
@ -20,14 +20,11 @@ export class ClientStatisticsEntity extends TrackedEntity {
|
|||||||
sessionId: string;
|
sessionId: string;
|
||||||
|
|
||||||
@Index()
|
@Index()
|
||||||
@Column({
|
@Column({ type: 'integer' })
|
||||||
type: 'datetime',
|
time: number;
|
||||||
transformer: new DateTimeTransformer()
|
|
||||||
})
|
|
||||||
time: Date;
|
|
||||||
|
|
||||||
@Column({ type: 'real' })
|
@Column({ type: 'real' })
|
||||||
difficulty: number;
|
shares: number;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,7 +18,17 @@ export class ClientStatisticsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async save(clientStatistic: Partial<ClientStatisticsEntity>) {
|
public async save(clientStatistic: Partial<ClientStatisticsEntity>) {
|
||||||
return await this.clientStatisticsRepository.save(clientStatistic);
|
const res1 = await this.clientStatisticsRepository.createQueryBuilder()
|
||||||
|
.update(ClientStatisticsEntity)
|
||||||
|
.set({
|
||||||
|
shares: () => `"shares" + ${clientStatistic.shares}` // Use the actual value of shares here
|
||||||
|
})
|
||||||
|
.where('address = :address AND clientName = :clientName AND sessionId = :sessionId AND time = :time', { address: clientStatistic.address, clientName: clientStatistic.clientName, sessionId: clientStatistic.sessionId, time: clientStatistic.time })
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
if (res1.affected == 0) {
|
||||||
|
await this.clientStatisticsRepository.insert(clientStatistic);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async deleteOldStatistics() {
|
public async deleteOldStatistics() {
|
||||||
@ -34,79 +44,74 @@ export class ClientStatisticsService {
|
|||||||
|
|
||||||
public async getChartDataForSite() {
|
public async getChartDataForSite() {
|
||||||
|
|
||||||
|
var yesterday = new Date(new Date().getTime() - (24 * 60 * 60 * 1000));
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
WITH result_set AS (
|
|
||||||
SELECT
|
SELECT
|
||||||
MAX(time) || 'GMT' AS label,
|
time AS label,
|
||||||
(SUM(difficulty) * 4294967296) /
|
ROUND(((SUM(shares) * 4294967296) / 600)) AS data
|
||||||
((JULIANDAY(MAX(time)) - JULIANDAY(MIN(time))) * 24 * 60 * 60) AS data
|
|
||||||
FROM
|
FROM
|
||||||
client_statistics_entity AS entry
|
client_statistics_entity AS entry
|
||||||
WHERE
|
WHERE
|
||||||
entry.time > datetime("now", "-1 day")
|
entry.time > ${yesterday.getTime()}
|
||||||
GROUP BY
|
GROUP BY
|
||||||
strftime('%Y-%m-%d %H', time, 'localtime') || (strftime('%M', time, 'localtime') / 10)
|
time
|
||||||
ORDER BY
|
ORDER BY
|
||||||
time
|
time
|
||||||
)
|
LIMIT 144;
|
||||||
SELECT *
|
|
||||||
FROM result_set
|
|
||||||
WHERE label <> (SELECT MAX(label) FROM result_set);
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const result = await this.clientStatisticsRepository.query(query);
|
const result: any[] = await this.clientStatisticsRepository.query(query);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return result.map(res => {
|
return result.map(res => {
|
||||||
res.label = new Date(res.label).toISOString();
|
res.label = new Date(res.label).toISOString();
|
||||||
return res;
|
return res;
|
||||||
});
|
}).slice(0, result.length - 1)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async getHashRateForAddress(address: string) {
|
// public async getHashRateForAddress(address: string) {
|
||||||
|
|
||||||
const query = `
|
// const oneHour = new Date(new Date().getTime() - (60 * 60 * 1000));
|
||||||
SELECT
|
|
||||||
(JULIANDAY(MAX(entry.time)) - JULIANDAY(MIN(entry.time))) * 24 * 60 * 60 AS timeDiff,
|
|
||||||
SUM(entry.difficulty) AS difficultySum
|
|
||||||
FROM
|
|
||||||
client_statistics_entity AS entry
|
|
||||||
WHERE
|
|
||||||
entry.address = ? AND entry.time > datetime("now", "-1 hour")
|
|
||||||
`;
|
|
||||||
|
|
||||||
const result = await this.clientStatisticsRepository.query(query, [address]);
|
// const query = `
|
||||||
|
// SELECT
|
||||||
|
// SUM(entry.shares) AS difficultySum
|
||||||
|
// FROM
|
||||||
|
// client_statistics_entity AS entry
|
||||||
|
// WHERE
|
||||||
|
// entry.address = ? AND entry.time > ${oneHour}
|
||||||
|
// `;
|
||||||
|
|
||||||
const timeDiff = result[0].timeDiff;
|
// const result = await this.clientStatisticsRepository.query(query, [address]);
|
||||||
const difficultySum = result[0].difficultySum;
|
|
||||||
|
|
||||||
return (difficultySum * 4294967296) / (timeDiff);
|
// const difficultySum = result[0].difficultySum;
|
||||||
|
|
||||||
}
|
// return (difficultySum * 4294967296) / (600);
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
public async getChartDataForAddress(address: string) {
|
public async getChartDataForAddress(address: string) {
|
||||||
|
|
||||||
|
var yesterday = new Date(new Date().getTime() - (24 * 60 * 60 * 1000));
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
WITH result_set AS (
|
|
||||||
SELECT
|
SELECT
|
||||||
MAX(time) || 'GMT' AS label,
|
time label,
|
||||||
(SUM(difficulty) * 4294967296) /
|
(SUM(shares) * 4294967296) / 600 AS data
|
||||||
((JULIANDAY(MAX(time)) - JULIANDAY(MIN(time))) * 24 * 60 * 60) AS data
|
|
||||||
FROM
|
FROM
|
||||||
client_statistics_entity AS entry
|
client_statistics_entity AS entry
|
||||||
WHERE
|
WHERE
|
||||||
entry.address = ? AND entry.time > datetime("now", "-1 day")
|
entry.address = ? AND entry.time > ${yesterday.getTime()}
|
||||||
GROUP BY
|
GROUP BY
|
||||||
strftime('%Y-%m-%d %H', time, 'localtime') || (strftime('%M', time, 'localtime') / 10)
|
time
|
||||||
ORDER BY
|
ORDER BY
|
||||||
time
|
time
|
||||||
)
|
LIMIT 144;
|
||||||
SELECT *
|
|
||||||
FROM result_set
|
|
||||||
WHERE label <> (SELECT MAX(label) FROM result_set);
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const result = await this.clientStatisticsRepository.query(query, [address]);
|
const result = await this.clientStatisticsRepository.query(query, [address]);
|
||||||
@ -114,52 +119,50 @@ export class ClientStatisticsService {
|
|||||||
return result.map(res => {
|
return result.map(res => {
|
||||||
res.label = new Date(res.label).toISOString();
|
res.label = new Date(res.label).toISOString();
|
||||||
return res;
|
return res;
|
||||||
});
|
}).slice(0, result.length - 1);
|
||||||
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async getHashRateForGroup(address: string, clientName: string) {
|
public async getHashRateForGroup(address: string, clientName: string) {
|
||||||
|
|
||||||
|
var oneHour = new Date(new Date().getTime() - (60 * 60 * 1000));
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
SELECT
|
SELECT
|
||||||
(JULIANDAY(MAX(entry.time)) - JULIANDAY(MIN(entry.time))) * 24 * 60 * 60 AS timeDiff,
|
SUM(entry.shares) AS difficultySum
|
||||||
SUM(entry.difficulty) AS difficultySum
|
|
||||||
FROM
|
FROM
|
||||||
client_statistics_entity AS entry
|
client_statistics_entity AS entry
|
||||||
WHERE
|
WHERE
|
||||||
entry.address = ? AND entry.clientName = ? AND entry.time > datetime("now", "-1 hour")
|
entry.address = ? AND entry.clientName = ? AND entry.time > ${oneHour.getTime()}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const result = await this.clientStatisticsRepository.query(query, [address, clientName]);
|
const result = await this.clientStatisticsRepository.query(query, [address, clientName]);
|
||||||
|
|
||||||
const timeDiff = result[0].timeDiff;
|
|
||||||
const difficultySum = result[0].difficultySum;
|
const difficultySum = result[0].difficultySum;
|
||||||
|
|
||||||
return (difficultySum * 4294967296) / (timeDiff);
|
return (difficultySum * 4294967296) / (600);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getChartDataForGroup(address: string, clientName: string) {
|
public async getChartDataForGroup(address: string, clientName: string) {
|
||||||
|
var yesterday = new Date(new Date().getTime() - (24 * 60 * 60 * 1000));
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
WITH result_set AS (
|
SELECT
|
||||||
SELECT
|
time label,
|
||||||
MAX(time) || 'GMT' AS label,
|
(SUM(shares) * 4294967296) / 600 AS data
|
||||||
(SUM(difficulty) * 4294967296) /
|
FROM
|
||||||
((JULIANDAY(MAX(time)) - JULIANDAY(MIN(time))) * 24 * 60 * 60) AS data
|
client_statistics_entity AS entry
|
||||||
FROM
|
WHERE
|
||||||
client_statistics_entity AS entry
|
entry.address = ? AND entry.clientName = ? AND entry.time > ${yesterday.getTime()}
|
||||||
WHERE
|
GROUP BY
|
||||||
entry.address = ? AND entry.clientName = ? AND entry.time > datetime("now", "-1 day")
|
|
||||||
GROUP BY
|
|
||||||
strftime('%Y-%m-%d %H', time, 'localtime') || (strftime('%M', time, 'localtime') / 10)
|
|
||||||
ORDER BY
|
|
||||||
time
|
time
|
||||||
)
|
ORDER BY
|
||||||
SELECT *
|
time
|
||||||
FROM result_set
|
LIMIT 144;
|
||||||
WHERE label <> (SELECT MAX(label) FROM result_set);
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const result = await this.clientStatisticsRepository.query(query, [address, clientName]);
|
const result = await this.clientStatisticsRepository.query(query, [address, clientName]);
|
||||||
@ -167,9 +170,9 @@ export class ClientStatisticsService {
|
|||||||
return result.map(res => {
|
return result.map(res => {
|
||||||
res.label = new Date(res.label).toISOString();
|
res.label = new Date(res.label).toISOString();
|
||||||
return res;
|
return res;
|
||||||
});
|
}).slice(0, result.length - 1);
|
||||||
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -177,43 +180,50 @@ export class ClientStatisticsService {
|
|||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
SELECT
|
SELECT
|
||||||
(JULIANDAY(MAX(entry.time)) - JULIANDAY(MIN(entry.time))) * 24 * 60 * 60 AS timeDiff,
|
createdAt,
|
||||||
SUM(entry.difficulty) AS difficultySum
|
updatedAt,
|
||||||
|
shares
|
||||||
FROM
|
FROM
|
||||||
client_statistics_entity AS entry
|
client_statistics_entity AS entry
|
||||||
WHERE
|
WHERE
|
||||||
entry.address = ? AND entry.clientName = ? AND entry.sessionId = ? AND entry.time > datetime("now", "-1 hour")
|
entry.address = ? AND entry.clientName = ? AND entry.sessionId = ?
|
||||||
|
ORDER BY time DESC
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const result = await this.clientStatisticsRepository.query(query, [address, clientName, sessionId]);
|
const result = await this.clientStatisticsRepository.query(query, [address, clientName, sessionId]);
|
||||||
|
|
||||||
const timeDiff = result[0].timeDiff;
|
if (result.length < 1) {
|
||||||
const difficultySum = result[0].difficultySum;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return (difficultySum * 4294967296) / (timeDiff);
|
const time = new Date(result[0].updatedAt).getTime() - new Date(result[0].createdAt).getTime();
|
||||||
|
|
||||||
|
if (time < 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result[0].shares * 4294967296) / (time / 1000);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getChartDataForSession(address: string, clientName: string, sessionId: string) {
|
public async getChartDataForSession(address: string, clientName: string, sessionId: string) {
|
||||||
|
var yesterday = new Date(new Date().getTime() - (24 * 60 * 60 * 1000));
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
WITH result_set AS (
|
SELECT
|
||||||
SELECT
|
time label,
|
||||||
MAX(time) || 'GMT' AS label,
|
(SUM(shares) * 4294967296) / 600 AS data
|
||||||
(SUM(difficulty) * 4294967296) /
|
FROM
|
||||||
((JULIANDAY(MAX(time)) - JULIANDAY(MIN(time))) * 24 * 60 * 60) AS data
|
client_statistics_entity AS entry
|
||||||
FROM
|
WHERE
|
||||||
client_statistics_entity AS entry
|
entry.address = ? AND entry.clientName = ? AND entry.sessionId = ? AND entry.time > ${yesterday.getTime()}
|
||||||
WHERE
|
GROUP BY
|
||||||
entry.address = ? AND entry.clientName = ? AND entry.sessionId = ? AND entry.time > datetime("now", "-1 day")
|
time
|
||||||
GROUP BY
|
ORDER BY
|
||||||
strftime('%Y-%m-%d %H', time, 'localtime') || (strftime('%M', time, 'localtime') / 10)
|
time
|
||||||
ORDER BY
|
LIMIT 144;
|
||||||
time
|
|
||||||
)
|
|
||||||
SELECT *
|
|
||||||
FROM result_set
|
|
||||||
WHERE label <> (SELECT MAX(label) FROM result_set);
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const result = await this.clientStatisticsRepository.query(query, [address, clientName, sessionId]);
|
const result = await this.clientStatisticsRepository.query(query, [address, clientName, sessionId]);
|
||||||
@ -221,9 +231,8 @@ export class ClientStatisticsService {
|
|||||||
return result.map(res => {
|
return result.map(res => {
|
||||||
res.label = new Date(res.label).toISOString();
|
res.label = new Date(res.label).toISOString();
|
||||||
return res;
|
return res;
|
||||||
});
|
}).slice(0, result.length - 1);
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async deleteAll() {
|
public async deleteAll() {
|
||||||
|
@ -21,26 +21,30 @@ export class AppController {
|
|||||||
const blockData = await this.blocksService.getFoundBlocks();
|
const blockData = await this.blocksService.getFoundBlocks();
|
||||||
const userAgents = await this.clientService.getUserAgents();
|
const userAgents = await this.clientService.getUserAgents();
|
||||||
|
|
||||||
const CACHE_KEY = 'SITE_HASHRATE_GRAPH';
|
|
||||||
const cachedResult = await this.cacheManager.get(CACHE_KEY);
|
|
||||||
if (cachedResult != null) {
|
|
||||||
return {
|
|
||||||
chartData: cachedResult,
|
|
||||||
blockData,
|
|
||||||
userAgents
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const chartData = [];// await this.clientStatisticsService.getChartDataForSite();
|
|
||||||
|
|
||||||
//5 min
|
|
||||||
await this.cacheManager.set(CACHE_KEY, chartData, 5 * 60 * 1000);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
chartData,
|
|
||||||
blockData,
|
blockData,
|
||||||
userAgents
|
userAgents
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@Get('info/chart')
|
||||||
|
public async infoChart() {
|
||||||
|
|
||||||
|
|
||||||
|
// const CACHE_KEY = 'SITE_HASHRATE_GRAPH';
|
||||||
|
// const cachedResult = await this.cacheManager.get(CACHE_KEY);
|
||||||
|
|
||||||
|
// if (cachedResult != null) {
|
||||||
|
// return cachedResult;
|
||||||
|
// }
|
||||||
|
|
||||||
|
const chartData = await this.clientStatisticsService.getChartDataForSite();
|
||||||
|
|
||||||
|
//5 min
|
||||||
|
//await this.cacheManager.set(CACHE_KEY, chartData, 5 * 60 * 1000);
|
||||||
|
|
||||||
|
return chartData;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,8 @@ export class ClientController {
|
|||||||
|
|
||||||
const workers = await this.clientService.getByAddress(address);
|
const workers = await this.clientService.getByAddress(address);
|
||||||
|
|
||||||
const chartData = await this.clientStatisticsService.getChartDataForAddress(address);
|
|
||||||
|
|
||||||
const addressSettings = await this.addressSettingsService.getSettings(address);
|
const addressSettings = await this.addressSettingsService.getSettings(address);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
bestDifficulty: addressSettings?.bestDifficulty,
|
bestDifficulty: addressSettings?.bestDifficulty,
|
||||||
workersCount: workers.length,
|
workersCount: workers.length,
|
||||||
@ -39,11 +35,16 @@ export class ClientController {
|
|||||||
startTime: worker.startTime
|
startTime: worker.startTime
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
),
|
)
|
||||||
chartData
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get(':address/chart')
|
||||||
|
async getClientInfoChart(@Param('address') address: string) {
|
||||||
|
const chartData = await this.clientStatisticsService.getChartDataForAddress(address);
|
||||||
|
return chartData;
|
||||||
|
}
|
||||||
|
|
||||||
@Get(':address/:workerName')
|
@Get(':address/:workerName')
|
||||||
async getWorkerGroupInfo(@Param('address') address: string, @Param('workerName') workerName: string) {
|
async getWorkerGroupInfo(@Param('address') address: string, @Param('workerName') workerName: string) {
|
||||||
|
|
||||||
|
@ -24,9 +24,14 @@ export class StratumV1ClientStatistics {
|
|||||||
difficulty: targetDifficulty,
|
difficulty: targetDifficulty,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 10 min
|
||||||
|
var coeff = 1000 * 60 * 10;
|
||||||
|
var date = new Date();
|
||||||
|
var rounded = new Date(Math.round(date.getTime() / coeff) * coeff);
|
||||||
|
|
||||||
await this.clientStatisticsService.save({
|
await this.clientStatisticsService.save({
|
||||||
time: new Date(),
|
time: rounded.getTime(),
|
||||||
difficulty: targetDifficulty,
|
shares: targetDifficulty,
|
||||||
address: client.address,
|
address: client.address,
|
||||||
clientName: client.clientName,
|
clientName: client.clientName,
|
||||||
sessionId: client.sessionId,
|
sessionId: client.sessionId,
|
||||||
|
@ -14,7 +14,7 @@ export class SubscriptionMessage extends StratumBaseMessage {
|
|||||||
@IsString()
|
@IsString()
|
||||||
@MaxLength(128)
|
@MaxLength(128)
|
||||||
@Transform(({ value, key, obj, type }) => {
|
@Transform(({ value, key, obj, type }) => {
|
||||||
return obj.params[0] == null ? 'unknown' : SubscriptionMessage.refineUserAgent(obj.params);
|
return obj.params[0] == null ? 'unknown' : SubscriptionMessage.refineUserAgent(obj.params[0]);
|
||||||
})
|
})
|
||||||
public userAgent: string;
|
public userAgent: string;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user