mirror of
https://github.com/everoddandeven/monerod-gui.git
synced 2025-03-12 09:30:30 +00:00
Mining operations implementation
This commit is contained in:
parent
0d78976e1d
commit
3ca4c45923
3 changed files with 461 additions and 62 deletions
|
@ -342,18 +342,26 @@ export class DaemonService {
|
|||
public async submitBlock(... blockBlobData: string[]): Promise<void> {
|
||||
const response = await this.callRpc(new SubmitBlockRequest(blockBlobData));
|
||||
|
||||
if (response.error) {
|
||||
if (!response.message) {
|
||||
throw new Error(`Error code: ${response.code}`);
|
||||
if (response.result && typeof response.result.status == 'string' && response.result.status != 'OK') {
|
||||
if (response.result.status == 'BUSY') {
|
||||
throw new CoreIsBusyError();
|
||||
}
|
||||
|
||||
throw new Error(response.message);
|
||||
throw new Error(response.result.status);
|
||||
}
|
||||
}
|
||||
|
||||
public async generateBlocks(amountOfBlocks: number, walletAddress: string, prevBlock: string = '', startingNonce: number): Promise<GeneratedBlocks> {
|
||||
const response = await this.callRpc(new GenerateBlocksRequest(amountOfBlocks, walletAddress, prevBlock, startingNonce));
|
||||
|
||||
if(response.result && response.result.status != 'OK') {
|
||||
if (response.result.status == 'BUSY') {
|
||||
throw new CoreIsBusyError();
|
||||
}
|
||||
|
||||
throw new Error(response.result.status);
|
||||
}
|
||||
|
||||
return GeneratedBlocks.parse(response.result);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,76 +11,339 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!coreBusy && daemonRunning" class="tab-content" id="pills-tabContent">
|
||||
<div class="tab-pane fade show active" id="pills-miner-data" role="tabpanel" aria-labelledby="pills-miner-data-tab" tabindex="0">
|
||||
<div class="row d-flex justify-content-center">
|
||||
|
||||
@for(card of cards; track card.header) {
|
||||
<div class="card text-bg-dark m-3 text-center" style="max-width: 18rem;">
|
||||
<div class="card-header">{{card.header}}</div>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{card.content}}</h5>
|
||||
</div>
|
||||
<div *ngIf="daemonRunning" class="tab-content" id="pills-tabContent">
|
||||
<div class="tab-pane fade show active" id="pills-mining-status" role="tabpanel" aria-labelledby="pills-mining-status-tab" tabindex="0">
|
||||
<div *ngIf="miningStatusLoading">
|
||||
<!-- Placeholder per il caricamento -->
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title placeholder-glow">
|
||||
<span class="placeholder col-6"></span>
|
||||
</h5>
|
||||
<p class="card-text placeholder-glow">
|
||||
<span class="placeholder col-7"></span>
|
||||
<span class="placeholder col-4"></span>
|
||||
<span class="placeholder col-4"></span>
|
||||
<span class="placeholder col-6"></span>
|
||||
<span class="placeholder col-8"></span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="miningStatus" class="card">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h4>Mining Status</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{ miningStatus.active ? 'Mining Active' : 'Mining Inactive' }}</h5>
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item">
|
||||
<strong>Address:</strong> {{ miningStatus.address }}
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<strong>Background Idle Threshold:</strong> {{ miningStatus.bgIdleThreshold }}%
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<strong>Background Min Idle Seconds:</strong> {{ miningStatus.bgMinIdleSeconds }} seconds
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<strong>Background Target:</strong> {{ miningStatus.bgTarget }}
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<strong>Block Reward:</strong> {{ miningStatus.blockReward }}
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<strong>Block Target:</strong> {{ miningStatus.blockTarget }}
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<strong>Difficulty:</strong> {{ miningStatus.difficulty }} (Top 64: {{ miningStatus.difficultyTop64 }})
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<strong>Is Background Mining Enabled:</strong> {{ miningStatus.isBackgroundMiningEnabled ? 'Yes' : 'No' }}
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<strong>PoW Algorithm:</strong> {{ miningStatus.powAlgorithm }}
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<strong>Speed:</strong> {{ miningStatus.speed }} H/s
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<strong>Threads Count:</strong> {{ miningStatus.threadsCount }}
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<strong>Wide Difficulty:</strong> {{ miningStatus.wideDifficulty }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-miner-data" role="tabpanel" aria-labelledby="pills-miner-data-tab" tabindex="0">
|
||||
<div *ngIf="coreBusy" class="alert alert-danger d-flex align-items-center justify-content-center text-center" role="alert">
|
||||
<h4><i class="bi bi-exclamation-triangle m-2"></i></h4>
|
||||
<div>
|
||||
Core is busy: miner data is not available during blockchain sync
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="!coreBusy && daemonRunning" class="row d-flex justify-content-center">
|
||||
|
||||
@for(card of cards; track card.header) {
|
||||
<div class="card text-bg-dark m-3 text-center" style="max-width: 18rem;">
|
||||
<div class="card-header">{{card.header}}</div>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{card.content}}</h5>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="tab-pane fade" id="pills-alternate-chains" role="tabpanel" aria-labelledby="pills-alternate-chains-tab" tabindex="0">
|
||||
<div class="m-3">
|
||||
<table
|
||||
id="chainsTable"
|
||||
data-toggle="chainsTable"
|
||||
data-toolbar="#toolbar"
|
||||
data-height="460"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-field="blockHash">Block Hash</th>
|
||||
<th data-field="height">Height</th>
|
||||
<th data-field="length">Length</th>
|
||||
<th data-field="mainChainParentBlock">Main Chain Parent Block</th>
|
||||
<th data-field="wideDifficulty">Wide Difficulty</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="pills-alternate-chains" role="tabpanel" aria-labelledby="pills-alternate-chains-tab" tabindex="0">
|
||||
<div class="m-3">
|
||||
<table
|
||||
id="chainsTable"
|
||||
data-toggle="chainsTable"
|
||||
data-toolbar="#toolbar"
|
||||
data-height="460"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-field="blockHash">Block Hash</th>
|
||||
<th data-field="height">Height</th>
|
||||
<th data-field="length">Length</th>
|
||||
<th data-field="mainChainParentBlock">Main Chain Parent Block</th>
|
||||
<th data-field="wideDifficulty">Wide Difficulty</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-block-template" role="tabpanel" aria-labelledby="pills-block-template-tab" tabindex="0">
|
||||
<div *ngIf="getBlockTemplateError != ''" class="alert alert-danger d-flex align-items-center justify-content-center text-center" role="alert">
|
||||
<h4><i class="bi bi-exclamation-triangle m-2"></i></h4>
|
||||
<div>
|
||||
{{ getBlockTemplateError }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-block-template" role="tabpanel" aria-labelledby="pills-block-template-tab" tabindex="0">
|
||||
<div class="input-group flex-nowrap m-4">
|
||||
<span class="input-group-text" id="addon-wrapping">Address</span>
|
||||
<input type="text" class="form-control" aria-label="Address" aria-describedby="addon-wrapping">
|
||||
<div class="row g-5 p-2">
|
||||
<div class="cold-md-7 col-lg-12">
|
||||
<div class="row gy-3">
|
||||
|
||||
<div class="col-sm-9">
|
||||
<label for="get-block-template-address" class="form-label">Address</label>
|
||||
<input type="text" class="form-control" id="get-block-template-address" placeholder="" [(ngModel)]="getBlockTemplateAddress" [ngModelOptions]="{standalone: true}" required="">
|
||||
<small class="text-body-secondary">Address of wallet to receive coinbase transactions if block is successfully mined</small>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3">
|
||||
<label for="get-block-header-reserve-size" class="form-label">Reserve size</label>
|
||||
<input type="number" class="form-control" min="0" id="get-block-header-reserve-size" placeholder="" [(ngModel)]="getBlockTemplateReserveSize" [ngModelOptions]="{standalone: true}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-4">
|
||||
|
||||
<button *ngIf="!gettingBlockTemplate" class="w-100 btn btn-primary btn-lg" type="button" (click)="getBlockTemplate()">Get Block Template</button>
|
||||
<button *ngIf="gettingBlockTemplate" class="w-100 btn btn-primary btn-lg" type="button" disabled>Getting Block Template ...</button>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-calc-pow" role="tabpanel" aria-labelledby="pills-calc-pow-tab" tabindex="0">
|
||||
<div *ngIf="calcPowError != ''" class="alert alert-danger d-flex align-items-center justify-content-center text-center" role="alert">
|
||||
<h4><i class="bi bi-exclamation-triangle m-2"></i></h4>
|
||||
<div>
|
||||
{{ calcPowError }}
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="calculatedPowHash != ''" class="alert alert-success d-flex align-items-center justify-content-center text-center" role="alert">
|
||||
<h4><i class="bi bi-check-circle m-2"></i></h4>
|
||||
<div>
|
||||
Calculated PoW Hash: {{ calculatedPowHash }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-5 p-2">
|
||||
<div class="cold-md-7 col-lg-12">
|
||||
<div class="row gy-3">
|
||||
<h4 class="mb-3">Calculate PoW hash for a block candidate</h4>
|
||||
<div class="col-sm-6">
|
||||
<label for="calc-pow-major-version" class="form-label">Major version</label>
|
||||
<input type="number" class="form-control" min="0" id="calc-pow-major-version" placeholder="" [(ngModel)]="calcPowMajorVersion" [ngModelOptions]="{standalone: true}">
|
||||
<small class="text-body-secondary">The major version of the monero protocol at this block height</small>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6">
|
||||
<label for="calc-pow-height" class="form-label">Height</label>
|
||||
<input type="number" class="form-control" min="0" id="calc-pow-height" placeholder="" [(ngModel)]="calcPowHeight" [ngModelOptions]="{standalone: true}">
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12">
|
||||
<label for="calc-pow-blob-data" class="form-label">Blob data</label>
|
||||
<textarea [(ngModel)]="calcPowBlobData" [ngModelOptions]="{standalone: true}" type="text" class="form-control" id="calc-pow-blob-data" placeholder=""
|
||||
rows="15" cols="15" ></textarea>
|
||||
<div class="invalid-feedback">
|
||||
Invalid blob data.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12">
|
||||
<label for="calc-pow-seed" class="form-label">Seed</label>
|
||||
<input type="text" class="form-control" id="calc-pow-seed" placeholder="" [(ngModel)]="calcPowSeed" [ngModelOptions]="{standalone: true}" required="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-4">
|
||||
|
||||
<button *ngIf="!gettingCalcPow" class="w-100 btn btn-primary btn-lg" type="button" (click)="calcPowHash()">Calculate PoW Hash</button>
|
||||
<button *ngIf="gettingCalcPow" class="w-100 btn btn-primary btn-lg" type="button" disabled>Calculating PoW Hash ...</button>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="tab-pane fade" id="pills-submit-block" role="tabpanel" aria-labelledby="pills-submit-block-tab" tabindex="0">
|
||||
<div *ngIf="submitBlockError != ''" class="alert alert-danger d-flex align-items-center justify-content-center text-center" role="alert">
|
||||
<h4><i class="bi bi-exclamation-triangle m-2"></i></h4>
|
||||
<div>
|
||||
{{ submitBlockError }}
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="submitBlockSuccess" class="alert alert-success d-flex align-items-center justify-content-center text-center" role="alert">
|
||||
<h4><i class="bi bi-send-check m-2"></i></h4>
|
||||
<div>
|
||||
Successfully submitted block
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-5 p-2">
|
||||
<div class="cold-md-7 col-lg-12">
|
||||
<div class="col-md-7 col-lg-12">
|
||||
|
||||
<h4 class="mb-3">Submit a mined block to the network</h4>
|
||||
<form class="needs-validation" novalidate="">
|
||||
<div class="row g-3">
|
||||
|
||||
<div class="input-group flex-nowrap m-4">
|
||||
<span class="input-group-text" id="addon-wrapping">Reserve Size</span>
|
||||
<input type="number" class="form-control" aria-label="Reserve Size" aria-describedby="addon-wrapping">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label for="submit-block-blob-data" class="form-label">Tx Ids</label>
|
||||
<textarea [(ngModel)]="submitBlockBlobDataJsonString" [ngModelOptions]="{standalone: true}" type="text" [class]="!modifiedSubmitBlockBlobData ? 'form-control' : validBlobData() ? 'form-control' : 'form-control is-invalid'" id="tx_ids" placeholder="[
|
||||
'0707e6bdfedc053771512f1bc27c62731ae9e8f2443db64ce742f4e57f5cf8d393de28551e441a0000000002fb830a01ffbf830a018cfe88bee283060274c0aae2ef5730e680308d9c00b6da59187ad0352efe3c71d36eeeb28782f29f2501bd56b952c3ddc3e350c2631d3a5086cac172c56893831228b17de296ff4669de020200000000'
|
||||
]"
|
||||
rows="15" cols="15" ></textarea>
|
||||
<div class="invalid-feedback">
|
||||
Invalid blob data.
|
||||
</div>
|
||||
<small class="text-body-secondary">list of block blobs which have been mined. See get_block_template to get a blob on which to mine</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="input-group m-4">
|
||||
<button class="btn btn-primary" type="button" id="getBlockTemplateButton">Get Block Template</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="pills-disabled" role="tabpanel" aria-labelledby="pills-disabled-tab" tabindex="0">...</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="coreBusy && daemonRunning" class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column text-bg-dark rounded-3 m-4 text-center">
|
||||
<hr class="my-4">
|
||||
|
||||
<button *ngIf="!submittingBlock" class="w-100 btn btn-primary btn-lg" type="button" (click)="submitBlock()">Submit Block</button>
|
||||
<button *ngIf="submittingBlock" class="w-100 btn btn-primary btn-lg" type="button" disabled>Submitting Block ...</button>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-generate-blocks" role="tabpanel" aria-labelledby="pills-generate-blocks-tab" tabindex="0">
|
||||
<div *ngIf="generateBlocksError != ''" class="alert alert-danger d-flex align-items-center justify-content-center text-center" role="alert">
|
||||
<h4><i class="bi bi-exclamation-triangle m-2"></i></h4>
|
||||
<div>
|
||||
{{ generateBlocksError }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="generatingBlocks">
|
||||
<!-- Placeholder per il caricamento -->
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title placeholder-glow">
|
||||
<span class="placeholder col-6"></span>
|
||||
</h5>
|
||||
<p class="card-text placeholder-glow">
|
||||
<span class="placeholder col-7"></span>
|
||||
<span class="placeholder col-4"></span>
|
||||
<span class="placeholder col-4"></span>
|
||||
<span class="placeholder col-6"></span>
|
||||
<span class="placeholder col-8"></span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="generatedBlocks" class="card">
|
||||
<div class="card-header bg-success text-white">
|
||||
<h4>Generated Blocks</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Status: {{ generatedBlocks.status }}</h5>
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item">
|
||||
<strong>Height:</strong> {{ generatedBlocks.height }}
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<strong>Untrusted:</strong> {{ generatedBlocks.untrusted ? 'Yes' : 'No' }}
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<strong>Blocks:</strong>
|
||||
<ul>
|
||||
<li *ngFor="let block of generatedBlocks.blocks">{{ block }}</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr *ngIf="generatedBlocks" class="my-4">
|
||||
|
||||
<div class="row g-5 p-2">
|
||||
<div class="cold-md-7 col-lg-12">
|
||||
<div class="row gy-3">
|
||||
<h4 class="mb-3">Calculate PoW hash for a block candidate</h4>
|
||||
<div class="col-sm-6">
|
||||
<label for="generate-blocks-starting-nonce" class="form-label">Starting Nonce</label>
|
||||
<input type="number" class="form-control" min="0" id="generate-blocks-starting-nonce" placeholder="" [(ngModel)]="generateStartingNonce" [ngModelOptions]="{standalone: true}">
|
||||
<small class="text-body-secondary">Increased by miner until it finds a matching result that solves a block</small>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6">
|
||||
<label for="generate-blocks-amount-of-blocks" class="form-label">Amount of blocks</label>
|
||||
<input type="number" class="form-control" min="0" id="generate-blocks-amount-of-blocks" placeholder="" [(ngModel)]="generateBlocksAmountOfBlocks" [ngModelOptions]="{standalone: true}">
|
||||
<small class="text-body-secondary">Number of blocks to be generated</small>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12">
|
||||
<label for="generate-blocks-address" class="form-label">Wallet Address</label>
|
||||
<input type="text" class="form-control" id="generate-blocks-address" placeholder="" [(ngModel)]="generateBlocksAddress" [ngModelOptions]="{standalone: true}" required="">
|
||||
<small class="text-body-secondary">Address to receive the coinbase reward</small>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12">
|
||||
<label for="generate-blocks-prev-block" class="form-label">Prev Block</label>
|
||||
<input type="text" class="form-control" id="generate-blocks-prev-block" placeholder="" [(ngModel)]="generateBlockPrevBlock" [ngModelOptions]="{standalone: true}" required="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-4">
|
||||
|
||||
<button *ngIf="!generatingBlocks" class="w-100 btn btn-primary btn-lg" type="button" (click)="generateBlocks()">Generate Blocks</button>
|
||||
<button *ngIf="generatingBlocks" class="w-100 btn btn-primary btn-lg" type="button" disabled>Generating Blocks ...</button>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-disabled" role="tabpanel" aria-labelledby="pills-disabled-tab" tabindex="0">...</div>
|
||||
|
||||
<main class="px-3">
|
||||
<h1><i class="bi bi-exclamation-diamond m-4"></i> Core is busy</h1>
|
||||
<p class="lead">Mining capabilities are not available during daemon sync.</p>
|
||||
<!--
|
||||
<p class="lead">
|
||||
<a href="#" class="btn btn-lg btn-light fw-bold border-white bg-white">Learn more</a>
|
||||
</p>
|
||||
-->
|
||||
</main>
|
||||
<!--
|
||||
<footer class="mt-auto text-white-50">
|
||||
<p>Cover template for <a href="https://getbootstrap.com/" class="text-white">Bootstrap</a>, by <a href="https://twitter.com/mdo" class="text-white">mdo</a>.</p>
|
||||
</footer>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<app-daemon-not-running></app-daemon-not-running>
|
||||
|
|
|
@ -7,6 +7,7 @@ import { NavbarLink } from '../../shared/components/navbar/navbar.model';
|
|||
import { MineableTxBacklog } from '../../../common/MineableTxBacklog';
|
||||
import { Chain } from '../../../common/Chain';
|
||||
import { CoreIsBusyError } from '../../../common/error';
|
||||
import { BlockTemplate, GeneratedBlocks, MiningStatus } from '../../../common';
|
||||
|
||||
@Component({
|
||||
selector: 'app-mining',
|
||||
|
@ -18,6 +19,39 @@ export class MiningComponent implements AfterViewInit {
|
|||
public readonly navbarLinks: NavbarLink[];
|
||||
public coreBusy: boolean;
|
||||
private minerData?: MinerData;
|
||||
public miningStatus?: MiningStatus;
|
||||
public miningStatusLoading?: boolean = false;
|
||||
|
||||
public gettingBlockTemplate: boolean = false;
|
||||
public getBlockTemplateAddress: string = '';
|
||||
public getBlockTemplateReserveSize: number = 0;
|
||||
public getBlockTemplateError: string = '';
|
||||
|
||||
public blockTemplate?: BlockTemplate;
|
||||
|
||||
public submittingBlock: boolean = false;
|
||||
public submitBlockError: string = '';
|
||||
public submitBlockSuccess: boolean = false;
|
||||
public submitBlockBlobDataJsonString: string = '';
|
||||
public get modifiedSubmitBlockBlobData(): boolean {
|
||||
return this.submitBlockBlobDataJsonString != '';
|
||||
}
|
||||
|
||||
public gettingCalcPow: boolean = false;
|
||||
public calcPowBlobData: string = '';
|
||||
public calcPowMajorVersion: number = 0;
|
||||
public calcPowHeight: number = 0;
|
||||
public calcPowSeed: string = '';
|
||||
public calcPowError: string = '';
|
||||
public calculatedPowHash: string = '';
|
||||
|
||||
public generatedBlocks?: GeneratedBlocks;
|
||||
public generatingBlocks: boolean = false;
|
||||
public generateBlocksError: string = '';
|
||||
public generateBlocksAmountOfBlocks: number = 0;
|
||||
public generateBlocksAddress: string = '';
|
||||
public generateBlockPrevBlock: string = '';
|
||||
public generateStartingNonce: number = 0;
|
||||
|
||||
private majorVersion: number;
|
||||
private height: number;
|
||||
|
@ -45,7 +79,8 @@ export class MiningComponent implements AfterViewInit {
|
|||
this.coreBusy = false;
|
||||
|
||||
this.navbarLinks = [
|
||||
new NavbarLink('pills-miner-data-tab', '#pills-miner-data', 'miner-data', true, 'Miner Data'),
|
||||
new NavbarLink('pills-mining-status-tab', '#pills-mining-status', 'mining-status', true, 'Status'),
|
||||
new NavbarLink('pills-miner-data-tab', '#pills-miner-data', 'miner-data', false, 'Miner Data'),
|
||||
new NavbarLink('pills-alternate-chains-tab', '#pills-alternate-chains', 'alternate-chains', false, 'Alternate Chains'),
|
||||
new NavbarLink('pills-block-template-tab', '#pills-block-template', 'block-template', false, 'Block Template'),
|
||||
new NavbarLink('pills-generate-blocks-tab', '#pills-generate-blocks', 'generate-blocks', false, 'Generate Blocks'),
|
||||
|
@ -95,7 +130,74 @@ export class MiningComponent implements AfterViewInit {
|
|||
});
|
||||
}
|
||||
|
||||
private async getMiningStatus(): Promise<void> {
|
||||
this.miningStatusLoading = true;
|
||||
try {
|
||||
this.miningStatus = await this.daemonService.miningStatus();
|
||||
} catch(error) {
|
||||
console.error(error);
|
||||
this.miningStatus = undefined;
|
||||
}
|
||||
this.miningStatusLoading = false;
|
||||
}
|
||||
|
||||
public async getBlockTemplate(): Promise<void> {
|
||||
this.gettingBlockTemplate = true;
|
||||
|
||||
try {
|
||||
this.blockTemplate = await this.daemonService.getBlockTemplate(this.getBlockTemplateAddress, this.getBlockTemplateReserveSize);
|
||||
this.getBlockTemplateError = '';
|
||||
} catch(error) {
|
||||
this.getBlockTemplateError = `${error}`;
|
||||
}
|
||||
|
||||
this.gettingBlockTemplate = false;
|
||||
}
|
||||
|
||||
public async submitBlock(): Promise<void> {
|
||||
if (!this.validBlobData()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.submittingBlock = true;
|
||||
|
||||
try {
|
||||
const blobData: string[] = JSON.parse(this.submitBlockBlobDataJsonString);
|
||||
await this.daemonService.submitBlock(...blobData);
|
||||
this.submitBlockError = '';
|
||||
this.submitBlockSuccess = true;
|
||||
}
|
||||
catch(error) {
|
||||
console.error(error);
|
||||
this.submitBlockError = `${error}`;
|
||||
}
|
||||
this.submittingBlock = false;
|
||||
}
|
||||
|
||||
public validBlobData(): boolean {
|
||||
try {
|
||||
const parsed: any[] = JSON.parse(this.submitBlockBlobDataJsonString);
|
||||
|
||||
if (!Array.isArray(parsed)) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
parsed.forEach((blob) => {
|
||||
if (typeof blob != 'string') {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
|
||||
return true;
|
||||
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private async load(): Promise<void> {
|
||||
await this.getMiningStatus();
|
||||
|
||||
try {
|
||||
const running = await this.daemonService.isRunning();
|
||||
|
||||
|
@ -161,6 +263,32 @@ export class MiningComponent implements AfterViewInit {
|
|||
return chains;
|
||||
}
|
||||
|
||||
public async calcPowHash() {
|
||||
this.gettingCalcPow = true;
|
||||
|
||||
try {
|
||||
this.calculatedPowHash = await this.daemonService.calculatePoWHash(this.calcPowMajorVersion, this.calcPowHeight, this.calcPowBlobData, this.calcPowSeed)
|
||||
} catch(error) {
|
||||
this.calcPowError = `${error}`;
|
||||
}
|
||||
|
||||
this.gettingCalcPow = false;
|
||||
}
|
||||
|
||||
public async generateBlocks(): Promise<void> {
|
||||
this.generatingBlocks = true;
|
||||
|
||||
try {
|
||||
this.generatedBlocks = await this.daemonService.generateBlocks(this.generateBlocksAmountOfBlocks, this.generateBlocksAddress, this.generateBlockPrevBlock, this.generateStartingNonce);
|
||||
this.generateBlocksError = '';
|
||||
}
|
||||
catch(error) {
|
||||
this.generateBlocksError = `${error}`;
|
||||
}
|
||||
|
||||
this.generatingBlocks = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Card {
|
||||
|
|
Loading…
Reference in a new issue