mirror of
https://github.com/benjamin-wilson/public-pool.git
synced 2026-09-29 17:15:03 -07:00
optimize share submission path
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import Big from 'big.js';
|
||||
import * as bitcoinjs from 'bitcoinjs-lib';
|
||||
import { plainToInstance } from 'class-transformer';
|
||||
import { validate, ValidatorOptions } from 'class-validator';
|
||||
@@ -29,6 +28,8 @@ import { EXTRANONCE1_SIZE_BYTES } from './stratum.constants';
|
||||
import { SuggestDifficulty } from './stratum-messages/SuggestDifficultyMessage';
|
||||
import { StratumV1ClientStatistics } from './StratumV1ClientStatistics';
|
||||
|
||||
const TRUE_DIFF_ONE = 2.695953529101131e67;
|
||||
|
||||
export function effectiveJobDifficulty(
|
||||
jobIdInt: number,
|
||||
currentDiff: number,
|
||||
@@ -481,46 +482,28 @@ export class StratumV1Client {
|
||||
}
|
||||
|
||||
|
||||
private async handleMiningSubmission(submission: MiningSubmitMessage) {
|
||||
private async ensureClientEntity() {
|
||||
if (this.clientEntity != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.clientEntity == null) {
|
||||
if (this.creatingEntity == null) {
|
||||
this.creatingEntity = new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
this.clientEntity = await this.clientService.insert({
|
||||
sessionId: this.extraNonceAndSessionId,
|
||||
address: this.clientAuthorization.address,
|
||||
clientName: this.clientAuthorization.worker,
|
||||
userAgent: this.clientSubscription.userAgent,
|
||||
startTime: new Date(),
|
||||
bestDifficulty: 0
|
||||
});
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
resolve();
|
||||
if (this.creatingEntity == null) {
|
||||
this.creatingEntity = (async () => {
|
||||
this.clientEntity = await this.clientService.insert({
|
||||
sessionId: this.extraNonceAndSessionId,
|
||||
address: this.clientAuthorization.address,
|
||||
clientName: this.clientAuthorization.worker,
|
||||
userAgent: this.clientSubscription.userAgent,
|
||||
startTime: new Date(),
|
||||
bestDifficulty: 0
|
||||
});
|
||||
await this.creatingEntity;
|
||||
|
||||
} else {
|
||||
await this.creatingEntity;
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
const submissionHash = submission.hash();
|
||||
if(this.miningSubmissionHashes.has(submissionHash)){
|
||||
const err = new StratumErrorMessage(
|
||||
submission.id,
|
||||
eStratumErrorCode.DuplicateShare,
|
||||
'Duplicate share').response();
|
||||
const success = await this.write(err);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}else{
|
||||
this.miningSubmissionHashes.add(submissionHash);
|
||||
}
|
||||
await this.creatingEntity;
|
||||
}
|
||||
|
||||
private async handleMiningSubmission(submission: MiningSubmitMessage) {
|
||||
|
||||
const job = this.stratumV1JobsService.getJobById(submission.jobId);
|
||||
|
||||
@@ -565,17 +548,40 @@ export class StratumV1Client {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
const updatedJobBlock = job.copyAndUpdateBlock(
|
||||
const submissionHash = [
|
||||
submission.jobId,
|
||||
submission.extraNonce2,
|
||||
submission.ntime,
|
||||
submission.nonce,
|
||||
submission.versionMask ?? ''
|
||||
].join(':');
|
||||
if (this.miningSubmissionHashes.has(submissionHash)) {
|
||||
const err = new StratumErrorMessage(
|
||||
submission.id,
|
||||
eStratumErrorCode.DuplicateShare,
|
||||
'Duplicate share').response();
|
||||
const success = await this.write(err);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
this.miningSubmissionHashes.add(submissionHash);
|
||||
}
|
||||
|
||||
const versionMask = parseInt(submission.versionMask, 16);
|
||||
const nonce = parseInt(submission.nonce, 16);
|
||||
const timestamp = parseInt(submission.ntime, 16);
|
||||
|
||||
const header = job.buildHeaderBuffer(
|
||||
jobTemplate,
|
||||
parseInt(submission.versionMask, 16),
|
||||
parseInt(submission.nonce, 16),
|
||||
versionMask,
|
||||
nonce,
|
||||
this.extraNonceAndSessionId,
|
||||
submission.extraNonce2,
|
||||
parseInt(submission.ntime, 16)
|
||||
timestamp
|
||||
);
|
||||
const header = updatedJobBlock.toBuffer(true);
|
||||
const { submissionDifficulty } = this.calculateDifficulty(header);
|
||||
|
||||
//console.log(`DIFF: ${submissionDifficulty} of ${this.sessionDifficulty} from ${this.clientAuthorization.worker + '.' + this.extraNonceAndSessionId}`);
|
||||
@@ -588,9 +594,21 @@ export class StratumV1Client {
|
||||
|
||||
|
||||
if (submissionDifficulty >= effectiveDiff) {
|
||||
const success = await this.write(JSON.stringify(submission.response()) + '\n');
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (submissionDifficulty >= jobTemplate.blockData.networkDifficulty) {
|
||||
console.log('!!! BLOCK FOUND !!!');
|
||||
const updatedJobBlock = job.copyAndUpdateBlock(
|
||||
jobTemplate,
|
||||
versionMask,
|
||||
nonce,
|
||||
this.extraNonceAndSessionId,
|
||||
submission.extraNonce2,
|
||||
timestamp
|
||||
);
|
||||
const blockHex = updatedJobBlock.toHex(false);
|
||||
const result = await this.bitcoinRpcService.SUBMIT_BLOCK(blockHex);
|
||||
if (result === 'SUCCESS!') {
|
||||
@@ -608,12 +626,13 @@ export class StratumV1Client {
|
||||
console.warn(`[Block submit rejected at height ${jobTemplate.blockData.height}]: ${result}`);
|
||||
}
|
||||
}
|
||||
await this.ensureClientEntity();
|
||||
try {
|
||||
await this.statistics.addShares(this.clientEntity, effectiveDiff);
|
||||
const now = new Date();
|
||||
// only update every minute
|
||||
//if (this.clientEntity.updatedAt == null || now.getTime() - this.clientEntity.updatedAt.getTime() > 1000 * 60) {
|
||||
await this.clientService.heartbeatBulkAsync(this.clientEntity.id, this.statistics.hashRate, now);
|
||||
this.clientService.heartbeatBulkAsync(this.clientEntity.id, this.statistics.hashRate, now);
|
||||
this.clientEntity.updatedAt = now;
|
||||
//}
|
||||
|
||||
@@ -622,11 +641,9 @@ export class StratumV1Client {
|
||||
}
|
||||
|
||||
if (submissionDifficulty > this.clientEntity.bestDifficulty) {
|
||||
await this.clientService.updateBestDifficulty(this.clientEntity.id, submissionDifficulty);
|
||||
await this.clientService.updateBestDifficultyIfHigher(this.clientEntity.id, submissionDifficulty);
|
||||
this.clientEntity.bestDifficulty = submissionDifficulty;
|
||||
if (submissionDifficulty > (await this.addressSettingsService.getSettings(this.clientAuthorization.address, true)).bestDifficulty) {
|
||||
await this.addressSettingsService.updateBestDifficulty(this.clientAuthorization.address, submissionDifficulty, this.clientEntity.userAgent);
|
||||
}
|
||||
await this.addressSettingsService.updateBestDifficultyIfHigher(this.clientAuthorization.address, submissionDifficulty, this.clientEntity.userAgent);
|
||||
}
|
||||
|
||||
|
||||
@@ -646,7 +663,7 @@ export class StratumV1Client {
|
||||
}
|
||||
|
||||
//await this.checkDifficulty();
|
||||
return true;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@@ -689,20 +706,18 @@ export class StratumV1Client {
|
||||
|
||||
const hashResult = bitcoinjs.crypto.hash256(header);
|
||||
|
||||
let s64 = this.le256todouble(hashResult);
|
||||
|
||||
const truediffone = Big('26959535291011309493156476344723991336010898738574164086137773096960');
|
||||
const difficulty = truediffone.div(s64.toString());
|
||||
return { submissionDifficulty: difficulty.toNumber(), submissionHash: hashResult.toString('hex') };
|
||||
const target = this.le256todouble(hashResult);
|
||||
const submissionDifficulty = target === 0 ? Number.POSITIVE_INFINITY : TRUE_DIFF_ONE / target;
|
||||
return { submissionDifficulty, submissionHash: hashResult.toString('hex') };
|
||||
}
|
||||
|
||||
|
||||
private le256todouble(target: Buffer): bigint {
|
||||
private le256todouble(target: Buffer): number {
|
||||
|
||||
const number = target.reduceRight((acc, byte) => {
|
||||
// Shift the number 8 bits to the left and OR with the current byte
|
||||
return (acc << BigInt(8)) | BigInt(byte);
|
||||
}, BigInt(0));
|
||||
let number = 0;
|
||||
for (let i = target.length - 1; i >= 0; i--) {
|
||||
number = number * 256 + target[i];
|
||||
}
|
||||
|
||||
return number;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user