mirror of
https://github.com/benjamin-wilson/public-pool.git
synced 2026-09-29 09:05:06 -07:00
network stats and better client hashrate estimation
This commit is contained in:
@@ -188,8 +188,7 @@ export class ClientStatisticsService {
|
|||||||
WHERE
|
WHERE
|
||||||
entry.address = ? AND entry.clientName = ? AND entry.sessionId = ?
|
entry.address = ? AND entry.clientName = ? AND entry.sessionId = ?
|
||||||
ORDER BY time DESC
|
ORDER BY time DESC
|
||||||
LIMIT 1;
|
LIMIT 2;
|
||||||
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const result = await this.clientStatisticsRepository.query(query, [address, clientName, sessionId]);
|
const result = await this.clientStatisticsRepository.query(query, [address, clientName, sessionId]);
|
||||||
@@ -198,14 +197,23 @@ export class ClientStatisticsService {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const time = new Date(result[0].updatedAt).getTime() - new Date(result[0].createdAt).getTime();
|
const latestStat = result[0];
|
||||||
|
|
||||||
if (time < 1) {
|
if (result.length < 2) {
|
||||||
return 0;
|
const time = new Date(latestStat.updatedAt).getTime() - new Date(latestStat.createdAt).getTime();
|
||||||
|
if (time < 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (latestStat.shares * 4294967296) / (time / 1000);
|
||||||
|
} else {
|
||||||
|
const secondLatestStat = result[1];
|
||||||
|
const time = new Date(latestStat.updatedAt).getTime() - new Date(secondLatestStat.createdAt).getTime();
|
||||||
|
if (time < 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ((latestStat.shares + secondLatestStat.shares) * 4294967296) / (time / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (result[0].shares * 4294967296) / (time / 1000);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getChartDataForSession(address: string, clientName: string, sessionId: string) {
|
public async getChartDataForSession(address: string, clientName: string, sessionId: string) {
|
||||||
|
|||||||
+14
-4
@@ -1,18 +1,21 @@
|
|||||||
import { CACHE_MANAGER } from '@nestjs/cache-manager';
|
import { CACHE_MANAGER } from '@nestjs/cache-manager';
|
||||||
import { Controller, Get, Inject } from '@nestjs/common';
|
import { Controller, Get, Inject } from '@nestjs/common';
|
||||||
import { Cache } from 'cache-manager';
|
import { Cache } from 'cache-manager';
|
||||||
|
import { firstValueFrom } from 'rxjs';
|
||||||
|
|
||||||
import { BlocksService } from './ORM/blocks/blocks.service';
|
import { BlocksService } from './ORM/blocks/blocks.service';
|
||||||
import { ClientStatisticsService } from './ORM/client-statistics/client-statistics.service';
|
import { ClientStatisticsService } from './ORM/client-statistics/client-statistics.service';
|
||||||
import { ClientService } from './ORM/client/client.service';
|
import { ClientService } from './ORM/client/client.service';
|
||||||
|
import { BitcoinRpcService } from './services/bitcoin-rpc.service';
|
||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
export class AppController {
|
export class AppController {
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(CACHE_MANAGER) private cacheManager: Cache,
|
@Inject(CACHE_MANAGER) private readonly cacheManager: Cache,
|
||||||
private clientService: ClientService,
|
private readonly clientService: ClientService,
|
||||||
private clientStatisticsService: ClientStatisticsService,
|
private readonly clientStatisticsService: ClientStatisticsService,
|
||||||
private blocksService: BlocksService
|
private readonly blocksService: BlocksService,
|
||||||
|
private readonly bitcoinRpcService: BitcoinRpcService
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
@Get('info')
|
@Get('info')
|
||||||
@@ -26,6 +29,13 @@ export class AppController {
|
|||||||
userAgents
|
userAgents
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get('network')
|
||||||
|
public async network() {
|
||||||
|
const miningInfo = await firstValueFrom(this.bitcoinRpcService.newBlock$);
|
||||||
|
return miningInfo;
|
||||||
|
}
|
||||||
|
|
||||||
@Get('info/chart')
|
@Get('info/chart')
|
||||||
public async infoChart() {
|
public async infoChart() {
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { ConfigService } from '@nestjs/config';
|
import { ConfigService } from '@nestjs/config';
|
||||||
import { RPCClient } from 'rpc-bitcoin';
|
import { RPCClient } from 'rpc-bitcoin';
|
||||||
import { BehaviorSubject, filter } from 'rxjs';
|
import { BehaviorSubject, filter, shareReplay } from 'rxjs';
|
||||||
|
|
||||||
import { IBlockTemplate } from '../models/bitcoin-rpc/IBlockTemplate';
|
import { IBlockTemplate } from '../models/bitcoin-rpc/IBlockTemplate';
|
||||||
import { IMiningInfo } from '../models/bitcoin-rpc/IMiningInfo';
|
import { IMiningInfo } from '../models/bitcoin-rpc/IMiningInfo';
|
||||||
@@ -12,7 +12,7 @@ export class BitcoinRpcService {
|
|||||||
private blockHeight = 0;
|
private blockHeight = 0;
|
||||||
private client: RPCClient;
|
private client: RPCClient;
|
||||||
private _newBlock$: BehaviorSubject<IMiningInfo> = new BehaviorSubject(undefined);
|
private _newBlock$: BehaviorSubject<IMiningInfo> = new BehaviorSubject(undefined);
|
||||||
public newBlock$ = this._newBlock$.pipe(filter(block => block != null));
|
public newBlock$ = this._newBlock$.pipe(filter(block => block != null), shareReplay({ refCount: true, bufferSize: 1 }));
|
||||||
|
|
||||||
constructor(private readonly configService: ConfigService) {
|
constructor(private readonly configService: ConfigService) {
|
||||||
const url = this.configService.get('BITCOIN_RPC_URL');
|
const url = this.configService.get('BITCOIN_RPC_URL');
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import * as merkle from 'merkle-lib';
|
|||||||
import * as merkleProof from 'merkle-lib/proof';
|
import * as merkleProof from 'merkle-lib/proof';
|
||||||
import { combineLatest, filter, from, interval, map, Observable, shareReplay, startWith, switchMap, tap } from 'rxjs';
|
import { combineLatest, filter, from, interval, map, Observable, shareReplay, startWith, switchMap, tap } from 'rxjs';
|
||||||
|
|
||||||
import { IBlockTemplate } from '../models/bitcoin-rpc/IBlockTemplate';
|
|
||||||
import { MiningJob } from '../models/MiningJob';
|
import { MiningJob } from '../models/MiningJob';
|
||||||
import { BitcoinRpcService } from './bitcoin-rpc.service';
|
import { BitcoinRpcService } from './bitcoin-rpc.service';
|
||||||
|
|
||||||
@@ -36,13 +35,10 @@ export class StratumV1JobsService {
|
|||||||
|
|
||||||
public blocks: { [id: number]: IJobTemplate } = {};
|
public blocks: { [id: number]: IJobTemplate } = {};
|
||||||
|
|
||||||
private currentBlockTemplate$: Observable<{ blockTemplate: IBlockTemplate }>;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly bitcoinRpcService: BitcoinRpcService
|
private readonly bitcoinRpcService: BitcoinRpcService
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|
||||||
this.newMiningJob$ = combineLatest([this.bitcoinRpcService.newBlock$, interval(60000).pipe(startWith(-1))]).pipe(
|
this.newMiningJob$ = combineLatest([this.bitcoinRpcService.newBlock$, interval(60000).pipe(startWith(-1))]).pipe(
|
||||||
switchMap(([miningInfo, interval]) => {
|
switchMap(([miningInfo, interval]) => {
|
||||||
return from(this.bitcoinRpcService.getBlockTemplate()).pipe(map((blockTemplate) => {
|
return from(this.bitcoinRpcService.getBlockTemplate()).pipe(map((blockTemplate) => {
|
||||||
@@ -102,8 +98,6 @@ export class StratumV1JobsService {
|
|||||||
// remove the first (coinbase) and last (root) element from the branch
|
// remove the first (coinbase) and last (root) element from the branch
|
||||||
const merkle_branch = merkleBranches.slice(1, merkleBranches.length).map(b => b.toString('hex'))
|
const merkle_branch = merkleBranches.slice(1, merkleBranches.length).map(b => b.toString('hex'))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
block.prevHash = prevHash;
|
block.prevHash = prevHash;
|
||||||
block.version = version;
|
block.version = version;
|
||||||
block.bits = bits;
|
block.bits = bits;
|
||||||
|
|||||||
Reference in New Issue
Block a user