fix possible dup work on diff change

This commit is contained in:
Ben
2026-06-05 09:51:06 -04:00
parent 4cab56a1a0
commit f2d2283b47
3 changed files with 65 additions and 4 deletions
@@ -12,6 +12,7 @@ describe('StratumV1JobsService', () => {
const createTemplate = (height = MockRecording1.BLOCK_TEMPLATE.height): IBlockTemplate => ({
...MockRecording1.BLOCK_TEMPLATE,
transactions: MockRecording1.BLOCK_TEMPLATE.transactions.map(tx => ({ ...tx })),
height
});
@@ -62,6 +63,34 @@ describe('StratumV1JobsService', () => {
expect(service.getJobTemplateById(jobTemplate.blockData.id)).toBe(jobTemplate);
});
it('should skip identical non-clean template refreshes', async () => {
await firstValueFrom(service.newMiningJob$);
blockTemplate$.next(createTemplate());
expect(service.latestJobTemplateId).toBe(2);
expect(Object.keys(service.blocks)).toHaveLength(1);
});
it('should emit when transaction identity changes without changing transaction count', async () => {
await firstValueFrom(service.newMiningJob$);
const reorderedTemplate = createTemplate();
reorderedTemplate.transactions = [
reorderedTemplate.transactions[1],
reorderedTemplate.transactions[0],
...reorderedTemplate.transactions.slice(2)
];
const nextTemplate = firstValueFrom(service.newMiningJob$.pipe(skip(1)));
blockTemplate$.next(reorderedTemplate);
const jobTemplate = await nextTemplate;
expect(jobTemplate.blockData.clearJobs).toBe(false);
expect(jobTemplate.blockData.id).toBe('2');
expect(service.getJobTemplateById(jobTemplate.blockData.id)).toBe(jobTemplate);
});
it('should age old jobs and templates after five minutes', async () => {
await firstValueFrom(service.newMiningJob$);
const oldCreation = Date.now() - (1000 * 60 * 11);
@@ -71,6 +100,7 @@ describe('StratumV1JobsService', () => {
} as any;
bitcoinRpcService.miningInfo.blocks = MockRecording1.BLOCK_TEMPLATE.height;
jest.setSystemTime(new Date(Date.now() + 1000));
const nextTemplate = firstValueFrom(service.newMiningJob$.pipe(skip(1)));
blockTemplate$.next(createTemplate());
const jobTemplate = await nextTemplate;
+18 -1
View File
@@ -31,6 +31,7 @@ export class StratumV1JobsService {
public blocks: { [id: number]: IJobTemplate } = {};
private lastBlockHeight = 0;
private lastWorkSignature: string;
constructor(
private readonly bitcoinRpcService: BitcoinRpcService
@@ -53,13 +54,29 @@ export class StratumV1JobsService {
}
const currentTime = Math.floor(new Date().getTime() / 1000);
const timestamp = blockTemplate.mintime > currentTime ? blockTemplate.mintime : currentTime;
const workSignature = [
blockTemplate.previousblockhash,
blockTemplate.version,
blockTemplate.bits,
timestamp,
blockTemplate.height,
blockTemplate.coinbasevalue,
...blockTemplate.transactions.map(tx => tx.hash ?? tx.txid ?? tx.data)
].join('|');
if (!clearJobs && workSignature === this.lastWorkSignature) {
return null;
}
this.lastWorkSignature = workSignature;
return {
version: blockTemplate.version,
bits: parseInt(blockTemplate.bits, 16),
prevHash: this.convertToLittleEndian(blockTemplate.previousblockhash),
transactions: blockTemplate.transactions.map(t => bitcoinjs.Transaction.fromHex(t.data)),
coinbasevalue: blockTemplate.coinbasevalue,
timestamp: blockTemplate.mintime > currentTime ? blockTemplate.mintime : currentTime,
timestamp,
networkDifficulty: this.calculateNetworkDifficulty(parseInt(blockTemplate.bits, 16)),
clearJobs,
height: blockTemplate.height