diff --git a/src/bitcoin-rpc.service.ts b/src/bitcoin-rpc.service.ts index eb1de45..46b5e05 100644 --- a/src/bitcoin-rpc.service.ts +++ b/src/bitcoin-rpc.service.ts @@ -65,9 +65,15 @@ export class BitcoinRpcService { } public async SUBMIT_BLOCK(hexdata: string) { - await this.client.submitblock({ - hexdata - }); + try { + const res = await this.client.submitblock({ + hexdata + }); + console.log(`BLOCK SUBMISSION RESPONSE: ${res}`); + } catch (e) { + console.log(`BLOCK SUBMISSION RESPONSE ERROR: ${e}`); + } + } } diff --git a/src/models/StratumV1Client.ts b/src/models/StratumV1Client.ts index 6018574..f61432f 100644 --- a/src/models/StratumV1Client.ts +++ b/src/models/StratumV1Client.ts @@ -1,9 +1,11 @@ +import { Block, Transaction } from 'bitcoinjs-lib'; import { plainToInstance } from 'class-transformer'; import { validate, ValidatorOptions } from 'class-validator'; import * as crypto from 'crypto'; import { Socket } from 'net'; import { combineLatest, interval, startWith } from 'rxjs'; +import { BitcoinRpcService } from '../bitcoin-rpc.service'; import { BlockTemplateService } from '../BlockTemplateService'; import { StratumV1JobsService } from '../stratum-v1-jobs.service'; import { EasyUnsubscribe } from '../utils/AutoUnsubscribe'; @@ -38,7 +40,8 @@ export class StratumV1Client extends EasyUnsubscribe { constructor( public readonly socket: Socket, private readonly stratumV1JobsService: StratumV1JobsService, - private readonly blockTemplateService: BlockTemplateService + private readonly blockTemplateService: BlockTemplateService, + private readonly bitcoinRpcService: BitcoinRpcService ) { super(); this.id = this.getRandomHexString(); @@ -234,14 +237,34 @@ export class StratumV1Client extends EasyUnsubscribe { const diff = submission.calculateDifficulty(this.id, job, submission); console.log(`DIFF: ${diff}`); if (diff >= this.clientDifficulty) { - if (diff >= job.networkDifficulty) { console.log('!!! BOCK FOUND !!!'); + this.constructBlockAndBroadcast(job, submission); } } else { console.log(`Difficulty too low`); } + } + + private constructBlockAndBroadcast(job: MiningJob, submission: MiningSubmitMessage) { + const block = new Block(); + + block.version = job.blockTemplate.version; + block.prevHash = Buffer.from(job.prevhash, 'hex'); + block.merkleRoot = Buffer.from(job.merkleRoot, 'hex'); + block.timestamp = job.ntime; + block.bits = job.nbits; + block.nonce = parseInt(submission.nonce, 16); + block.transactions = job.blockTemplate.transactions.map(tx => { + return Transaction.fromHex(tx.data); + }); + + const coinbaseTx = `${job.coinb1}${this.id}${submission.extraNonce2}${job.coinb2}`; + block.transactions.unshift(Transaction.fromHex(coinbaseTx)); + + const blockHex = block.toHex(false); + this.bitcoinRpcService.SUBMIT_BLOCK(blockHex); } diff --git a/src/stratum-v1.service.ts b/src/stratum-v1.service.ts index a15b946..3e05edd 100644 --- a/src/stratum-v1.service.ts +++ b/src/stratum-v1.service.ts @@ -37,7 +37,7 @@ export class StratumV1Service implements OnModuleInit { console.log('New client connected:', socket.remoteAddress); - const client = new StratumV1Client(socket, new StratumV1JobsService(), this.blockTemplateService); + const client = new StratumV1Client(socket, new StratumV1JobsService(), this.blockTemplateService, this.bitcoinRpcService); this.clients.push(client);