mirror of
https://github.com/benjamin-wilson/public-pool.git
synced 2025-03-27 02:02:10 +01:00
test nonce work
This commit is contained in:
parent
edd2845829
commit
e74b2e0eb5
18
package-lock.json
generated
18
package-lock.json
generated
@ -13,6 +13,7 @@
|
||||
"@nestjs/config": "^2.3.2",
|
||||
"@nestjs/core": "^9.0.0",
|
||||
"@nestjs/platform-fastify": "^9.4.2",
|
||||
"big.js": "^6.2.1",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.14.0",
|
||||
"merkletreejs": "^0.3.10",
|
||||
@ -2856,6 +2857,18 @@
|
||||
"tweetnacl": "^0.14.3"
|
||||
}
|
||||
},
|
||||
"node_modules/big.js": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.1.tgz",
|
||||
"integrity": "sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/bigjs"
|
||||
}
|
||||
},
|
||||
"node_modules/bignumber.js": {
|
||||
"version": "9.1.1",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz",
|
||||
@ -11090,6 +11103,11 @@
|
||||
"tweetnacl": "^0.14.3"
|
||||
}
|
||||
},
|
||||
"big.js": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.1.tgz",
|
||||
"integrity": "sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ=="
|
||||
},
|
||||
"bignumber.js": {
|
||||
"version": "9.1.1",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz",
|
||||
|
@ -24,6 +24,7 @@
|
||||
"@nestjs/config": "^2.3.2",
|
||||
"@nestjs/core": "^9.0.0",
|
||||
"@nestjs/platform-fastify": "^9.4.2",
|
||||
"big.js": "^6.2.1",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.14.0",
|
||||
"merkletreejs": "^0.3.10",
|
||||
|
@ -3,6 +3,6 @@ import { Injectable } from '@nestjs/common';
|
||||
@Injectable()
|
||||
export class AppService {
|
||||
getHello(): string {
|
||||
return 'Hello World!@';
|
||||
return 'Hello World!';
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ export class MiningJob {
|
||||
public method: eResponseMethod.MINING_NOTIFY;
|
||||
public params: string[];
|
||||
|
||||
public target: string;
|
||||
public target: number;
|
||||
public merkleRoot: string;
|
||||
|
||||
public job_id: string; // ID of the job. Use this ID while submitting share generated from this job.
|
||||
@ -22,24 +22,26 @@ export class MiningJob {
|
||||
public coinb1: string; // The hex-encoded prefix of the coinbase transaction (to precede extra nonce 2).
|
||||
public coinb2: string; //The hex-encoded suffix of the coinbase transaction (to follow extra nonce 2).
|
||||
public merkle_branch: string[]; // List of hashes, will be used for calculation of merkle root. This is not a list of all transactions, it only contains prepared hashes of steps of merkle tree algorithm.
|
||||
public version: string; // The hex-encoded block version.
|
||||
public version: number; // The hex-encoded block version.
|
||||
public nbits: string; // The hex-encoded network difficulty required for the block.
|
||||
public ntime: string; // Current ntime/
|
||||
public ntime: number; // Current ntime/
|
||||
public clean_jobs: boolean; // When true, server indicates that submitting shares from previous jobs don't have a sense and such shares will be rejected. When this flag is set, miner should also drop all previous jobs too.
|
||||
|
||||
public response: string;
|
||||
|
||||
public versionMask: number;
|
||||
|
||||
constructor(blockTemplate: IBlockTemplate) {
|
||||
|
||||
console.log(blockTemplate);
|
||||
|
||||
this.job_id = randomUUID();
|
||||
this.target = blockTemplate.target;
|
||||
this.target = Number(blockTemplate.target);
|
||||
this.prevhash = blockTemplate.previousblockhash;
|
||||
|
||||
this.version = blockTemplate.version.toString();
|
||||
this.version = blockTemplate.version;
|
||||
this.nbits = blockTemplate.bits;
|
||||
this.ntime = Math.floor(new Date().getTime() / 1000).toString();
|
||||
this.ntime = Math.floor(new Date().getTime() / 1000);
|
||||
this.clean_jobs = false;
|
||||
|
||||
const transactions = blockTemplate.transactions.map(tx => tx.hash);
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { plainToInstance } from 'class-transformer';
|
||||
import { validate, ValidatorOptions } from 'class-validator';
|
||||
import { Socket } from 'net';
|
||||
import { BehaviorSubject, combineLatest, concat, merge, Observable, takeUntil } from 'rxjs';
|
||||
import { BehaviorSubject, merge, Observable, takeUntil } from 'rxjs';
|
||||
|
||||
import { EasyUnsubscribe } from '../utils/AutoUnsubscribe';
|
||||
import { eRequestMethod } from './enums/eRequestMethod';
|
||||
import { MiningJob } from './MiningJob';
|
||||
import { AuthorizationMessage } from './stratum-messages/AuthorizationMessage';
|
||||
import { ConfigurationMessage } from './stratum-messages/ConfigurationMessage';
|
||||
import { MiningSubmitMessage } from './stratum-messages/MiningSubmitMessage';
|
||||
import { SubscriptionMessage } from './stratum-messages/SubscriptionMessage';
|
||||
import { SuggestDifficulty } from './stratum-messages/SuggestDifficultyMessage';
|
||||
import { MiningJob } from './MiningJob';
|
||||
|
||||
export class StratumV1Client extends EasyUnsubscribe {
|
||||
|
||||
@ -24,6 +24,7 @@ export class StratumV1Client extends EasyUnsubscribe {
|
||||
|
||||
public onInitialized: BehaviorSubject<void> = new BehaviorSubject(null);
|
||||
public localMiningJobEmitter: BehaviorSubject<MiningJob> = new BehaviorSubject(null);
|
||||
public blockFoundEmitter: BehaviorSubject<any> = new BehaviorSubject(null);
|
||||
|
||||
|
||||
private currentJob: MiningJob;
|
||||
@ -216,8 +217,11 @@ export class StratumV1Client extends EasyUnsubscribe {
|
||||
|
||||
|
||||
private handleMiningSubmission(submission: MiningSubmitMessage) {
|
||||
const diff = submission.testNonceValue(this.currentJob, submission.nonce);
|
||||
console.log(diff);
|
||||
const networkDifficulty = 0;
|
||||
const diff = submission.testNonceValue(this.currentJob, parseInt(submission.nonce, 16));
|
||||
if (networkDifficulty < diff) {
|
||||
this.blockFoundEmitter.next(true);
|
||||
}
|
||||
}
|
||||
|
||||
// private miningNotify() {
|
||||
|
27
src/models/stratum-messages/MiningSubmitMessage.spec.ts
Normal file
27
src/models/stratum-messages/MiningSubmitMessage.spec.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { MiningJob } from '../MiningJob';
|
||||
import { MiningSubmitMessage } from './MiningSubmitMessage';
|
||||
|
||||
describe('MiningSubmitMessage', () => {
|
||||
|
||||
|
||||
beforeEach(async () => {
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
describe('root', () => {
|
||||
|
||||
const value = new MiningSubmitMessage().testNonceValue({
|
||||
version: 0x20000004,
|
||||
prevhash: "0c859545a3498373a57452fac22eb7113df2a465000543520000000000000000",
|
||||
merkleRoot: "5bdc1968499c3393873edf8e07a1c3a50a97fc3a9d1a376bbf77087dd63778eb",
|
||||
ntime: 0x647025b5,
|
||||
target: 0x1705ae3a,
|
||||
} as MiningJob, 0x0a029ed1);
|
||||
|
||||
it('should be correct difficulty', () => {
|
||||
expect(value).toEqual(683);
|
||||
});
|
||||
});
|
||||
});
|
@ -1,18 +1,17 @@
|
||||
import Big from 'big.js';
|
||||
import { ArrayMaxSize, ArrayMinSize, IsArray } from 'class-validator';
|
||||
|
||||
import { eRequestMethod } from '../enums/eRequestMethod';
|
||||
import { StratumBaseMessage } from './StratumBaseMessage';
|
||||
import { MiningJob } from '../MiningJob';
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
import { eRequestMethod } from '../enums/eRequestMethod';
|
||||
import { MiningJob } from '../MiningJob';
|
||||
import { StratumBaseMessage } from './StratumBaseMessage';
|
||||
|
||||
const trueDiffOne = Number('26959535291011309493156476344723991336010898738574164086137773096960');
|
||||
export class MiningSubmitMessage extends StratumBaseMessage {
|
||||
|
||||
@IsArray()
|
||||
@ArrayMinSize(5)
|
||||
@ArrayMaxSize(5)
|
||||
params: string[];
|
||||
public params: string[];
|
||||
|
||||
public userId: string;
|
||||
public jobId: string;
|
||||
@ -43,48 +42,60 @@ export class MiningSubmitMessage extends StratumBaseMessage {
|
||||
}
|
||||
|
||||
|
||||
testNonceValue(job: MiningJob, nonce: string): number {
|
||||
testNonceValue(job: MiningJob, nonce: number, midstateIndex: number = 0): string {
|
||||
const truediffone = Big('26959535291011309493156476344723991336010898738574164086137773096960');
|
||||
let s64: Big, ds: number;
|
||||
const header = Buffer.alloc(80);
|
||||
|
||||
// TODO: Use the midstate hash instead of hashing the whole header
|
||||
|
||||
// Copy data from job to header
|
||||
|
||||
|
||||
header.set(Buffer.from(job.version, 'hex').subarray(0, 4), 0);
|
||||
header.set(Buffer.from(job.prevhash, 'hex').subarray(0, 32), 4);
|
||||
header.set(Buffer.from(job.merkleRoot, 'hex').subarray(0, 32), 36);
|
||||
header.set(Buffer.from(job.ntime).subarray(0, 4), 68);
|
||||
header.set(Buffer.from(job.target, 'hex').subarray(0, 4), 72);
|
||||
header.set(Buffer.from(nonce, 'hex').subarray(0, 4), 76);
|
||||
|
||||
|
||||
const hashBuffer = crypto.createHash('sha256').update(header).digest();
|
||||
const hashResult = crypto.createHash('sha256').update(hashBuffer).digest();
|
||||
|
||||
const d64 = 1.0;
|
||||
const s64 = this.littleEndianToDouble(hashResult);
|
||||
const ds = d64 / s64;
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
|
||||
private littleEndianToDouble(buffer: Buffer): number {
|
||||
// Reverse the byte order to big-endian
|
||||
const reversedBytes = Buffer.from(buffer).reverse();
|
||||
|
||||
// Convert the reversed bytes to a hexadecimal string
|
||||
const hexString = `0x${reversedBytes.toString('hex')}`;
|
||||
|
||||
// Interpret the hexadecimal string as a double
|
||||
const doubleValue = Number(hexString);
|
||||
|
||||
// Check for NaN and Infinity
|
||||
if (!Number.isFinite(doubleValue)) {
|
||||
throw new Error('Conversion resulted in NaN or Infinity');
|
||||
let rolledVersion = job.version;
|
||||
for (let i = 0; i < midstateIndex; i++) {
|
||||
rolledVersion = this.incrementBitmask(rolledVersion, job.versionMask);
|
||||
}
|
||||
|
||||
return doubleValue;
|
||||
header.writeUInt32LE(rolledVersion, 0);
|
||||
Buffer.from(job.prevhash, 'hex').copy(header, 4);
|
||||
Buffer.from(job.merkleRoot, 'hex').copy(header, 36);
|
||||
header.writeUInt32LE(job.ntime, 68);
|
||||
header.writeUInt32LE(job.target, 72);
|
||||
header.writeUInt32LE(nonce, 76);
|
||||
|
||||
console.log(header);
|
||||
|
||||
const hashBuffer: Buffer = crypto.createHash('sha256').update(header).digest();
|
||||
const hashResult: Buffer = crypto.createHash('sha256').update(hashBuffer).digest();
|
||||
|
||||
s64 = this.le256todouble(hashResult);
|
||||
ds = truediffone.div(s64);
|
||||
|
||||
return ds.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private le256todouble(target: Buffer): Big {
|
||||
|
||||
const bits192 = new Big(6277101735386680763835789423207666416102355444464034512896);
|
||||
const bits128 = new Big(340282366920938463463374607431768211456);
|
||||
const bits64 = new Big(18446744073709551616);
|
||||
|
||||
const data64_3 = target.readBigUInt64LE(24);
|
||||
const data64_2 = target.readBigUInt64LE(16);
|
||||
const data64_1 = target.readBigUInt64LE(8);
|
||||
const data64_0 = target.readBigUInt64LE(0);
|
||||
|
||||
const dcut64 = new Big(data64_3).times(bits192)
|
||||
.plus(new Big(data64_2).times(bits128))
|
||||
.plus(new Big(data64_1).times(bits64))
|
||||
.plus(new Big(data64_0));
|
||||
|
||||
return dcut64;
|
||||
}
|
||||
|
||||
public incrementBitmask(rolledVersion: number, versionMask: number) {
|
||||
return (rolledVersion + 1) | versionMask;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user