mirror of
https://github.com/benjamin-wilson/public-pool.git
synced 2026-09-29 09:05:06 -07:00
Omit current chart bucket
This commit is contained in:
@@ -66,34 +66,7 @@ export class ClientStatisticsService {
|
|||||||
WITH bounds AS (
|
WITH bounds AS (
|
||||||
SELECT
|
SELECT
|
||||||
NOW() - INTERVAL '${windowSql}' AS since,
|
NOW() - INTERVAL '${windowSql}' AS since,
|
||||||
time_bucket(INTERVAL '10 minutes', NOW()) AS realtime_start
|
time_bucket(INTERVAL '10 minutes', NOW()) AS current_bucket
|
||||||
),
|
|
||||||
aggregate_rows AS (
|
|
||||||
SELECT
|
|
||||||
"bucket",
|
|
||||||
SUM("shares") AS "shares",
|
|
||||||
SUM("acceptedCount") AS "acceptedCount"
|
|
||||||
FROM "accepted_share_10m", bounds
|
|
||||||
WHERE "bucket" > bounds.since
|
|
||||||
AND "bucket" < bounds.realtime_start
|
|
||||||
${filterSql}
|
|
||||||
GROUP BY "bucket"
|
|
||||||
),
|
|
||||||
realtime_rows AS (
|
|
||||||
SELECT
|
|
||||||
time_bucket(INTERVAL '10 minutes', "acceptedAt") AS "bucket",
|
|
||||||
SUM("creditedDifficulty") AS "shares",
|
|
||||||
COUNT(*) AS "acceptedCount"
|
|
||||||
FROM "accepted_share_entity", bounds
|
|
||||||
WHERE "acceptedAt" > bounds.since
|
|
||||||
AND "acceptedAt" >= bounds.realtime_start
|
|
||||||
${filterSql}
|
|
||||||
GROUP BY "bucket"
|
|
||||||
),
|
|
||||||
combined_rows AS (
|
|
||||||
SELECT * FROM aggregate_rows
|
|
||||||
UNION ALL
|
|
||||||
SELECT * FROM realtime_rows
|
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
"label",
|
"label",
|
||||||
@@ -106,7 +79,10 @@ export class ClientStatisticsService {
|
|||||||
ROUND((SUM("shares") * ${HASHES_PER_DIFFICULTY}) / ${CHART_BUCKET_SECONDS}) AS "data",
|
ROUND((SUM("shares") * ${HASHES_PER_DIFFICULTY}) / ${CHART_BUCKET_SECONDS}) AS "data",
|
||||||
SUM("shares") AS "shares",
|
SUM("shares") AS "shares",
|
||||||
SUM("acceptedCount") AS "acceptedCount"
|
SUM("acceptedCount") AS "acceptedCount"
|
||||||
FROM combined_rows
|
FROM "accepted_share_10m", bounds
|
||||||
|
WHERE "bucket" > bounds.since
|
||||||
|
AND "bucket" < bounds.current_bucket
|
||||||
|
${filterSql}
|
||||||
GROUP BY "bucket"
|
GROUP BY "bucket"
|
||||||
ORDER BY "bucket" DESC
|
ORDER BY "bucket" DESC
|
||||||
LIMIT ${limit}
|
LIMIT ${limit}
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ describe('TimescaleDB and Redis integration', () => {
|
|||||||
}]));
|
}]));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should serve realtime chart and hashrate data from accepted shares', async () => {
|
it('should serve completed chart buckets and omit the current in-progress bucket', async () => {
|
||||||
const client = await dataSource.getRepository(ClientEntity).save({
|
const client = await dataSource.getRepository(ClientEntity).save({
|
||||||
address: 'tb1qumezefzdeqqwn5zfvgdrhxjzc5ylr39uhuxcz4',
|
address: 'tb1qumezefzdeqqwn5zfvgdrhxjzc5ylr39uhuxcz4',
|
||||||
clientName: 'worker',
|
clientName: 'worker',
|
||||||
@@ -241,7 +241,10 @@ describe('TimescaleDB and Redis integration', () => {
|
|||||||
});
|
});
|
||||||
const accountingService = new ShareAccountingService(dataSource.getRepository(AcceptedShareEntity));
|
const accountingService = new ShareAccountingService(dataSource.getRepository(AcceptedShareEntity));
|
||||||
const statisticsService = new ClientStatisticsService(dataSource);
|
const statisticsService = new ClientStatisticsService(dataSource);
|
||||||
const acceptedAt = new Date();
|
const currentBucketStart = Math.floor(Date.now() / (10 * 60 * 1000)) * 10 * 60 * 1000;
|
||||||
|
const completedBucketStart = currentBucketStart - (10 * 60 * 1000);
|
||||||
|
const completedBucketEnd = currentBucketStart;
|
||||||
|
const acceptedAt = new Date(completedBucketStart + 1000);
|
||||||
|
|
||||||
for (const [index, difficulty] of [64, 32].entries()) {
|
for (const [index, difficulty] of [64, 32].entries()) {
|
||||||
await accountingService.recordAcceptedShare({
|
await accountingService.recordAcceptedShare({
|
||||||
@@ -265,11 +268,36 @@ describe('TimescaleDB and Redis integration', () => {
|
|||||||
blockSubmissionResult: null,
|
blockSubmissionResult: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
await accountingService.recordAcceptedShare({
|
||||||
|
protocol: 'sv1',
|
||||||
|
acceptedAt: new Date(currentBucketStart + 1000),
|
||||||
|
address: client.address,
|
||||||
|
clientName: client.clientName,
|
||||||
|
sessionId: client.sessionId,
|
||||||
|
clientId: client.id,
|
||||||
|
jobId: 'current-bucket',
|
||||||
|
jobTemplateId: 'realtime-template',
|
||||||
|
blockHeight: 900001,
|
||||||
|
creditedDifficulty: 1024,
|
||||||
|
submissionDifficulty: 2048,
|
||||||
|
networkDifficulty: 100000,
|
||||||
|
nonce: 'nonce-current',
|
||||||
|
ntime: '64b3f3ec',
|
||||||
|
version: '20000000',
|
||||||
|
extraNonce2: 'c708000000000000',
|
||||||
|
isBlockCandidate: false,
|
||||||
|
blockSubmissionResult: null,
|
||||||
|
});
|
||||||
|
await dataSource.query(
|
||||||
|
`CALL refresh_continuous_aggregate('accepted_share_10m', $1::timestamptz, $2::timestamptz)`,
|
||||||
|
[new Date(completedBucketStart), new Date(completedBucketEnd)],
|
||||||
|
);
|
||||||
|
|
||||||
const expectedHashRate = (96 * 4294967296) / 600;
|
const expectedHashRate = (96 * 4294967296) / 600;
|
||||||
const expectedChartData = Math.round(expectedHashRate).toString();
|
const expectedChartData = Math.round(expectedHashRate).toString();
|
||||||
|
const expectedLiveHashRate = ((96 + 1024) * 4294967296) / 600;
|
||||||
expect(await statisticsService.getHashRateForGroup(client.address, client.clientName))
|
expect(await statisticsService.getHashRateForGroup(client.address, client.clientName))
|
||||||
.toBeCloseTo(expectedHashRate);
|
.toBeCloseTo(expectedLiveHashRate);
|
||||||
|
|
||||||
const addressChart = await statisticsService.getChartDataForAddress(client.address);
|
const addressChart = await statisticsService.getChartDataForAddress(client.address);
|
||||||
const groupChart = await statisticsService.getChartDataForGroup(client.address, client.clientName);
|
const groupChart = await statisticsService.getChartDataForGroup(client.address, client.clientName);
|
||||||
@@ -280,6 +308,9 @@ describe('TimescaleDB and Redis integration', () => {
|
|||||||
expect(chart).toEqual(expect.arrayContaining([
|
expect(chart).toEqual(expect.arrayContaining([
|
||||||
expect.objectContaining({ data: expectedChartData }),
|
expect.objectContaining({ data: expectedChartData }),
|
||||||
]));
|
]));
|
||||||
|
expect(chart).not.toEqual(expect.arrayContaining([
|
||||||
|
expect.objectContaining({ label: new Date(currentBucketStart).toISOString() }),
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user