Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 75 additions & 8 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "frontend",
"version": "1.0.44",
"version": "1.0.59",
"scripts": {
"install:deps": "npm install",
"start": "npm install && ng serve --configuration local --open",
Expand Down Expand Up @@ -53,6 +53,7 @@
"eigen": "^0.2.2",
"express": "^4.18.2",
"firebase": "^11.0.1",
"jszip": "^3.10.1",
"mathjs": "^12.3.0",
"mina-signer": "^3.0.7",
"ngx-json-viewer": "^3.2.1",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/core/helpers/file-progress.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class AssetMonitor {
url: resource.toString(),
startTime,
progress: 0,
totalSize: 27355980,
totalSize: 30111552,
status: 'pending',
endTime: 0,
duration: 0,
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/app/core/services/rust.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export class RustService {
this.node = node;
}

get activeNodeIsWebNode(): boolean {
return this.node.isWebNode;
}

get URL(): string {
return this.node.url;
}
Expand Down
70 changes: 70 additions & 0 deletions frontend/src/app/core/services/sentry.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { inject, Injectable } from '@angular/core';
import { NodesOverviewLedger, NodesOverviewLedgerStepState } from '@shared/types/nodes/dashboard/nodes-overview-ledger.type';
import * as Sentry from '@sentry/angular';
import { NodesOverviewBlock, NodesOverviewNodeBlockStatus } from '@shared/types/nodes/dashboard/nodes-overview-block.type';
import { lastItem, ONE_BILLION } from '@openmina/shared';
import { RustService } from '@core/services/rust.service';

@Injectable({
providedIn: 'root',
})
export class SentryService {

private ledgerIsSynced: boolean = false;
private blockIsSynced: boolean = false;
private rustService: RustService = inject(RustService);

updateLedgerSyncStatus(ledger: NodesOverviewLedger): void {
if (this.ledgerIsSynced) {
return;
}
if (ledger.rootStaged.state === NodesOverviewLedgerStepState.SUCCESS) {
this.ledgerIsSynced = true;
const syncDetails = {
stakingLedger: {
fetchHashes: ledger.stakingEpoch.snarked.fetchHashesDuration + 's',
fetchAccounts: ledger.stakingEpoch.snarked.fetchAccountsDuration + 's',
},
nextEpochLedger: {
fetchHashes: ledger.nextEpoch.snarked.fetchHashesDuration + 's',
fetchAccounts: ledger.nextEpoch.snarked.fetchAccountsDuration + 's',
},
snarkedRootLedger: {
fetchHashes: ledger.rootSnarked.snarked.fetchHashesDuration + 's',
fetchAccounts: ledger.rootSnarked.snarked.fetchAccountsDuration + 's',
},
stagedRootLedger: {
fetchParts: ledger.rootStaged.staged.fetchPartsDuration + 's',
reconstruct: ledger.rootStaged.staged.reconstructDuration + 's',
},
};

const syncedIn = Math.round((ledger.rootStaged.staged.reconstructEnd - ledger.stakingEpoch.snarked.fetchHashesStart) / ONE_BILLION);

Sentry.captureMessage(`Ledger synced in ${syncedIn}s`, {
level: 'info',
tags: { type: 'webnode', subType: 'sync.ledger' },
contexts: { ledger: syncDetails },
});
}
}

updateBlockSyncStatus(blocks: NodesOverviewBlock[], startTime: number): void {
if (this.blockIsSynced || !this.rustService.activeNodeIsWebNode) {
return;
}

const blocksSynced = blocks.every(b => b.status === NodesOverviewNodeBlockStatus.APPLIED);
if (blocksSynced && blocks[0]) {
this.blockIsSynced = true;
blocks = blocks.slice(1);
const bestTipBlock = blocks[0].height;
const root = lastItem(blocks).height;
Sentry.captureMessage(`Last 290 blocks synced in ${Math.round((Date.now() - startTime) / 1000)}s`, {
level: 'info',
tags: { type: 'webnode', subType: 'sync.block' },
contexts: { blocks: { bestTipBlock, root } },
});
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<mina-benchmarks-wallets-toolbar></mina-benchmarks-wallets-toolbar>
<div class="h-minus-xl flex-column">
<mina-benchmarks-wallets-zkapp-toolbar *ngIf="!isWebNode"></mina-benchmarks-wallets-zkapp-toolbar>
<div [class.h-minus-xl]="!isWebNode"
@if (!isWebNode) {
<mina-benchmarks-wallets-zkapp-toolbar></mina-benchmarks-wallets-zkapp-toolbar>
}
<div [ngClass]="isWebNode ? 'h-100' : 'h-minus-xl'"
class="flex-column">
<mina-benchmarks-wallets-table></mina-benchmarks-wallets-table>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
import { MinaState, selectMinaState } from '@app/app.setup';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { Effect } from '@openmina/shared';
import { EMPTY, forkJoin, map, switchMap } from 'rxjs';
import { combineLatest, EMPTY, map, switchMap } from 'rxjs';
import { Store } from '@ngrx/store';
import {
BENCHMARKS_WALLETS_CLOSE,
Expand All @@ -11,8 +11,11 @@ import {
BENCHMARKS_WALLETS_GET_WALLETS,
BENCHMARKS_WALLETS_GET_WALLETS_SUCCESS,
BENCHMARKS_WALLETS_SEND_TX_SUCCESS,
BENCHMARKS_WALLETS_SEND_TXS, BENCHMARKS_WALLETS_SEND_ZKAPPS, BENCHMARKS_WALLETS_SEND_ZKAPPS_SUCCESS,
BenchmarksWalletsActions, BenchmarksWalletsClose,
BENCHMARKS_WALLETS_SEND_TXS,
BENCHMARKS_WALLETS_SEND_ZKAPPS,
BENCHMARKS_WALLETS_SEND_ZKAPPS_SUCCESS,
BenchmarksWalletsActions,
BenchmarksWalletsClose,
BenchmarksWalletsGetWallets,
BenchmarksWalletsSendTxs,
} from '@benchmarks/wallets/benchmarks-wallets.actions';
Expand Down Expand Up @@ -74,7 +77,7 @@ export class BenchmarksWalletsEffects extends MinaRustBaseEffect<BenchmarksWalle
this.getAllTxs$ = createEffect(() => this.actions$.pipe(
ofType(BENCHMARKS_WALLETS_GET_ALL_TXS),
switchMap(() =>
forkJoin([
combineLatest([
this.mempoolService.getTransactionPool(),
this.benchmarksService.getAllIncludedTransactions(),
]),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@if (isPending || nodeIsBootstrapping || isCalculatingVRF || isLoading) {
@if ((isPending || nodeIsBootstrapping || isCalculatingVRF || isLoading) && emptySlots) {
<div class="w-100 h-100 fx-col-full-cent"
@fadeInOut>
<mina-loading-spinner [size]="50" [borderWidth]="2"></mina-loading-spinner>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class BlockProductionWonSlotsComponent extends StoreDispatcher implements
total: number;
};
epoch: number;
emptySlots: boolean = false;
emptySlots: boolean = true;
isLoading: boolean = true;

constructor(protected el: ElementRef) { super(); }
Expand Down Expand Up @@ -82,8 +82,9 @@ export class BlockProductionWonSlotsComponent extends StoreDispatcher implements

private listenToActiveEpoch(): void {
this.select(BlockProductionWonSlotsSelectors.epoch, (activeEpoch) => {
this.epoch = activeEpoch.epochNumber;
this.epoch = activeEpoch?.epochNumber;
this.vrfStats = activeEpoch.vrfStats;
this.isCalculatingVRF = activeEpoch.vrfStats?.evaluated < activeEpoch.vrfStats?.total;
this.detect();
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class BlockProductionWonSlotsService {
}
const attemptsSlots = response.attempts.map((attempt: Attempt) => {
attempt.won_slot.slot_time = Math.floor(attempt.won_slot.slot_time / ONE_MILLION); // converted to milliseconds
attempt.active = BlockProductionWonSlotsService.getActive(attempt);
attempt.active = this.getActive(attempt);
let slot = {
epoch: attempt.won_slot.epoch,
message: this.getMessage(attempt),
Expand Down Expand Up @@ -114,7 +114,7 @@ export class BlockProductionWonSlotsService {
);
}

private static getActive(attempt: Attempt): boolean {
private getActive(attempt: Attempt): boolean {
const slotTime = attempt.won_slot.slot_time;
const now = Date.now();
return slotTime <= now && (now < 3 * 60 * 1000 + slotTime) && !attempt.times?.discarded;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { NodesOverviewNode } from '@shared/types/nodes/dashboard/nodes-overview-
import { NodesOverviewNodeBlockStatus } from '@shared/types/nodes/dashboard/nodes-overview-block.type';
import { isDesktop, lastItem, ONE_MILLION } from '@openmina/shared';
import { DashboardPeer } from '@shared/types/dashboard/dashboard.peer';
import { SentryService } from '@core/services/sentry.service';

const PENDING = 'Pending';
const SYNCED = 'Synced';
Expand All @@ -30,6 +31,10 @@ export class DashboardBlocksSyncComponent extends StoreDispatcher implements OnI
isDesktop: boolean = isDesktop();
remaining: number;

private syncStartTime: number = Date.now();

constructor(private sentryService: SentryService) {super();}

ngOnInit(): void {
this.listenToNodesChanges();
}
Expand Down Expand Up @@ -76,6 +81,8 @@ export class DashboardBlocksSyncComponent extends StoreDispatcher implements OnI

this.extractNodesData(nodes);
this.extractPeersData(peers);

this.sentryService.updateBlockSyncStatus(nodes[0].blocks, this.syncStartTime);
}
this.detect();
});
Expand Down Expand Up @@ -115,8 +122,8 @@ export class DashboardBlocksSyncComponent extends StoreDispatcher implements OnI

this.fetched = blocks.filter(b => ![NodesOverviewNodeBlockStatus.MISSING, NodesOverviewNodeBlockStatus.FETCHING].includes(b.status)).length;
this.applied = blocks.filter(b => b.status === NodesOverviewNodeBlockStatus.APPLIED).length;
this.fetchedPercentage = Math.round(this.fetched * 100 / 291) + '%';
this.appliedPercentage = Math.round(this.applied * 100 / 291);
this.fetchedPercentage = Math.round(this.fetched * 100 / 290) + '%';
this.appliedPercentage = Math.round(this.applied * 100 / 290);
}

private calculateProgressTime(timestamp: number): string {
Expand Down
Loading
Loading