From a435a9bbd86d9e228dd460f0bf569f795efe6fec Mon Sep 17 00:00:00 2001 From: Ben Wilson Date: Mon, 26 Jun 2023 20:52:00 -0400 Subject: [PATCH] cleanup and support for all address types --- package-lock.json | 145 ++++++++++++++++++ package.json | 3 + .../client-statistics.entity.ts | 4 +- .../client-statistics.service.ts | 11 ++ src/ORM/client/client.service.ts | 13 ++ src/app.controller.ts | 6 +- src/app.module.ts | 15 +- src/app.service.ts | 8 - src/models/MiningJob.ts | 28 +++- src/models/StratumV1Client.ts | 7 +- src/{ => services}/bitcoin-rpc.service.ts | 5 +- .../block-template.service.ts} | 2 +- src/services/cleanup.service.ts | 27 ++++ src/{ => services}/stratum-v1-jobs.service.ts | 2 +- src/{ => services}/stratum-v1.service.ts | 8 +- 15 files changed, 253 insertions(+), 31 deletions(-) delete mode 100644 src/app.service.ts rename src/{ => services}/bitcoin-rpc.service.ts (94%) rename src/{BlockTemplateService.ts => services/block-template.service.ts} (92%) create mode 100644 src/services/cleanup.service.ts rename src/{ => services}/stratum-v1-jobs.service.ts (91%) rename src/{ => services}/stratum-v1.service.ts (87%) diff --git a/package-lock.json b/package-lock.json index 3d6987d..d8efb6c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,8 +13,10 @@ "@nestjs/config": "^2.3.2", "@nestjs/core": "^9.0.0", "@nestjs/platform-fastify": "^9.4.2", + "@nestjs/schedule": "^3.0.1", "@nestjs/typeorm": "^10.0.0", "big.js": "^6.2.1", + "bitcoin-address-validation": "^2.2.1", "bitcoinjs-lib": "^6.1.3", "bs58": "^5.0.0", "class-transformer": "^0.5.1", @@ -31,6 +33,7 @@ "@nestjs/schematics": "^9.0.0", "@nestjs/testing": "^9.0.0", "@types/big.js": "^6.1.6", + "@types/cron": "^2.0.1", "@types/express": "^4.17.13", "@types/jest": "29.5.1", "@types/node": "18.16.12", @@ -1724,6 +1727,28 @@ } } }, + "node_modules/@nestjs/schedule": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@nestjs/schedule/-/schedule-3.0.1.tgz", + "integrity": "sha512-4CAFu4rE/QPYnz/icRg3GiuLmY1bXopG8bWTJ9d7bXzaHBaPKIjGvZ20wsK8P+MncrVCkmK0iYhQrNj0cwX9+A==", + "dependencies": { + "cron": "2.3.1", + "uuid": "9.0.0" + }, + "peerDependencies": { + "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", + "@nestjs/core": "^8.0.0 || ^9.0.0 || ^10.0.0", + "reflect-metadata": "^0.1.12" + } + }, + "node_modules/@nestjs/schedule/node_modules/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@nestjs/schematics": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-9.2.0.tgz", @@ -2058,6 +2083,16 @@ "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", "dev": true }, + "node_modules/@types/cron": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/cron/-/cron-2.0.1.tgz", + "integrity": "sha512-WHa/1rtNtD2Q/H0+YTTZoty+/5rcE66iAFX2IY+JuUoOACsevYyFkSYu/2vdw+G5LrmO7Lxowrqm0av4k3qWNQ==", + "dev": true, + "dependencies": { + "@types/luxon": "*", + "@types/node": "*" + } + }, "node_modules/@types/eslint": { "version": "8.40.1", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.1.tgz", @@ -2157,6 +2192,12 @@ "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", "dev": true }, + "node_modules/@types/luxon": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.3.0.tgz", + "integrity": "sha512-uKRI5QORDnrGFYgcdAVnHvEIvEZ8noTpP/Bg+HeUzZghwinDlIS87DEenV5r1YoOF9G4x600YsUXLWZ19rmTmg==", + "dev": true + }, "node_modules/@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", @@ -3099,6 +3140,14 @@ "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" }, + "node_modules/base58-js": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/base58-js/-/base58-js-1.0.5.tgz", + "integrity": "sha512-LkkAPP8Zu+c0SVNRTRVDyMfKVORThX+rCViget00xdgLRrKkClCTz1T7cIrpr69ShwV5XJuuoZvMvJ43yURwkA==", + "engines": { + "node": ">= 8" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -3168,6 +3217,16 @@ "node": ">=8.0.0" } }, + "node_modules/bitcoin-address-validation": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bitcoin-address-validation/-/bitcoin-address-validation-2.2.1.tgz", + "integrity": "sha512-f6LXNpvRKlTbHWb37N9tHoAbYGbshzM8FPWvCtloh++hxZ0/dmkokvKNVLz6HkG82zVwo8w6Sq4JmfO2timzyg==", + "dependencies": { + "base58-js": "^1.0.0", + "bech32": "^2.0.0", + "sha256-uint8array": "^0.10.3" + } + }, "node_modules/bitcoinjs-lib": { "version": "6.1.3", "resolved": "https://registry.npmjs.org/bitcoinjs-lib/-/bitcoinjs-lib-6.1.3.tgz", @@ -3955,6 +4014,14 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "devOptional": true }, + "node_modules/cron": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/cron/-/cron-2.3.1.tgz", + "integrity": "sha512-1eRRlIT0UfIqauwbG9pkg3J6CX9A6My2ytJWqAXoK0T9oJnUZTzGBNPxao0zjodIbPgf8UQWjE62BMb9eVllSQ==", + "dependencies": { + "luxon": "^3.2.1" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -6942,6 +7009,14 @@ "node": ">=10" } }, + "node_modules/luxon": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.3.0.tgz", + "integrity": "sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==", + "engines": { + "node": ">=12" + } + }, "node_modules/macos-release": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.1.tgz", @@ -8809,6 +8884,11 @@ "sha.js": "bin.js" } }, + "node_modules/sha256-uint8array": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/sha256-uint8array/-/sha256-uint8array-0.10.5.tgz", + "integrity": "sha512-KjYP8M6y8VvV62lnSSZwzutuwqphVOOVQamP+GmmClZcYhbq1HSIw/M2tlKgHndiaIwe3tFG5X38YYsQfUdItw==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -11604,6 +11684,22 @@ "tslib": "2.5.2" } }, + "@nestjs/schedule": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@nestjs/schedule/-/schedule-3.0.1.tgz", + "integrity": "sha512-4CAFu4rE/QPYnz/icRg3GiuLmY1bXopG8bWTJ9d7bXzaHBaPKIjGvZ20wsK8P+MncrVCkmK0iYhQrNj0cwX9+A==", + "requires": { + "cron": "2.3.1", + "uuid": "9.0.0" + }, + "dependencies": { + "uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" + } + } + }, "@nestjs/schematics": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-9.2.0.tgz", @@ -11870,6 +11966,16 @@ "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", "dev": true }, + "@types/cron": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/cron/-/cron-2.0.1.tgz", + "integrity": "sha512-WHa/1rtNtD2Q/H0+YTTZoty+/5rcE66iAFX2IY+JuUoOACsevYyFkSYu/2vdw+G5LrmO7Lxowrqm0av4k3qWNQ==", + "dev": true, + "requires": { + "@types/luxon": "*", + "@types/node": "*" + } + }, "@types/eslint": { "version": "8.40.1", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.1.tgz", @@ -11969,6 +12075,12 @@ "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", "dev": true }, + "@types/luxon": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.3.0.tgz", + "integrity": "sha512-uKRI5QORDnrGFYgcdAVnHvEIvEZ8noTpP/Bg+HeUzZghwinDlIS87DEenV5r1YoOF9G4x600YsUXLWZ19rmTmg==", + "dev": true + }, "@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", @@ -12722,6 +12834,11 @@ "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" }, + "base58-js": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/base58-js/-/base58-js-1.0.5.tgz", + "integrity": "sha512-LkkAPP8Zu+c0SVNRTRVDyMfKVORThX+rCViget00xdgLRrKkClCTz1T7cIrpr69ShwV5XJuuoZvMvJ43yURwkA==" + }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -12761,6 +12878,16 @@ "resolved": "https://registry.npmjs.org/bip174/-/bip174-2.1.0.tgz", "integrity": "sha512-lkc0XyiX9E9KiVAS1ZiOqK1xfiwvf4FXDDdkDq5crcDzOq+xGytY+14qCsqz7kCiy8rpN1CRNfacRhf9G3JNSA==" }, + "bitcoin-address-validation": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bitcoin-address-validation/-/bitcoin-address-validation-2.2.1.tgz", + "integrity": "sha512-f6LXNpvRKlTbHWb37N9tHoAbYGbshzM8FPWvCtloh++hxZ0/dmkokvKNVLz6HkG82zVwo8w6Sq4JmfO2timzyg==", + "requires": { + "base58-js": "^1.0.0", + "bech32": "^2.0.0", + "sha256-uint8array": "^0.10.3" + } + }, "bitcoinjs-lib": { "version": "6.1.3", "resolved": "https://registry.npmjs.org/bitcoinjs-lib/-/bitcoinjs-lib-6.1.3.tgz", @@ -13361,6 +13488,14 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "devOptional": true }, + "cron": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/cron/-/cron-2.3.1.tgz", + "integrity": "sha512-1eRRlIT0UfIqauwbG9pkg3J6CX9A6My2ytJWqAXoK0T9oJnUZTzGBNPxao0zjodIbPgf8UQWjE62BMb9eVllSQ==", + "requires": { + "luxon": "^3.2.1" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -15656,6 +15791,11 @@ "yallist": "^4.0.0" } }, + "luxon": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.3.0.tgz", + "integrity": "sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==" + }, "macos-release": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.1.tgz", @@ -17045,6 +17185,11 @@ "safe-buffer": "^5.0.1" } }, + "sha256-uint8array": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/sha256-uint8array/-/sha256-uint8array-0.10.5.tgz", + "integrity": "sha512-KjYP8M6y8VvV62lnSSZwzutuwqphVOOVQamP+GmmClZcYhbq1HSIw/M2tlKgHndiaIwe3tFG5X38YYsQfUdItw==" + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", diff --git a/package.json b/package.json index 347760c..1be334a 100644 --- a/package.json +++ b/package.json @@ -24,8 +24,10 @@ "@nestjs/config": "^2.3.2", "@nestjs/core": "^9.0.0", "@nestjs/platform-fastify": "^9.4.2", + "@nestjs/schedule": "^3.0.1", "@nestjs/typeorm": "^10.0.0", "big.js": "^6.2.1", + "bitcoin-address-validation": "^2.2.1", "bitcoinjs-lib": "^6.1.3", "bs58": "^5.0.0", "class-transformer": "^0.5.1", @@ -42,6 +44,7 @@ "@nestjs/schematics": "^9.0.0", "@nestjs/testing": "^9.0.0", "@types/big.js": "^6.1.6", + "@types/cron": "^2.0.1", "@types/express": "^4.17.13", "@types/jest": "29.5.1", "@types/node": "18.16.12", diff --git a/src/ORM/client-statistics/client-statistics.entity.ts b/src/ORM/client-statistics/client-statistics.entity.ts index b2bfe40..35632f8 100644 --- a/src/ORM/client-statistics/client-statistics.entity.ts +++ b/src/ORM/client-statistics/client-statistics.entity.ts @@ -1,4 +1,4 @@ -import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; +import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm'; import { DateTimeTransformer } from '../utils/DateTimeTransformer'; import { TrackedEntity } from '../utils/TrackedEntity.entity'; @@ -15,9 +15,11 @@ export class ClientStatisticsEntity extends TrackedEntity { @Column() clientName: string; + @Index() @Column({ length: 8, type: 'varchar' }) sessionId: string; + @Index() @Column({ type: 'datetime', transformer: new DateTimeTransformer() diff --git a/src/ORM/client-statistics/client-statistics.service.ts b/src/ORM/client-statistics/client-statistics.service.ts index 691c389..2ce541e 100644 --- a/src/ORM/client-statistics/client-statistics.service.ts +++ b/src/ORM/client-statistics/client-statistics.service.ts @@ -19,6 +19,17 @@ export class ClientStatisticsService { return await this.clientStatisticsRepository.save(clientStatistic); } + public async deleteOldStatistics() { + const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000); + + return await this.clientStatisticsRepository + .createQueryBuilder() + .delete() + .from(ClientStatisticsEntity) + .where('time < :time', { time: oneDayAgo }) + .execute(); + } + public async getHashRateForAddress(address: string) { const query = ` diff --git a/src/ORM/client/client.service.ts b/src/ORM/client/client.service.ts index a7bd8e7..bff0fb1 100644 --- a/src/ORM/client/client.service.ts +++ b/src/ORM/client/client.service.ts @@ -25,6 +25,19 @@ export class ClientService { return await this.clientRepository.softDelete({ sessionId }); } + public async deleteOldClients() { + + const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000); + + return await this.clientRepository + .createQueryBuilder() + .delete() + .from(ClientEntity) + .where('deletedAt < :time', { time: oneDayAgo }) + .execute(); + + } + public async updateBestDifficulty(sessionId: string, bestDifficulty: number) { return await this.clientRepository.update({ sessionId }, { bestDifficulty }); } diff --git a/src/app.controller.ts b/src/app.controller.ts index cd815d6..e6e24ed 100644 --- a/src/app.controller.ts +++ b/src/app.controller.ts @@ -1,15 +1,13 @@ import { Controller, Get, NotFoundException, Param } from '@nestjs/common'; -import { AppService } from './app.service'; import { ClientStatisticsService } from './ORM/client-statistics/client-statistics.service'; import { ClientService } from './ORM/client/client.service'; -import { StratumV1Service } from './stratum-v1.service'; + + @Controller() export class AppController { constructor( - private readonly appService: AppService, - private readonly stratumV1Service: StratumV1Service, private readonly clientService: ClientService, private readonly clientStatisticsService: ClientStatisticsService ) { } diff --git a/src/app.module.ts b/src/app.module.ts index 3e8ec26..675e6bd 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,14 +1,16 @@ import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; +import { ScheduleModule } from '@nestjs/schedule'; import { TypeOrmModule } from '@nestjs/typeorm'; import { AppController } from './app.controller'; -import { AppService } from './app.service'; -import { BitcoinRpcService } from './bitcoin-rpc.service'; -import { BlockTemplateService } from './BlockTemplateService'; import { ClientStatisticsModule } from './ORM/client-statistics/client-statistics.module'; import { ClientModule } from './ORM/client/client.module'; -import { StratumV1Service } from './stratum-v1.service'; +import { BitcoinRpcService } from './services/bitcoin-rpc.service'; +import { BlockTemplateService } from './services/block-template.service'; +import { CleanupService } from './services/cleanup.service'; +import { StratumV1Service } from './services/stratum-v1.service'; + const ORMModules = [ ClientStatisticsModule, @@ -23,12 +25,15 @@ const ORMModules = [ database: './DB/public-pool.sqlite', synchronize: true, autoLoadEntities: true, + logging: false }), + ScheduleModule.forRoot(), ...ORMModules ], controllers: [AppController], providers: [ - AppService, + + CleanupService, StratumV1Service, BitcoinRpcService, BlockTemplateService diff --git a/src/app.service.ts b/src/app.service.ts deleted file mode 100644 index 927d7cc..0000000 --- a/src/app.service.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -@Injectable() -export class AppService { - getHello(): string { - return 'Hello World!'; - } -} diff --git a/src/models/MiningJob.ts b/src/models/MiningJob.ts index 717d5ba..6e76b63 100644 --- a/src/models/MiningJob.ts +++ b/src/models/MiningJob.ts @@ -1,3 +1,4 @@ +import { AddressType, getAddressInfo } from 'bitcoin-address-validation'; import * as bitcoinjs from 'bitcoinjs-lib'; import * as crypto from 'crypto'; import { MerkleTree } from 'merkletreejs'; @@ -134,10 +135,9 @@ export class MiningJob { let rewardBalance = reward; addresses.forEach(recipientAddress => { - const scriptPubKey = bitcoinjs.payments.p2wpkh({ address: recipientAddress.address, network: bitcoinjs.networks.testnet }); const amount = Math.floor((recipientAddress.percent / 100) * reward); rewardBalance -= amount; - coinbaseTransaction.addOutput(scriptPubKey.output, amount); + coinbaseTransaction.addOutput(this.getPaymentScript(recipientAddress.address), amount); }) //Add any remaining sats from the Math.floor @@ -151,6 +151,30 @@ export class MiningJob { return coinbaseTransaction; } + private getPaymentScript(address: string): Buffer { + const addressInfo = getAddressInfo(address); + switch (addressInfo.type) { + case AddressType.p2wpkh: { + return bitcoinjs.payments.p2wpkh({ address, network: bitcoinjs.networks.testnet }).output; + } + case AddressType.p2pkh: { + return bitcoinjs.payments.p2pkh({ address }).output;; + } + case AddressType.p2sh: { + return bitcoinjs.payments.p2sh({ address }).output;; + } + case AddressType.p2tr: { + return bitcoinjs.payments.p2tr({ address }).output;; + } + case AddressType.p2wsh: { + return bitcoinjs.payments.p2wsh({ address }).output; + } + default: { + return Buffer.alloc(0); + } + } + } + private sha256(data) { return crypto.createHash('sha256').update(data).digest() } diff --git a/src/models/StratumV1Client.ts b/src/models/StratumV1Client.ts index 63d241b..c1c9e90 100644 --- a/src/models/StratumV1Client.ts +++ b/src/models/StratumV1Client.ts @@ -5,12 +5,12 @@ 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 { ClientStatisticsService } from '../ORM/client-statistics/client-statistics.service'; import { ClientEntity } from '../ORM/client/client.entity'; import { ClientService } from '../ORM/client/client.service'; -import { StratumV1JobsService } from '../stratum-v1-jobs.service'; +import { BitcoinRpcService } from '../services/bitcoin-rpc.service'; +import { BlockTemplateService } from '../services/block-template.service'; +import { StratumV1JobsService } from '../services/stratum-v1-jobs.service'; import { EasyUnsubscribe } from '../utils/AutoUnsubscribe'; import { eRequestMethod } from './enums/eRequestMethod'; import { MiningJob } from './MiningJob'; @@ -22,6 +22,7 @@ import { SuggestDifficulty } from './stratum-messages/SuggestDifficultyMessage'; import { StratumV1ClientStatistics } from './StratumV1ClientStatistics'; + export class StratumV1Client extends EasyUnsubscribe { private clientSubscription: SubscriptionMessage; diff --git a/src/bitcoin-rpc.service.ts b/src/services/bitcoin-rpc.service.ts similarity index 94% rename from src/bitcoin-rpc.service.ts rename to src/services/bitcoin-rpc.service.ts index 367dd1a..49260e3 100644 --- a/src/bitcoin-rpc.service.ts +++ b/src/services/bitcoin-rpc.service.ts @@ -3,8 +3,9 @@ import { ConfigService } from '@nestjs/config'; import { RPCClient } from 'rpc-bitcoin'; import { BehaviorSubject, filter } from 'rxjs'; -import { IBlockTemplate } from './models/bitcoin-rpc/IBlockTemplate'; -import { IMiningInfo } from './models/bitcoin-rpc/IMiningInfo'; +import { IBlockTemplate } from '../models/bitcoin-rpc/IBlockTemplate'; +import { IMiningInfo } from '../models/bitcoin-rpc/IMiningInfo'; + @Injectable() diff --git a/src/BlockTemplateService.ts b/src/services/block-template.service.ts similarity index 92% rename from src/BlockTemplateService.ts rename to src/services/block-template.service.ts index 5e17da3..684cb74 100644 --- a/src/BlockTemplateService.ts +++ b/src/services/block-template.service.ts @@ -1,8 +1,8 @@ import { Injectable } from '@nestjs/common'; import { from, map, Observable, shareReplay, switchMap, tap } from 'rxjs'; +import { IBlockTemplate } from '../models/bitcoin-rpc/IBlockTemplate'; import { BitcoinRpcService } from './bitcoin-rpc.service'; -import { IBlockTemplate } from './models/bitcoin-rpc/IBlockTemplate'; @Injectable() export class BlockTemplateService { diff --git a/src/services/cleanup.service.ts b/src/services/cleanup.service.ts new file mode 100644 index 0000000..cb23bca --- /dev/null +++ b/src/services/cleanup.service.ts @@ -0,0 +1,27 @@ +import { Injectable, OnModuleInit } from '@nestjs/common'; +import { Cron, CronExpression } from '@nestjs/schedule'; + +import { ClientStatisticsService } from '../ORM/client-statistics/client-statistics.service'; +import { ClientService } from '../ORM/client/client.service'; + +@Injectable() +export class CleanupService implements OnModuleInit { + + constructor( + private clientStatisticsService: ClientStatisticsService, + private clientService: ClientService + ) { + + } + onModuleInit() { + console.log('Cleanup service running.') + } + + @Cron(CronExpression.EVERY_HOUR) + private async deleteOldStatistics() { + const deletedStatistics = await this.clientStatisticsService.deleteOldStatistics(); + console.log(`Deleted ${deletedStatistics.affected} old statistics`); + const deletedClients = await this.clientService.deleteOldClients(); + console.log(`Deleted ${deletedClients.affected} old clients`); + } +} \ No newline at end of file diff --git a/src/stratum-v1-jobs.service.ts b/src/services/stratum-v1-jobs.service.ts similarity index 91% rename from src/stratum-v1-jobs.service.ts rename to src/services/stratum-v1-jobs.service.ts index 3184a59..e59d09d 100644 --- a/src/stratum-v1-jobs.service.ts +++ b/src/services/stratum-v1-jobs.service.ts @@ -1,4 +1,4 @@ -import { MiningJob } from './models/MiningJob'; +import { MiningJob } from '../models/MiningJob'; export class StratumV1JobsService { diff --git a/src/stratum-v1.service.ts b/src/services/stratum-v1.service.ts similarity index 87% rename from src/stratum-v1.service.ts rename to src/services/stratum-v1.service.ts index 9047ac3..53125df 100644 --- a/src/stratum-v1.service.ts +++ b/src/services/stratum-v1.service.ts @@ -1,11 +1,11 @@ import { Injectable, OnModuleInit } from '@nestjs/common'; import { Server, Socket } from 'net'; +import { StratumV1Client } from '../models/StratumV1Client'; +import { ClientStatisticsService } from '../ORM/client-statistics/client-statistics.service'; +import { ClientService } from '../ORM/client/client.service'; import { BitcoinRpcService } from './bitcoin-rpc.service'; -import { BlockTemplateService } from './BlockTemplateService'; -import { StratumV1Client } from './models/StratumV1Client'; -import { ClientStatisticsService } from './ORM/client-statistics/client-statistics.service'; -import { ClientService } from './ORM/client/client.service'; +import { BlockTemplateService } from './block-template.service'; import { StratumV1JobsService } from './stratum-v1-jobs.service';