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
21 changes: 21 additions & 0 deletions frontend/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@
],
"outputHashing": "all"
},
"fuzzing": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.fuzzing.ts"
}
],
"outputHashing": "all"
},
"producer": {
"fileReplacements": [
{
Expand All @@ -110,6 +119,9 @@
},
"local": {
"browserTarget": "frontend:build:local"
},
"fuzzing": {
"browserTarget": "frontend:build:fuzzing"
}
},
"options": {
Expand Down Expand Up @@ -185,6 +197,15 @@
}
]
},
"fuzzing": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.fuzzing.ts"
}
],
"outputHashing": "all"
},
"producer": {
"outputHashing": "media",
"fileReplacements": [
Expand Down
4 changes: 2 additions & 2 deletions frontend/package-lock.json

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

5 changes: 3 additions & 2 deletions frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"name": "frontend",
"version": "1.0.59",
"version": "1.0.66",
"scripts": {
"install:deps": "npm install",
"start": "npm install && ng serve --configuration local --open",
"start:dev": "ng serve --configuration development",
"start:dev:mobile": "ng serve --configuration development --host 0.0.0.0",
"start:fuzzing": "npm run install:deps && ng build --configuration fuzzing && npm run start:bundle",
"build": "ng build",
"build:prod": "ng build --configuration production && npm run sentry:sourcemaps",
"tests": "npx cypress open --config baseUrl=http://localhost:4200",
Expand Down Expand Up @@ -87,4 +88,4 @@
"webpack": "^5.88.2",
"webpack-bundle-analyzer": "^4.9.0"
}
}
}
1 change: 1 addition & 0 deletions frontend/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<mina-toolbar></mina-toolbar>
}
<div id="mina-content"
class="overflow-hidden"
[class.no-toolbar]="hideToolbar"
[class.no-submenus]="subMenusLength < 2"
[class.mobile]="menu.isMobile">
Expand Down
1 change: 0 additions & 1 deletion frontend/src/app/app.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ mat-sidenav-content {
$toolbar: 40px;
height: calc(100% - #{$toolbar});
border-top-left-radius: 6px;
overflow: hidden;
background-color: $base-surface;

&.no-toolbar {
Expand Down
12 changes: 9 additions & 3 deletions frontend/src/app/app.routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const BLOCK_PRODUCTION_TITLE: string = APP_TITLE + ' - Block Production';
export const MEMPOOL_TITLE: string = APP_TITLE + ' - Mempool';
export const BENCHMARKS_TITLE: string = APP_TITLE + ' - Benchmarks';
export const WEBNODE_TITLE: string = APP_TITLE + ' - Web Node';
export const FUZZING_TITLE: string = APP_TITLE + ' - Fuzzing';


function generateRoutes(): Routes {
Expand Down Expand Up @@ -57,17 +58,22 @@ function generateRoutes(): Routes {
},
{
path: 'mempool',
loadChildren: () => import('./features/mempool/mempool.module').then(m => m.MempoolModule),
loadChildren: () => import('@mempool/mempool.module').then(m => m.MempoolModule),
title: MEMPOOL_TITLE,
},
{
path: 'benchmarks',
loadChildren: () => import('./features/benchmarks/benchmarks.module').then(m => m.BenchmarksModule),
loadChildren: () => import('@benchmarks/benchmarks.module').then(m => m.BenchmarksModule),
title: BENCHMARKS_TITLE,
},
{
path: 'fuzzing',
loadChildren: () => import('@fuzzing/fuzzing.module').then(m => m.FuzzingModule),
title: FUZZING_TITLE,
},
{
path: 'loading-web-node',
loadChildren: () => import('./features/webnode/webnode.module').then(m => m.WebnodeModule),
loadChildren: () => import('@web-node/web-node.module').then(m => m.WebNodeModule),
title: WEBNODE_TITLE,
},
];
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/app/app.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ import { MempoolState } from '@app/features/mempool/mempool.state';
import { mempoolReducer } from '@app/features/mempool/mempool.reducer';
import { BenchmarksState } from '@benchmarks/benchmarks.state';
import { benchmarksReducer } from '@benchmarks/benchmarks.reducer';
import { fuzzingReducer } from '@fuzzing/fuzzing.reducer';
import { FuzzingState } from '@fuzzing/fuzzing.state';
import { FuzzingAction } from '@fuzzing/fuzzing.actions';

export interface MinaState {
[APP_KEY]: AppState;
Expand All @@ -49,6 +52,7 @@ export interface MinaState {
state: StateState;
snarks: SnarksState;
benchmarks: BenchmarksState;
fuzzing: FuzzingState;
}

type MinaAction =
Expand All @@ -59,6 +63,7 @@ type MinaAction =
& ResourcesAction
& StateAction
& SnarksAction
& FuzzingAction
;

export const reducers: ActionReducerMap<MinaState, MinaAction> = {
Expand All @@ -74,6 +79,7 @@ export const reducers: ActionReducerMap<MinaState, MinaAction> = {
state: stateReducer,
snarks: snarksReducer,
benchmarks: benchmarksReducer,
fuzzing: fuzzingReducer,
};

export const metaReducers: MetaReducer<MinaState, MinaAction>[] = [];
Expand Down
19 changes: 16 additions & 3 deletions frontend/src/app/core/services/sentry.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@ 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';
import { getElapsedTime } from '@shared/helpers/date.helper';

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

private readonly rustService: RustService = inject(RustService);
private ledgerIsSynced: boolean = false;
private blockIsSynced: boolean = false;
private rustService: RustService = inject(RustService);
private ledgerSyncedTime: number;
private blockSyncedTime: number;

updateLedgerSyncStatus(ledger: NodesOverviewLedger): void {
if (this.ledgerIsSynced) {
Expand Down Expand Up @@ -40,8 +43,9 @@ export class SentryService {
};

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

Sentry.captureMessage(`Ledger synced in ${syncedIn}s`, {
Sentry.captureMessage(`Ledger synced in ${getElapsedTime(syncedIn)}s`, {
level: 'info',
tags: { type: 'webnode', subType: 'sync.ledger' },
contexts: { ledger: syncDetails },
Expand All @@ -60,11 +64,20 @@ export class SentryService {
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`, {
this.blockSyncedTime = Math.round((Date.now() - startTime) / 1000);
Sentry.captureMessage(`Last 290 blocks synced in ${getElapsedTime(this.blockSyncedTime)}s`, {
level: 'info',
tags: { type: 'webnode', subType: 'sync.block' },
contexts: { blocks: { bestTipBlock, root } },
});

const syncTotal = this.ledgerSyncedTime + this.blockSyncedTime;
setTimeout(() => {
Sentry.captureMessage(`Web Node Synced in ${getElapsedTime(syncTotal)}`, {
level: 'info',
tags: { type: 'webnode', subType: 'sync.total' },
});
}, 2000);
}
}
}
12 changes: 11 additions & 1 deletion frontend/src/app/core/services/web-node.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,20 @@ import { DashboardPeerStatus } from '@shared/types/dashboard/dashboard.peer';
import { FileProgressHelper } from '@core/helpers/file-progress.helper';
import { CONFIG } from '@shared/constants/config';

export interface PrivateStake {
publicKey: string;
password: string;
stake: string;
}

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

private readonly webnode$: BehaviorSubject<any> = new BehaviorSubject<any>(null);
private readonly wasm$: BehaviorSubject<any> = new BehaviorSubject<any>(null);

private webNodeKeyPair: { publicKey: string, privateKey: string };
private webNodeNetwork: String;
private webNodeStartTime: number;
Expand All @@ -23,6 +30,7 @@ export class WebNodeService {
readonly webnodeProgress$: BehaviorSubject<string> = new BehaviorSubject<string>('');

memory: WebAssembly.MemoryDescriptor;
privateStake: PrivateStake;

constructor(private http: HttpClient) {
FileProgressHelper.initDownloadProgress();
Expand Down Expand Up @@ -111,7 +119,9 @@ export class WebNodeService {
}
})();
console.log('webnode config:', !!this.webNodeKeyPair.privateKey, this.webNodeNetwork, urls);
return from(wasm.run(this.webNodeKeyPair.privateKey, urls.seeds, urls.genesisConfig));
const privateKey = this.privateStake ? [this.privateStake.stake, this.privateStake.password] : this.webNodeKeyPair.privateKey;

return from(wasm.run(privateKey, urls.seeds, urls.genesisConfig));
}),
tap((webnode: any) => {
any(window).webnode = webnode;
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
<span [tooltip]="'Started ' + startedAgo + ' ago'">{{ epoch }}</span>
@if (isMobile) {
<span [copyToClipboard]="publicKey" class="fx-row-vert-cent tertiary">
<span>{{ publicKey | truncateMid: 6: 6 }}</span>
<span class="mina-icon ml-5">content_copy</span>
</span>
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,21 @@ import { BlockProductionWonSlotsSelectors } from '@block-production/won-slots/bl
import { filter } from 'rxjs';
import { BlockProductionWonSlotsSlot } from '@shared/types/block-production/won-slots/block-production-won-slots-slot.type';
import { BlockProductionWonSlotsEpoch } from '@shared/types/block-production/won-slots/block-production-won-slots-epoch.type';
import { ONE_BILLION, ONE_THOUSAND } from '@openmina/shared';
import { isMobile, ONE_BILLION, ONE_THOUSAND } from '@openmina/shared';
import { getTimeDiff } from '@shared/helpers/date.helper';

@Component({
selector: 'mina-block-production-won-slots-epoch',
templateUrl: './block-production-won-slots-epoch.component.html',
styleUrl: './block-production-won-slots-epoch.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'h-lg pl-12 f-600 fx-row-vert-cent border-bottom' },
host: { class: 'h-lg pl-12 pr-12 f-600 fx-row-vert-cent border-bottom flex-between' },
})
export class BlockProductionWonSlotsEpochComponent extends StoreDispatcher implements OnInit {
readonly isMobile = isMobile();

epoch: string;
publicKey: string;
startedAgo: string;

ngOnInit(): void {
Expand All @@ -34,7 +37,7 @@ export class BlockProductionWonSlotsEpochComponent extends StoreDispatcher imple
this.select(BlockProductionWonSlotsSelectors.epoch, (epoch: BlockProductionWonSlotsEpoch) => {
const epochStartTime = this.addMinutesToTimestamp(Math.floor(epoch.currentTime / ONE_BILLION), -(epoch.currentGlobalSlot - epoch.start) * 3);
this.startedAgo = getTimeDiff(Math.floor(epochStartTime * ONE_THOUSAND)).diff;

this.publicKey = epoch.publicKey;
this.detect();
}, filter(Boolean));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ export class BlockProductionWonSlotsComponent extends StoreDispatcher implements
private listenToActiveEpoch(): void {
this.select(BlockProductionWonSlotsSelectors.epoch, (activeEpoch) => {
this.epoch = activeEpoch?.epochNumber;
this.vrfStats = activeEpoch.vrfStats;
this.isCalculatingVRF = activeEpoch.vrfStats?.evaluated < activeEpoch.vrfStats?.total;
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 @@ -108,6 +108,7 @@ export class BlockProductionWonSlotsService {
evaluated: response.current_epoch_vrf_stats?.evaluated_slots,
total: response.current_epoch_vrf_stats?.total_slots,
},
publicKey: response.public_key,
},
};
}),
Expand Down Expand Up @@ -171,6 +172,7 @@ export interface WonSlotResponse {
total_slots: number;
};
};
public_key: string;
}

interface Attempt {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<mina-horizontal-menu [template]="template"></mina-horizontal-menu>

<ng-template #template>
<div class="flex-row">
<div class="flex-row h-100">
<mina-card label="Next Won Slot in"
[value]="card1.nextWonSlot"
[hint]="card1.slot ? 'Slot ' + card1.slot : '-'"
Expand All @@ -24,11 +24,13 @@
labelColor="var(--base-tertiary)"
color="var(--base-tertiary)"
class="mr-10"></mina-card>
<mina-card label="Total Rewards"
[value]="card5.totalRewards ? card5.totalRewards + ' MINA' : '-'"
[hint]="card5.totalRewards ? 'Coinbase and Transaction Fees' : '-'"
labelColor="var(--base-tertiary)"
color="var(--base-tertiary)"
class="mr-10"></mina-card>
<div class="custom-card flex-column flex-between tertiary h-100 pb-8 pt-8 pl-12">
<div class="label">Public Key</div>
<div class="pub-key">{{ card5.publicKey | truncateMid: 6: 6 }}</div>
<div class="fx-row-vert-cent primary-hover pointer" [copyToClipboard]="card5.publicKey">
<span class="mina-icon">content_copy</span>
<span>Copy</span>
</div>
</div>
</div>
</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,12 @@
mina-card {
height: 109px;
}

.pub-key {
font-size: 24px;
font-weight: 600;

& + div {
margin-left: -2px;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class BlockProductionWonSlotsCardsComponent extends StoreDispatcher imple
card2: { wonSlots: number; slotsUsed: number; } = { wonSlots: null, slotsUsed: null };
card3: { acceptedBlocks: number; lastBlockTime: string; } = { acceptedBlocks: null, lastBlockTime: null };
card4: { epochProgress: string; endIn: string; } = { epochProgress: '-', endIn: null };
card5: { totalRewards: string; } = { totalRewards: null };
card5: { publicKey: string; totalRewards: string } = { publicKey: null, totalRewards: null };

ngOnInit(): void {
this.listenToSlots();
Expand All @@ -38,6 +38,7 @@ export class BlockProductionWonSlotsCardsComponent extends StoreDispatcher imple
const epochEndTime = this.addMinutesToTimestamp(epoch.currentTime / ONE_BILLION, (epoch.end - epoch.currentGlobalSlot) * 3);
this.card4.endIn = getTimeDiff(epochEndTime * ONE_THOUSAND).diff;
this.card4.epochProgress = Math.floor((epoch.currentGlobalSlot - epoch.start) / (epoch.end - epoch.start) * 100) + '%';
this.card5.publicKey = epoch.publicKey;

this.detect();
}, filter(Boolean));
Expand Down
Loading
Loading