Expose fallback best share in client accounting

This commit is contained in:
Ben
2026-06-08 13:47:43 -04:00
parent 8252111c32
commit 294c4a6825
2 changed files with 68 additions and 3 deletions
@@ -9,6 +9,14 @@ import { ClientController } from './client.controller';
describe('ClientController', () => { describe('ClientController', () => {
let controller: ClientController; let controller: ClientController;
let addressSettingsService: { getSettings: jest.Mock };
let shareAccountingService: {
getAddressSummary: jest.Mock;
getWorkerGroupSummary: jest.Mock;
getSessionSummary: jest.Mock;
getSessionSummaries: jest.Mock;
};
let redisMessagingService: { getClientPresenceByAddress: jest.Mock };
beforeEach(async () => { beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({ const module: TestingModule = await Test.createTestingModule({
@@ -56,9 +64,40 @@ describe('ClientController', () => {
}).compile(); }).compile();
controller = module.get<ClientController>(ClientController); controller = module.get<ClientController>(ClientController);
addressSettingsService = module.get(AddressSettingsService);
shareAccountingService = module.get(ShareAccountingService);
redisMessagingService = module.get(RedisMessagingService);
}); });
it('should be defined', () => { it('should be defined', () => {
expect(controller).toBeDefined(); expect(controller).toBeDefined();
}); });
it('should expose the existing address best difficulty in accounting when rollup best is empty', async () => {
redisMessagingService.getClientPresenceByAddress.mockResolvedValue([
{
clientId: '92f5302f-5e32-487e-af67-f56fd78b13c7',
sessionId: 'abcd1234',
clientName: 'worker',
bestDifficulty: 64,
hashRate: 1024,
startTime: '2026-06-08T12:00:00.000Z',
lastSeen: '2026-06-08T12:10:00.000Z',
},
]);
addressSettingsService.getSettings.mockResolvedValue({ bestDifficulty: 4096 });
shareAccountingService.getSessionSummaries.mockResolvedValue(new Map());
shareAccountingService.getAddressSummary.mockResolvedValue({
totalAcceptedShares: 10,
totalCreditedDifficulty: 100,
bestSubmissionDifficulty: 0,
});
await expect(controller.getClientInfo('bc1qtest')).resolves.toEqual(expect.objectContaining({
bestDifficulty: 4096,
accounting: expect.objectContaining({
bestSubmissionDifficulty: 4096,
}),
}));
});
}); });
+29 -3
View File
@@ -27,10 +27,13 @@ export class ClientController {
const addressSettings = process.env.API_ONLY === 'true' const addressSettings = process.env.API_ONLY === 'true'
? null ? null
: await this.addressSettingsService.getSettings(address, false); : await this.addressSettingsService.getSettings(address, false);
const accounting = await this.shareAccountingService.getAddressSummary(address);
const bestDifficulty = addressSettings?.bestDifficulty ?? workers.reduce((best, worker) => { const bestDifficulty = addressSettings?.bestDifficulty ?? workers.reduce((best, worker) => {
return Math.max(best, Number(worker.bestDifficulty ?? 0)); return Math.max(best, Number(worker.bestDifficulty ?? 0));
}, 0); }, 0);
const accounting = this.withBestSubmissionDifficulty(
await this.shareAccountingService.getAddressSummary(address),
bestDifficulty,
);
const response = { const response = {
bestDifficulty, bestDifficulty,
@@ -76,7 +79,10 @@ export class ClientController {
}, 0); }, 0);
const chartData = await this.clientStatisticsService.getChartDataForGroup(address, workerName); const chartData = await this.clientStatisticsService.getChartDataForGroup(address, workerName);
const accounting = await this.shareAccountingService.getWorkerGroupSummary(address, workerName); const accounting = this.withBestSubmissionDifficulty(
await this.shareAccountingService.getWorkerGroupSummary(address, workerName),
bestDifficulty,
);
const response = { const response = {
name: workerName, name: workerName,
@@ -106,7 +112,10 @@ export class ClientController {
return new NotFoundException(); return new NotFoundException();
} }
const chartData = await this.clientStatisticsService.getChartDataForSession(worker.id); const chartData = await this.clientStatisticsService.getChartDataForSession(worker.id);
const accounting = await this.shareAccountingService.getSessionSummary(worker.id); const accounting = this.withBestSubmissionDifficulty(
await this.shareAccountingService.getSessionSummary(worker.id),
worker.bestDifficulty,
);
const response = { const response = {
sessionId: worker.sessionId, sessionId: worker.sessionId,
@@ -118,4 +127,21 @@ export class ClientController {
} }
return response; return response;
} }
private withBestSubmissionDifficulty<T extends { bestSubmissionDifficulty?: number }>(
accounting: T,
fallbackBestDifficulty: unknown,
): T {
const existing = Number(accounting?.bestSubmissionDifficulty ?? 0);
const fallback = Number(fallbackBestDifficulty ?? 0);
if (!Number.isFinite(fallback) || fallback <= existing) {
return accounting;
}
return {
...accounting,
bestSubmissionDifficulty: fallback,
};
}
} }