network stats and better client hashrate estimation

This commit is contained in:
Ben Wilson 2023-08-03 22:37:48 -04:00
parent 3c4c35ab53
commit f907d6efe1
4 changed files with 31 additions and 19 deletions

View File

@ -188,8 +188,7 @@ export class ClientStatisticsService {
WHERE
entry.address = ? AND entry.clientName = ? AND entry.sessionId = ?
ORDER BY time DESC
LIMIT 1;
LIMIT 2;
`;
const result = await this.clientStatisticsRepository.query(query, [address, clientName, sessionId]);
@ -198,14 +197,23 @@ export class ClientStatisticsService {
return 0;
}
const time = new Date(result[0].updatedAt).getTime() - new Date(result[0].createdAt).getTime();
const latestStat = result[0];
if (time < 1) {
return 0;
if (result.length < 2) {
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) {

View File

@ -1,18 +1,21 @@
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Controller, Get, Inject } from '@nestjs/common';
import { Cache } from 'cache-manager';
import { firstValueFrom } from 'rxjs';
import { BlocksService } from './ORM/blocks/blocks.service';
import { ClientStatisticsService } from './ORM/client-statistics/client-statistics.service';
import { ClientService } from './ORM/client/client.service';
import { BitcoinRpcService } from './services/bitcoin-rpc.service';
@Controller()
export class AppController {
constructor(
@Inject(CACHE_MANAGER) private cacheManager: Cache,
private clientService: ClientService,
private clientStatisticsService: ClientStatisticsService,
private blocksService: BlocksService
@Inject(CACHE_MANAGER) private readonly cacheManager: Cache,
private readonly clientService: ClientService,
private readonly clientStatisticsService: ClientStatisticsService,
private readonly blocksService: BlocksService,
private readonly bitcoinRpcService: BitcoinRpcService
) { }
@Get('info')
@ -26,6 +29,13 @@ export class AppController {
userAgents
};
}
@Get('network')
public async network() {
const miningInfo = await firstValueFrom(this.bitcoinRpcService.newBlock$);
return miningInfo;
}
@Get('info/chart')
public async infoChart() {

View File

@ -1,7 +1,7 @@
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { RPCClient } from 'rpc-bitcoin';
import { BehaviorSubject, filter } from 'rxjs';
import { BehaviorSubject, filter, shareReplay } from 'rxjs';
import { IBlockTemplate } from '../models/bitcoin-rpc/IBlockTemplate';
import { IMiningInfo } from '../models/bitcoin-rpc/IMiningInfo';
@ -12,7 +12,7 @@ export class BitcoinRpcService {
private blockHeight = 0;
private client: RPCClient;
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) {
const url = this.configService.get('BITCOIN_RPC_URL');

View File

@ -4,7 +4,6 @@ import * as merkle from 'merkle-lib';
import * as merkleProof from 'merkle-lib/proof';
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 { BitcoinRpcService } from './bitcoin-rpc.service';
@ -36,13 +35,10 @@ export class StratumV1JobsService {
public blocks: { [id: number]: IJobTemplate } = {};
private currentBlockTemplate$: Observable<{ blockTemplate: IBlockTemplate }>;
constructor(
private readonly bitcoinRpcService: BitcoinRpcService
) {
this.newMiningJob$ = combineLatest([this.bitcoinRpcService.newBlock$, interval(60000).pipe(startWith(-1))]).pipe(
switchMap(([miningInfo, interval]) => {
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
const merkle_branch = merkleBranches.slice(1, merkleBranches.length).map(b => b.toString('hex'))
block.prevHash = prevHash;
block.version = version;
block.bits = bits;