Skip to content

Commit 3f85eea

Browse files
committed
New updates for leaderboard
New updates for leaderboard More updates Sentry feat(heartbeats): Implement more advanced rate limiting on API Leaderboard Leaderboard Block production sentry reporting Add allowed_keys.txt to .gitignore fix(heartbeats): Perform allowed keys replacements on generated .js file, not original source fix(frontend): Don't log stake Remove sentry for BP for now fix(mempool): Really verify tx snarks in another thread Sentry Add allowed_keys.txt to .gitignore fix(heartbeats): Perform allowed keys replacements on generated .js file, not original source fix(frontend): Don't log stake feat(rpc): Include previous block production attempt in /status response Remove sentry for BP for now fix(frontend/webnode): key upload file names Version Fix light theme Sentry - block production event Fix light theme New version - fix light theme Sentry - block production event feat(transition_frontier/sync/ledger/snarked): randomize which peer is used for query fix(transition_frontier/sync/ledger/snarked): edge case query not being made Sentry - report BP Duration Duration for block produced Leaderboard Whales Keys included Sentry BP report flattening attempt object Sentry BP report flattening attempt object 2 Heartbeat sentry - improve http on bad internet Heartbeats with context in Sentry Leaderboard page css Remove mina explorer and add fetch parts label
1 parent 806aa75 commit 3f85eea

File tree

40 files changed

+434
-195
lines changed

40 files changed

+434
-195
lines changed

.idea/.gitignore

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/functions/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ node_modules/
22
*.local
33
coverage/
44
lib/
5+
allowed_keys.txt

frontend/functions/build.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ if (fs.existsSync(keysFilePath)) {
1010
.map(key => key.trim())
1111
.filter(key => key.length > 0);
1212

13-
const validatorFilePath = path.resolve(__dirname, 'functions/submitterValidator.ts');
13+
const validatorFilePath = path.resolve(__dirname, 'lib/submitterValidator.js');
1414
let validatorFileContent = fs.readFileSync(validatorFilePath, 'utf-8');
1515

1616
const keysSetString = keys.map(key => `'${key}'`).join(',\n ');

frontend/functions/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/functions/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"logs": "firebase functions:log",
1010
"test": "jest",
1111
"test:watch": "jest --watch",
12-
"build": "node build.js && tsc -p tsconfig.json",
12+
"build": "tsc -p tsconfig.json && node build.js",
1313
"build:watch": "tsc --watch"
1414
},
1515
"engines": {
@@ -21,7 +21,7 @@
2121
"blake2": "^5.0.0",
2222
"bs58check": "^3.0.1",
2323
"firebase-admin": "^12.1.0",
24-
"firebase-functions": "^6.2.0",
24+
"firebase-functions": "^6.3.2",
2525
"mina-signer": "^3.0.7"
2626
},
2727
"devDependencies": {

frontend/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "frontend",
3-
"version": "1.0.130",
3+
"version": "1.0.180",
44
"scripts": {
55
"install:deps": "npm install",
66
"start": "npm install && ng serve --configuration local --open",
@@ -91,4 +91,4 @@
9191
"webpack": "^5.88.2",
9292
"webpack-bundle-analyzer": "^4.9.0"
9393
}
94-
}
94+
}

frontend/src/app/app.module.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,17 @@ import { ReactiveFormsModule } from '@angular/forms';
3636
import { WebNodeLandingPageComponent } from '@app/layout/web-node-landing-page/web-node-landing-page.component';
3737
import * as Sentry from '@sentry/angular';
3838
import { Router } from '@angular/router';
39-
import { initializeApp, provideFirebaseApp } from '@angular/fire/app';
39+
import { getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
4040
import { getAnalytics, provideAnalytics, ScreenTrackingService } from '@angular/fire/analytics';
4141
import { getPerformance, providePerformance } from '@angular/fire/performance';
4242
import { BlockProductionPillComponent } from '@app/layout/block-production-pill/block-production-pill.component';
4343
import { MenuTabsComponent } from '@app/layout/menu-tabs/menu-tabs.component';
4444
import { getFirestore, provideFirestore } from '@angular/fire/firestore';
4545
import { LeaderboardModule } from '@leaderboard/leaderboard.module';
4646
import { UptimePillComponent } from '@app/layout/uptime-pill/uptime-pill.component';
47+
import { provideAppCheck } from '@angular/fire/app-check';
48+
import { initializeAppCheck, ReCaptchaV3Provider } from 'firebase/app-check';
49+
import { SETTINGS } from '@angular/fire/compat/firestore';
4750

4851
registerLocaleData(localeFr, 'fr');
4952
registerLocaleData(localeEn, 'en');
@@ -129,15 +132,20 @@ export class AppGlobalErrorhandler implements ErrorHandler {
129132
}
130133

131134
const firebaseProviders = [
135+
{
136+
provide: SETTINGS,
137+
useValue: { experimentalForceLongPolling: true },
138+
},
139+
provideFirebaseApp(() => initializeApp(CONFIG.globalConfig.firebase)),
132140
provideClientHydration(),
133141
provideHttpClient(withFetch()),
134-
provideFirebaseApp(() => initializeApp(CONFIG.globalConfig.firebase)),
135142
provideAnalytics(() => getAnalytics()),
136143
ScreenTrackingService,
137144
// provideAppCheck(() => {
138145
// // TODO get a reCAPTCHA Enterprise here https://console.cloud.google.com/security/recaptcha?project=_
139-
// const provider = new ReCaptchaEnterpriseProvider(/* reCAPTCHA Enterprise site key */);
140-
// return initializeAppCheck(undefined, { provider, isTokenAutoRefreshEnabled: true });
146+
// const app = getApp();
147+
// const provider = new ReCaptchaV3Provider('6LfAB-QqAAAAAEu9BO6upFj6Sewd08lf0UtFC16c');
148+
// return initializeAppCheck(app, { provider, isTokenAutoRefreshEnabled: true });
141149
// }),
142150
providePerformance(() => getPerformance()),
143151
provideFirestore(() => getFirestore()),
@@ -192,7 +200,8 @@ const firebaseProviders = [
192200
{ provide: Sentry.TraceService, deps: [Router] },
193201
{
194202
provide: APP_INITIALIZER,
195-
useFactory: () => () => {},
203+
useFactory: () => () => {
204+
},
196205
deps: [Sentry.TraceService],
197206
multi: true,
198207
},
@@ -203,4 +212,5 @@ const firebaseProviders = [
203212
MenuComponent,
204213
],
205214
})
206-
export class AppModule {}
215+
export class AppModule {
216+
}

frontend/src/app/app.service.ts

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,29 @@
11
import { Injectable } from '@angular/core';
2-
import { map, Observable, of } from 'rxjs';
2+
import { map, Observable, of, tap } from 'rxjs';
33
import { MinaNode } from '@shared/types/core/environment/mina-env.type';
44
import { CONFIG } from '@shared/constants/config';
55
import { RustService } from '@core/services/rust.service';
66
import { AppNodeDetails, AppNodeStatus } from '@shared/types/app/app-node-details.type';
77
import { getNetwork } from '@shared/helpers/mina.helper';
88
import { getLocalStorage, nanOrElse, ONE_MILLION } from '@openmina/shared';
9-
import { BlockProductionWonSlotsStatus } from '@shared/types/block-production/won-slots/block-production-won-slots-slot.type';
9+
import {
10+
BlockProductionWonSlotsStatus
11+
} from '@shared/types/block-production/won-slots/block-production-won-slots-slot.type';
1012
import { AppEnvBuild } from '@shared/types/app/app-env-build.type';
13+
import { SentryService } from '@core/services/sentry.service';
14+
import { WebNodeService } from '@core/services/web-node.service';
1115

1216
@Injectable({
1317
providedIn: 'root',
1418
})
1519
export class AppService {
1620

17-
constructor(private rust: RustService) { }
21+
private previousProducedBlock: BlockProductionAttempt;
22+
23+
constructor(private rust: RustService,
24+
private sentryService: SentryService,
25+
private webnodeService: WebNodeService) {
26+
}
1827

1928
getActiveNode(nodes: MinaNode[]): Observable<MinaNode> {
2029
const nodeName = new URL(location.href).searchParams.get('node');
@@ -37,6 +46,7 @@ export class AppService {
3746
getActiveNodeDetails(): Observable<AppNodeDetails> {
3847
return this.rust.get<NodeDetailsResponse>('/status')
3948
.pipe(
49+
tap((data: NodeDetailsResponse) => this.notifyPrevBlockChanged(data)),
4050
map((data: NodeDetailsResponse): AppNodeDetails => ({
4151
status: this.getStatus(data),
4252
blockHeight: data.transition_frontier.best_tip?.height,
@@ -55,6 +65,27 @@ export class AppService {
5565
);
5666
}
5767

68+
private notifyPrevBlockChanged(data: NodeDetailsResponse): void {
69+
if (!this.rust.activeNodeIsWebNode) {
70+
return;
71+
}
72+
73+
const isInProduction = (status: BlockProductionWonSlotsStatus) =>
74+
![
75+
BlockProductionWonSlotsStatus.Discarded,
76+
BlockProductionWonSlotsStatus.Orphaned,
77+
BlockProductionWonSlotsStatus.Canonical,
78+
].includes(status)
79+
80+
if (
81+
this.previousProducedBlock && data.previous_block_production_attempt
82+
&& isInProduction(this.previousProducedBlock.status) !== isInProduction(data.previous_block_production_attempt.status)
83+
) {
84+
this.sentryService.updateProducedBlock(data.previous_block_production_attempt, this.webnodeService.publicKey);
85+
}
86+
this.previousProducedBlock = data.previous_block_production_attempt;
87+
}
88+
5889
private getStatus(data: NodeDetailsResponse): AppNodeStatus {
5990
switch (data.transition_frontier.sync.phase) {
6091
case 'Bootstrap':
@@ -76,6 +107,7 @@ export interface NodeDetailsResponse {
76107
snark_pool: SnarkPool;
77108
chain_id: string | undefined;
78109
current_block_production_attempt: BlockProductionAttempt;
110+
previous_block_production_attempt: BlockProductionAttempt;
79111
}
80112

81113
export interface BlockProductionAttempt {
Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,28 @@
1-
import { Injectable, Optional } from '@angular/core';
2-
import { collection, CollectionReference, deleteDoc, doc, DocumentData, Firestore, updateDoc } from '@angular/fire/firestore';
1+
import { Injectable } from '@angular/core';
32
import { HttpClient } from '@angular/common/http';
4-
import { catchError, Observable, of } from 'rxjs';
3+
import { catchError, Observable, of, tap } from 'rxjs';
4+
import { SentryService } from '@core/services/sentry.service';
55

66
@Injectable({
77
providedIn: 'root',
88
})
99
export class FirestoreService {
10-
private heartbeatCollection: CollectionReference<DocumentData>;
1110
private cloudFunctionUrl = 'https://us-central1-webnode-gtm-test.cloudfunctions.net/handleValidationAndStore';
1211

13-
constructor(@Optional() private firestore: Firestore,
14-
private http: HttpClient) {
15-
if (this.firestore) {
16-
this.heartbeatCollection = collection(this.firestore, 'heartbeat');
17-
}
18-
}
12+
constructor(private sentryService: SentryService,
13+
private http: HttpClient) { }
1914

2015
addHeartbeat(data: any): Observable<any> {
2116
console.log('Posting to cloud function:', data);
22-
return this.http.post(this.cloudFunctionUrl, { data }).pipe(
23-
catchError(error => {
24-
console.error('Error while posting to cloud function:', error);
25-
return of(null);
26-
}),
27-
);
28-
}
29-
30-
updateHeartbeat(id: string, data: any): Promise<void> {
31-
const docRef = doc(this.heartbeatCollection, id);
32-
return updateDoc(docRef, data);
33-
}
34-
35-
deleteHeartbeat(id: string): Promise<void> {
36-
const docRef = doc(this.heartbeatCollection, id);
37-
return deleteDoc(docRef);
17+
return this.http.post(this.cloudFunctionUrl, { data })
18+
.pipe(
19+
// tap(() => {
20+
// this.sentryService.updateHeartbeat(data, data.submitter);
21+
// }),
22+
catchError(error => {
23+
console.error('Error while posting heartbeat', error);
24+
return of(null);
25+
}),
26+
);
3827
}
3928
}

0 commit comments

Comments
 (0)