mirror of
https://github.com/benjamin-wilson/public-pool.git
synced 2026-09-29 09:05:06 -07:00
Fix retained share high score ordering
This commit is contained in:
@@ -0,0 +1,250 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class AcceptedShareHighScoreNumericRetention1781402000000 implements MigrationInterface {
|
||||||
|
public name = 'AcceptedShareHighScoreNumericRetention1781402000000';
|
||||||
|
public transaction = false;
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE INDEX IF NOT EXISTS "IDX_accepted_share_block_10m_best"
|
||||||
|
ON "accepted_share_block_10m" ("bestSubmissionDifficulty" DESC, "bucket" DESC)
|
||||||
|
WHERE "bestSubmissionDifficulty" > 0
|
||||||
|
`);
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE INDEX IF NOT EXISTS "IDX_accepted_share_block_10m_mode_best"
|
||||||
|
ON "accepted_share_block_10m" ("payoutMode", "bestSubmissionDifficulty" DESC, "bucket" DESC)
|
||||||
|
WHERE "bestSubmissionDifficulty" > 0
|
||||||
|
`);
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE INDEX IF NOT EXISTS "IDX_client_best_difficulty_mode"
|
||||||
|
ON "client_entity" ("payoutMode", "bestDifficulty" DESC, "updatedAt" DESC)
|
||||||
|
WHERE "bestDifficulty" > 0
|
||||||
|
`);
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE INDEX IF NOT EXISTS "IDX_address_settings_best_difficulty"
|
||||||
|
ON "address_settings_entity" ("bestDifficulty" DESC, "updatedAt" DESC)
|
||||||
|
WHERE "bestDifficulty" > 0
|
||||||
|
`);
|
||||||
|
|
||||||
|
await this.backfillRollupAllTime(queryRunner);
|
||||||
|
await this.backfillClientAllTime(queryRunner);
|
||||||
|
await this.backfillAddressSettingsAllTime(queryRunner);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_address_settings_best_difficulty"`);
|
||||||
|
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_client_best_difficulty_mode"`);
|
||||||
|
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_accepted_share_block_10m_mode_best"`);
|
||||||
|
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_accepted_share_block_10m_best"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async backfillRollupAllTime(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`
|
||||||
|
WITH candidates AS (
|
||||||
|
SELECT
|
||||||
|
"payoutMode",
|
||||||
|
"bucket",
|
||||||
|
"blockHeight",
|
||||||
|
"bestSubmissionDifficulty"
|
||||||
|
FROM "accepted_share_block_10m"
|
||||||
|
WHERE "bestSubmissionDifficulty" IS NOT NULL
|
||||||
|
AND "bestSubmissionDifficulty" > 0
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
'all' AS "payoutMode",
|
||||||
|
"bucket",
|
||||||
|
"blockHeight",
|
||||||
|
"bestSubmissionDifficulty"
|
||||||
|
FROM "accepted_share_block_10m"
|
||||||
|
WHERE "bestSubmissionDifficulty" IS NOT NULL
|
||||||
|
AND "bestSubmissionDifficulty" > 0
|
||||||
|
),
|
||||||
|
best_rows AS (
|
||||||
|
SELECT DISTINCT ON ("payoutMode")
|
||||||
|
"payoutMode",
|
||||||
|
"bucket",
|
||||||
|
"blockHeight",
|
||||||
|
"bestSubmissionDifficulty"
|
||||||
|
FROM candidates
|
||||||
|
ORDER BY "payoutMode", "bestSubmissionDifficulty" DESC, "bucket" DESC
|
||||||
|
)
|
||||||
|
INSERT INTO "accepted_share_high_score" (
|
||||||
|
"scope",
|
||||||
|
"payoutMode",
|
||||||
|
"bucketDate",
|
||||||
|
"submissionDifficulty",
|
||||||
|
"acceptedAt",
|
||||||
|
"bucket",
|
||||||
|
"blockHeight",
|
||||||
|
"address",
|
||||||
|
"clientName",
|
||||||
|
"protocol"
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
'all_time',
|
||||||
|
"payoutMode",
|
||||||
|
DATE '1970-01-01',
|
||||||
|
"bestSubmissionDifficulty",
|
||||||
|
"bucket",
|
||||||
|
"bucket",
|
||||||
|
"blockHeight",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
FROM best_rows
|
||||||
|
ON CONFLICT ("scope", "payoutMode", "bucketDate")
|
||||||
|
DO UPDATE SET
|
||||||
|
"submissionDifficulty" = EXCLUDED."submissionDifficulty",
|
||||||
|
"acceptedAt" = EXCLUDED."acceptedAt",
|
||||||
|
"bucket" = EXCLUDED."bucket",
|
||||||
|
"blockHeight" = EXCLUDED."blockHeight",
|
||||||
|
"address" = EXCLUDED."address",
|
||||||
|
"clientName" = EXCLUDED."clientName",
|
||||||
|
"protocol" = EXCLUDED."protocol",
|
||||||
|
"updatedAt" = NOW()
|
||||||
|
WHERE EXCLUDED."submissionDifficulty" > "accepted_share_high_score"."submissionDifficulty"
|
||||||
|
OR (
|
||||||
|
EXCLUDED."submissionDifficulty" = "accepted_share_high_score"."submissionDifficulty"
|
||||||
|
AND EXCLUDED."acceptedAt" > COALESCE("accepted_share_high_score"."acceptedAt", '-infinity'::timestamptz)
|
||||||
|
)
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async backfillClientAllTime(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`
|
||||||
|
WITH candidates AS (
|
||||||
|
SELECT
|
||||||
|
"payoutMode",
|
||||||
|
"bestDifficulty",
|
||||||
|
"updatedAt",
|
||||||
|
"address",
|
||||||
|
"clientName",
|
||||||
|
"userAgent"
|
||||||
|
FROM "client_entity"
|
||||||
|
WHERE "bestDifficulty" IS NOT NULL
|
||||||
|
AND "bestDifficulty" > 0
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
'all' AS "payoutMode",
|
||||||
|
"bestDifficulty",
|
||||||
|
"updatedAt",
|
||||||
|
"address",
|
||||||
|
"clientName",
|
||||||
|
"userAgent"
|
||||||
|
FROM "client_entity"
|
||||||
|
WHERE "bestDifficulty" IS NOT NULL
|
||||||
|
AND "bestDifficulty" > 0
|
||||||
|
),
|
||||||
|
best_rows AS (
|
||||||
|
SELECT DISTINCT ON ("payoutMode")
|
||||||
|
"payoutMode",
|
||||||
|
"bestDifficulty",
|
||||||
|
"updatedAt",
|
||||||
|
"address",
|
||||||
|
"clientName",
|
||||||
|
"userAgent"
|
||||||
|
FROM candidates
|
||||||
|
ORDER BY "payoutMode", "bestDifficulty" DESC, "updatedAt" DESC
|
||||||
|
)
|
||||||
|
INSERT INTO "accepted_share_high_score" (
|
||||||
|
"scope",
|
||||||
|
"payoutMode",
|
||||||
|
"bucketDate",
|
||||||
|
"submissionDifficulty",
|
||||||
|
"acceptedAt",
|
||||||
|
"bucket",
|
||||||
|
"blockHeight",
|
||||||
|
"address",
|
||||||
|
"clientName",
|
||||||
|
"protocol"
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
'all_time',
|
||||||
|
"payoutMode",
|
||||||
|
DATE '1970-01-01',
|
||||||
|
"bestDifficulty",
|
||||||
|
"updatedAt",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
"address",
|
||||||
|
"clientName",
|
||||||
|
"userAgent"
|
||||||
|
FROM best_rows
|
||||||
|
ON CONFLICT ("scope", "payoutMode", "bucketDate")
|
||||||
|
DO UPDATE SET
|
||||||
|
"submissionDifficulty" = EXCLUDED."submissionDifficulty",
|
||||||
|
"acceptedAt" = EXCLUDED."acceptedAt",
|
||||||
|
"bucket" = EXCLUDED."bucket",
|
||||||
|
"blockHeight" = EXCLUDED."blockHeight",
|
||||||
|
"address" = EXCLUDED."address",
|
||||||
|
"clientName" = EXCLUDED."clientName",
|
||||||
|
"protocol" = EXCLUDED."protocol",
|
||||||
|
"updatedAt" = NOW()
|
||||||
|
WHERE EXCLUDED."submissionDifficulty" > "accepted_share_high_score"."submissionDifficulty"
|
||||||
|
OR (
|
||||||
|
EXCLUDED."submissionDifficulty" = "accepted_share_high_score"."submissionDifficulty"
|
||||||
|
AND EXCLUDED."acceptedAt" > COALESCE("accepted_share_high_score"."acceptedAt", '-infinity'::timestamptz)
|
||||||
|
)
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async backfillAddressSettingsAllTime(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`
|
||||||
|
WITH best_row AS (
|
||||||
|
SELECT
|
||||||
|
"bestDifficulty",
|
||||||
|
"updatedAt",
|
||||||
|
"address",
|
||||||
|
"bestDifficultyUserAgent"
|
||||||
|
FROM "address_settings_entity"
|
||||||
|
WHERE "bestDifficulty" IS NOT NULL
|
||||||
|
AND "bestDifficulty" > 0
|
||||||
|
ORDER BY "bestDifficulty" DESC, "updatedAt" DESC
|
||||||
|
LIMIT 1
|
||||||
|
)
|
||||||
|
INSERT INTO "accepted_share_high_score" (
|
||||||
|
"scope",
|
||||||
|
"payoutMode",
|
||||||
|
"bucketDate",
|
||||||
|
"submissionDifficulty",
|
||||||
|
"acceptedAt",
|
||||||
|
"bucket",
|
||||||
|
"blockHeight",
|
||||||
|
"address",
|
||||||
|
"clientName",
|
||||||
|
"protocol"
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
'all_time',
|
||||||
|
'all',
|
||||||
|
DATE '1970-01-01',
|
||||||
|
"bestDifficulty",
|
||||||
|
"updatedAt",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
"address",
|
||||||
|
NULL,
|
||||||
|
"bestDifficultyUserAgent"
|
||||||
|
FROM best_row
|
||||||
|
ON CONFLICT ("scope", "payoutMode", "bucketDate")
|
||||||
|
DO UPDATE SET
|
||||||
|
"submissionDifficulty" = EXCLUDED."submissionDifficulty",
|
||||||
|
"acceptedAt" = EXCLUDED."acceptedAt",
|
||||||
|
"bucket" = EXCLUDED."bucket",
|
||||||
|
"blockHeight" = EXCLUDED."blockHeight",
|
||||||
|
"address" = EXCLUDED."address",
|
||||||
|
"clientName" = EXCLUDED."clientName",
|
||||||
|
"protocol" = EXCLUDED."protocol",
|
||||||
|
"updatedAt" = NOW()
|
||||||
|
WHERE EXCLUDED."submissionDifficulty" > "accepted_share_high_score"."submissionDifficulty"
|
||||||
|
OR (
|
||||||
|
EXCLUDED."submissionDifficulty" = "accepted_share_high_score"."submissionDifficulty"
|
||||||
|
AND EXCLUDED."acceptedAt" > COALESCE("accepted_share_high_score"."acceptedAt", '-infinity'::timestamptz)
|
||||||
|
)
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
import { DataSource, EntityManager } from 'typeorm';
|
||||||
|
|
||||||
|
import { ShareHighScoreService } from './share-high-score.service';
|
||||||
|
|
||||||
|
describe('ShareHighScoreService', () => {
|
||||||
|
it('orders aggregate candidates numerically and retains all-time client/address highs', async () => {
|
||||||
|
const upserts: unknown[][] = [];
|
||||||
|
const manager = {
|
||||||
|
query: jest.fn(async (sql: string, params: unknown[] = []) => {
|
||||||
|
if (sql.includes('pg_try_advisory_xact_lock')) {
|
||||||
|
return [{ locked: true }];
|
||||||
|
}
|
||||||
|
if (sql.includes('WITH candidate_rows')) {
|
||||||
|
expect(sql).toContain('"bestSubmissionDifficulty"::numeric DESC');
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if (sql.includes('FROM "accepted_share_block_10m"')) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if (sql.includes('FROM "client_entity"')) {
|
||||||
|
const payoutMode = params[0] as string | undefined;
|
||||||
|
const difficultyByMode = {
|
||||||
|
solo: '10828324014691.838',
|
||||||
|
pplns: '2688488439606.743',
|
||||||
|
all: '10828324014691.838',
|
||||||
|
};
|
||||||
|
const mode = payoutMode ?? 'all';
|
||||||
|
return [{
|
||||||
|
submissionDifficulty: difficultyByMode[mode],
|
||||||
|
acceptedAt: new Date('2026-07-16T06:33:41.270Z'),
|
||||||
|
address: 'bc1qe4zjanpz5tg96a278ew3l2g0h9h0qddgcdvp43',
|
||||||
|
clientName: 'bitaxe',
|
||||||
|
protocol: 'bitaxe',
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
if (sql.includes('FROM "address_settings_entity"')) {
|
||||||
|
return [{
|
||||||
|
submissionDifficulty: '294141974944674.8',
|
||||||
|
acceptedAt: new Date('2026-07-10T03:31:15.987Z'),
|
||||||
|
address: 'bc1q0pp74ghs25vpn2ah6auz4vkehvzy8z8ddyzts7',
|
||||||
|
protocol: 'bitaxe',
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
if (sql.includes('INSERT INTO "accepted_share_high_score"')) {
|
||||||
|
upserts.push(params);
|
||||||
|
return [{ inserted: 1 }];
|
||||||
|
}
|
||||||
|
throw new Error(`Unexpected query: ${sql}`);
|
||||||
|
}),
|
||||||
|
} as unknown as EntityManager;
|
||||||
|
const dataSource = {
|
||||||
|
transaction: jest.fn((callback: (manager: EntityManager) => Promise<unknown>) => callback(manager)),
|
||||||
|
} as unknown as DataSource;
|
||||||
|
const service = new ShareHighScoreService(dataSource);
|
||||||
|
|
||||||
|
await expect(service.refreshHighScores()).resolves.toEqual({
|
||||||
|
processed: true,
|
||||||
|
updatedRows: 4,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(upserts).toEqual(expect.arrayContaining([
|
||||||
|
expect.arrayContaining(['all_time', 'all', '1970-01-01', '294141974944674.8']),
|
||||||
|
expect.arrayContaining(['all_time', 'solo', '1970-01-01', '10828324014691.838']),
|
||||||
|
expect.arrayContaining(['all_time', 'pplns', '1970-01-01', '2688488439606.743']),
|
||||||
|
]));
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -139,6 +139,11 @@ export class ShareHighScoreService implements OnModuleInit, OnModuleDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const allTimeRecords = await this.loadAllTimeRecords(manager, payoutMode);
|
||||||
|
for (const record of allTimeRecords) {
|
||||||
|
updatedRows += await this.upsertHighScore(manager, record);
|
||||||
|
}
|
||||||
|
|
||||||
return updatedRows;
|
return updatedRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,10 +172,130 @@ export class ShareHighScoreService implements OnModuleInit, OnModuleDestroy {
|
|||||||
"blockHeight"::text AS "blockHeight",
|
"blockHeight"::text AS "blockHeight",
|
||||||
"bestSubmissionDifficulty"::text AS "bestSubmissionDifficulty"
|
"bestSubmissionDifficulty"::text AS "bestSubmissionDifficulty"
|
||||||
FROM candidate_rows
|
FROM candidate_rows
|
||||||
ORDER BY "bucketDate", "bestSubmissionDifficulty" DESC, "bucket" DESC
|
ORDER BY "bucketDate", "bestSubmissionDifficulty"::numeric DESC, "bucket" DESC
|
||||||
`, params);
|
`, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async loadAllTimeRecords(manager: EntityManager, payoutMode: HighScorePayoutMode): Promise<HighScoreRecord[]> {
|
||||||
|
const records: HighScoreRecord[] = [];
|
||||||
|
const rollupCandidate = await this.loadRollupAllTimeCandidate(manager, payoutMode);
|
||||||
|
if (rollupCandidate != null) {
|
||||||
|
records.push(this.toRecord('all_time', payoutMode, ALL_TIME_BUCKET_DATE, rollupCandidate, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
const clientRecord = await this.loadClientAllTimeRecord(manager, payoutMode);
|
||||||
|
if (clientRecord != null) {
|
||||||
|
records.push(clientRecord);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payoutMode === 'all') {
|
||||||
|
const addressRecord = await this.loadAddressSettingsAllTimeRecord(manager);
|
||||||
|
if (addressRecord != null) {
|
||||||
|
records.push(addressRecord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return records;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async loadRollupAllTimeCandidate(
|
||||||
|
manager: EntityManager,
|
||||||
|
payoutMode: HighScorePayoutMode,
|
||||||
|
): Promise<HighScoreCandidate | null> {
|
||||||
|
const params: unknown[] = [];
|
||||||
|
const modeFilter = payoutMode === 'all'
|
||||||
|
? ''
|
||||||
|
: `AND "payoutMode" = $${params.push(payoutMode)}`;
|
||||||
|
const rows = await manager.query(`
|
||||||
|
SELECT
|
||||||
|
date_trunc('day', "bucket")::date::text AS "bucketDate",
|
||||||
|
"bucket",
|
||||||
|
"blockHeight"::text AS "blockHeight",
|
||||||
|
"bestSubmissionDifficulty"::text AS "bestSubmissionDifficulty"
|
||||||
|
FROM "accepted_share_block_10m"
|
||||||
|
WHERE "bestSubmissionDifficulty" IS NOT NULL
|
||||||
|
AND "bestSubmissionDifficulty" > 0
|
||||||
|
${modeFilter}
|
||||||
|
ORDER BY "bestSubmissionDifficulty" DESC, "bucket" DESC
|
||||||
|
LIMIT 1
|
||||||
|
`, params);
|
||||||
|
|
||||||
|
return rows[0] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async loadClientAllTimeRecord(
|
||||||
|
manager: EntityManager,
|
||||||
|
payoutMode: HighScorePayoutMode,
|
||||||
|
): Promise<HighScoreRecord | null> {
|
||||||
|
const params: unknown[] = [];
|
||||||
|
const modeFilter = payoutMode === 'all'
|
||||||
|
? ''
|
||||||
|
: `AND "payoutMode" = $${params.push(payoutMode)}`;
|
||||||
|
const rows = await manager.query(`
|
||||||
|
SELECT
|
||||||
|
"bestDifficulty"::text AS "submissionDifficulty",
|
||||||
|
"updatedAt" AS "acceptedAt",
|
||||||
|
"address",
|
||||||
|
"clientName",
|
||||||
|
"userAgent" AS "protocol"
|
||||||
|
FROM "client_entity"
|
||||||
|
WHERE "bestDifficulty" IS NOT NULL
|
||||||
|
AND "bestDifficulty" > 0
|
||||||
|
${modeFilter}
|
||||||
|
ORDER BY "bestDifficulty" DESC, "updatedAt" DESC
|
||||||
|
LIMIT 1
|
||||||
|
`, params);
|
||||||
|
const row = rows[0];
|
||||||
|
if (row == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
scope: 'all_time',
|
||||||
|
payoutMode,
|
||||||
|
bucketDate: ALL_TIME_BUCKET_DATE,
|
||||||
|
submissionDifficulty: row.submissionDifficulty,
|
||||||
|
acceptedAt: row.acceptedAt ?? null,
|
||||||
|
bucket: null,
|
||||||
|
blockHeight: null,
|
||||||
|
address: row.address ?? null,
|
||||||
|
clientName: row.clientName ?? null,
|
||||||
|
protocol: row.protocol ?? null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private async loadAddressSettingsAllTimeRecord(manager: EntityManager): Promise<HighScoreRecord | null> {
|
||||||
|
const rows = await manager.query(`
|
||||||
|
SELECT
|
||||||
|
"bestDifficulty"::text AS "submissionDifficulty",
|
||||||
|
"updatedAt" AS "acceptedAt",
|
||||||
|
"address",
|
||||||
|
"bestDifficultyUserAgent" AS "protocol"
|
||||||
|
FROM "address_settings_entity"
|
||||||
|
WHERE "bestDifficulty" IS NOT NULL
|
||||||
|
AND "bestDifficulty" > 0
|
||||||
|
ORDER BY "bestDifficulty" DESC, "updatedAt" DESC
|
||||||
|
LIMIT 1
|
||||||
|
`);
|
||||||
|
const row = rows[0];
|
||||||
|
if (row == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
scope: 'all_time',
|
||||||
|
payoutMode: 'all',
|
||||||
|
bucketDate: ALL_TIME_BUCKET_DATE,
|
||||||
|
submissionDifficulty: row.submissionDifficulty,
|
||||||
|
acceptedAt: row.acceptedAt ?? null,
|
||||||
|
bucket: null,
|
||||||
|
blockHeight: null,
|
||||||
|
address: row.address ?? null,
|
||||||
|
clientName: null,
|
||||||
|
protocol: row.protocol ?? null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private async loadExactHighScore(
|
private async loadExactHighScore(
|
||||||
manager: EntityManager,
|
manager: EntityManager,
|
||||||
candidate: HighScoreCandidate,
|
candidate: HighScoreCandidate,
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { AcceptedShareHighScores1781309000000 } from './ORM/_migrations/Accepted
|
|||||||
import { UserAgentReportNonzeroHashrate1781313000000 } from './ORM/_migrations/UserAgentReportNonzeroHashrate1781313000000';
|
import { UserAgentReportNonzeroHashrate1781313000000 } from './ORM/_migrations/UserAgentReportNonzeroHashrate1781313000000';
|
||||||
import { PoolSummaryContinuousAggregate1781400000000 } from './ORM/_migrations/PoolSummaryContinuousAggregate1781400000000';
|
import { PoolSummaryContinuousAggregate1781400000000 } from './ORM/_migrations/PoolSummaryContinuousAggregate1781400000000';
|
||||||
import { PoolSummaryRefreshWindow1781401000000 } from './ORM/_migrations/PoolSummaryRefreshWindow1781401000000';
|
import { PoolSummaryRefreshWindow1781401000000 } from './ORM/_migrations/PoolSummaryRefreshWindow1781401000000';
|
||||||
|
import { AcceptedShareHighScoreNumericRetention1781402000000 } from './ORM/_migrations/AcceptedShareHighScoreNumericRetention1781402000000';
|
||||||
import { UserAgentReportView } from './ORM/_views/user-agent-report/user-agent-report.view';
|
import { UserAgentReportView } from './ORM/_views/user-agent-report/user-agent-report.view';
|
||||||
import { AcceptedShareEntity } from './ORM/accepted-share/accepted-share.entity';
|
import { AcceptedShareEntity } from './ORM/accepted-share/accepted-share.entity';
|
||||||
import { AddressSettingsEntity } from './ORM/address-settings/address-settings.entity';
|
import { AddressSettingsEntity } from './ORM/address-settings/address-settings.entity';
|
||||||
@@ -66,6 +67,7 @@ export const databaseMigrations = [
|
|||||||
UserAgentReportNonzeroHashrate1781313000000,
|
UserAgentReportNonzeroHashrate1781313000000,
|
||||||
PoolSummaryContinuousAggregate1781400000000,
|
PoolSummaryContinuousAggregate1781400000000,
|
||||||
PoolSummaryRefreshWindow1781401000000,
|
PoolSummaryRefreshWindow1781401000000,
|
||||||
|
AcceptedShareHighScoreNumericRetention1781402000000,
|
||||||
];
|
];
|
||||||
|
|
||||||
export function createDatabaseOptions(env: NodeJS.ProcessEnv): TypeOrmModuleOptions & DataSourceOptions {
|
export function createDatabaseOptions(env: NodeJS.ProcessEnv): TypeOrmModuleOptions & DataSourceOptions {
|
||||||
|
|||||||
Reference in New Issue
Block a user