From 2efbde9cb95352e8ccc3b6e135a413d21b97c909 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Tue, 23 Sep 2025 20:25:42 +0200 Subject: [PATCH 1/5] frontend: configure prettier --- frontend/.prettierrc.json | 28 ++++++++++++++++++++++++++ frontend/Makefile | 41 ++++++++++++++++++++++++++++++++++++++ frontend/package-lock.json | 17 ++++++++++++++++ frontend/package.json | 5 ++++- 4 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 frontend/.prettierrc.json create mode 100644 frontend/Makefile diff --git a/frontend/.prettierrc.json b/frontend/.prettierrc.json new file mode 100644 index 0000000000..731ac911c8 --- /dev/null +++ b/frontend/.prettierrc.json @@ -0,0 +1,28 @@ +{ + "printWidth": 80, + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": true, + "quoteProps": "as-needed", + "jsxSingleQuote": false, + "trailingComma": "all", + "bracketSpacing": true, + "bracketSameLine": false, + "arrowParens": "avoid", + "proseWrap": "preserve", + "htmlWhitespaceSensitivity": "css", + "endOfLine": "lf", + "overrides": [ + { + "files": "**/*.html", + "options": { + "parser": "angular", + "printWidth": 80, + "bracketSameLine": false, + "htmlWhitespaceSensitivity": "ignore", + "singleAttributePerLine": false + } + } + ] +} \ No newline at end of file diff --git a/frontend/Makefile b/frontend/Makefile new file mode 100644 index 0000000000..5413b96f80 --- /dev/null +++ b/frontend/Makefile @@ -0,0 +1,41 @@ +# Frontend Makefile + +.PHONY: help +help: ## Display this help message + @echo "Frontend Makefile - Available targets:" + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' + +.PHONY: install +install: ## Install npm dependencies + npm install + +.PHONY: prettify +prettify: ## Format HTML, SCSS, TypeScript, and JavaScript files with Prettier + npx prettier --write 'src/**/*.{ts,js,html,scss,css,json}' + +.PHONY: check-prettify +check-prettify: ## Check if files are formatted with Prettier + npx prettier --check 'src/**/*.{ts,js,html,scss,css,json}' + +.PHONY: start +start: ## Start the development server + npm start + +.PHONY: build +build: ## Build the frontend for production + npm run build:prod + +.PHONY: test +test: ## Run Cypress tests + npm run tests + +.PHONY: test-headless +test-headless: ## Run Cypress tests in headless mode + npm run tests:headless + +.PHONY: clean +clean: ## Clean build artifacts and node_modules + rm -rf dist node_modules + +.PHONY: rebuild +rebuild: clean install build ## Clean, reinstall dependencies, and rebuild diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 778bbd9935..ade6e67cdb 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -69,6 +69,7 @@ "karma-coverage": "~2.2.0", "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "~2.1.0", + "prettier": "^3.6.2", "terser-webpack-plugin": "^5.3.10", "typescript": "~5.8.3", "webpack": "^5.88.2", @@ -15816,6 +15817,22 @@ "dev": true, "license": "MIT" }, + "node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 8d057435fb..f760769bee 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -19,7 +19,9 @@ "sentry:sourcemaps": "sentry-cli sourcemaps inject --org openmina-uv --project openmina ./dist/frontend/browser && sentry-cli sourcemaps upload --org openmina-uv --project openmina ./dist/frontend/browser", "copy-env": "cp dist/frontend/browser/assets/environments/webnode.js dist/frontend/browser/assets/environments/env.js", "deploy": "npm run prebuild && npm run build:prod && npm run copy-env && firebase deploy", - "deploy:leaderboard": "npm run prebuild && npm run build:prod && cp dist/frontend/browser/assets/environments/leaderboard.js dist/frontend/browser/assets/environments/env.js && firebase deploy" + "deploy:leaderboard": "npm run prebuild && npm run build:prod && cp dist/frontend/browser/assets/environments/leaderboard.js dist/frontend/browser/assets/environments/env.js && firebase deploy", + "prettify": "make prettify", + "check-prettify": "make check-prettify" }, "private": true, "dependencies": { @@ -84,6 +86,7 @@ "karma-coverage": "~2.2.0", "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "~2.1.0", + "prettier": "^3.6.2", "terser-webpack-plugin": "^5.3.10", "typescript": "~5.8.3", "webpack": "^5.88.2", From fe2ec3b981508ca2469a0d687bcb60cf9b455179 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 24 Sep 2025 11:20:32 +0200 Subject: [PATCH 2/5] frontend: run npx prettier --write 'src/**/*.{ts,js,html,scss,css,json}' src/app/app.actions.ts 51ms (unchanged) src/app/app.component.html 48ms (unchanged) src/app/app.component.scss 30ms (unchanged) src/app/app.component.ts 31ms (unchanged) src/app/app.config.ts 17ms (unchanged) src/app/app.effects.ts 14ms (unchanged) src/app/app.module.server.ts 1ms (unchanged) src/app/app.module.ts 3ms (unchanged) src/app/app.reducer.ts 11ms (unchanged) src/app/app.routing.ts 8ms (unchanged) src/app/app.service.ts 13ms (unchanged) src/app/app.setup.ts 4ms (unchanged) src/app/app.state.ts 3ms (unchanged) src/app/core/helpers/file-progress.helper.ts 8ms (unchanged) src/app/core/services/config.service.ts 3ms (unchanged) src/app/core/services/firestore.service.ts 2ms (unchanged) src/app/core/services/rust.service.ts 7ms (unchanged) src/app/core/services/sentry.service.ts 11ms (unchanged) src/app/core/services/web-node.service.ts 20ms (unchanged) src/app/features/benchmarks/benchmarks.component.html 1ms (unchanged) src/app/features/benchmarks/benchmarks.component.scss 0ms (unchanged) src/app/features/benchmarks/benchmarks.component.ts 2ms (unchanged) src/app/features/benchmarks/benchmarks.module.ts 1ms (unchanged) src/app/features/benchmarks/benchmarks.reducer.ts 1ms (unchanged) src/app/features/benchmarks/benchmarks.routing.ts 2ms (unchanged) src/app/features/benchmarks/benchmarks.state.ts 2ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets-table/benchmarks-wallets-table.component.html 9ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets-table/benchmarks-wallets-table.component.scss 2ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets-table/benchmarks-wallets-table.component.ts 3ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets-toolbar/benchmarks-wallets-toolbar.component.html 16ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets-toolbar/benchmarks-wallets-toolbar.component.scss 5ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets-toolbar/benchmarks-wallets-toolbar.component.ts 16ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets-zk.service.ts 5ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets-zkapp-toolbar/benchmarks-wallets-zkapp-toolbar.component.html 15ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets-zkapp-toolbar/benchmarks-wallets-zkapp-toolbar.component.scss 4ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets-zkapp-toolbar/benchmarks-wallets-zkapp-toolbar.component.ts 9ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets.actions.ts 6ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets.component.html 2ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets.component.scss 0ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets.component.ts 3ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets.effects.ts 6ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets.module.ts 1ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets.reducer.ts 18ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets.routing.ts 1ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets.service.ts 70ms (unchanged) src/app/features/benchmarks/wallets/benchmarks-wallets.state.ts 3ms (unchanged) src/app/features/block-production/block-production.actions.ts 1ms (unchanged) src/app/features/block-production/block-production.component.html 1ms (unchanged) src/app/features/block-production/block-production.component.scss 0ms (unchanged) src/app/features/block-production/block-production.component.ts 1ms (unchanged) src/app/features/block-production/block-production.guard.ts 3ms (unchanged) src/app/features/block-production/block-production.module.ts 1ms (unchanged) src/app/features/block-production/block-production.reducer.ts 1ms (unchanged) src/app/features/block-production/block-production.routing.ts 2ms (unchanged) src/app/features/block-production/block-production.state.ts 2ms (unchanged) src/app/features/block-production/overview/block-production-overview.actions.ts 3ms (unchanged) src/app/features/block-production/overview/block-production-overview.component.html 6ms (unchanged) src/app/features/block-production/overview/block-production-overview.component.scss 0ms (unchanged) src/app/features/block-production/overview/block-production-overview.component.ts 4ms (unchanged) src/app/features/block-production/overview/block-production-overview.effects.ts 6ms (unchanged) src/app/features/block-production/overview/block-production-overview.module.ts 1ms (unchanged) src/app/features/block-production/overview/block-production-overview.reducer.ts 4ms (unchanged) src/app/features/block-production/overview/block-production-overview.routing.ts 1ms (unchanged) src/app/features/block-production/overview/block-production-overview.service.ts 10ms (unchanged) src/app/features/block-production/overview/block-production-overview.state.ts 3ms (unchanged) src/app/features/block-production/overview/epoch-graphs/block-production-overview-epoch-graphs.component.html 14ms (unchanged) src/app/features/block-production/overview/epoch-graphs/block-production-overview-epoch-graphs.component.scss 4ms (unchanged) src/app/features/block-production/overview/epoch-graphs/block-production-overview-epoch-graphs.component.ts 4ms (unchanged) src/app/features/block-production/overview/side-panel/block-production-overview-side-panel.component.html 23ms (unchanged) src/app/features/block-production/overview/side-panel/block-production-overview-side-panel.component.scss 4ms (unchanged) src/app/features/block-production/overview/side-panel/block-production-overview-side-panel.component.ts 8ms (unchanged) src/app/features/block-production/overview/slot-details/block-production-overview-slot-details.component.html 6ms (unchanged) src/app/features/block-production/overview/slot-details/block-production-overview-slot-details.component.scss 0ms (unchanged) src/app/features/block-production/overview/slot-details/block-production-overview-slot-details.component.ts 2ms (unchanged) src/app/features/block-production/overview/slots/block-production-overview-slots.component.html 5ms (unchanged) src/app/features/block-production/overview/slots/block-production-overview-slots.component.scss 1ms (unchanged) src/app/features/block-production/overview/slots/block-production-overview-slots.component.ts 18ms (unchanged) src/app/features/block-production/overview/toolbar/block-production-overview-toolbar.component.html 13ms (unchanged) src/app/features/block-production/overview/toolbar/block-production-overview-toolbar.component.scss 1ms (unchanged) src/app/features/block-production/overview/toolbar/block-production-overview-toolbar.component.ts 6ms (unchanged) src/app/features/block-production/won-slots/block-production-won-slots-epoch/block-production-won-slots-epoch.component.html 3ms (unchanged) src/app/features/block-production/won-slots/block-production-won-slots-epoch/block-production-won-slots-epoch.component.scss 0ms (unchanged) src/app/features/block-production/won-slots/block-production-won-slots-epoch/block-production-won-slots-epoch.component.ts 3ms (unchanged) src/app/features/block-production/won-slots/block-production-won-slots.actions.ts 3ms (unchanged) src/app/features/block-production/won-slots/block-production-won-slots.component.html 8ms (unchanged) src/app/features/block-production/won-slots/block-production-won-slots.component.scss 2ms (unchanged) src/app/features/block-production/won-slots/block-production-won-slots.component.ts 5ms (unchanged) src/app/features/block-production/won-slots/block-production-won-slots.effects.ts 5ms (unchanged) src/app/features/block-production/won-slots/block-production-won-slots.module.ts 1ms (unchanged) src/app/features/block-production/won-slots/block-production-won-slots.reducer.ts 5ms (unchanged) src/app/features/block-production/won-slots/block-production-won-slots.routing.ts 1ms (unchanged) src/app/features/block-production/won-slots/block-production-won-slots.service.ts 10ms (unchanged) src/app/features/block-production/won-slots/block-production-won-slots.state.ts 2ms (unchanged) src/app/features/block-production/won-slots/cards/block-production-won-slots-cards.component.html 6ms (unchanged) src/app/features/block-production/won-slots/cards/block-production-won-slots-cards.component.scss 1ms (unchanged) src/app/features/block-production/won-slots/cards/block-production-won-slots-cards.component.ts 6ms (unchanged) src/app/features/block-production/won-slots/filters/block-production-won-slots-filters.component.html 10ms (unchanged) src/app/features/block-production/won-slots/filters/block-production-won-slots-filters.component.scss 1ms (unchanged) src/app/features/block-production/won-slots/filters/block-production-won-slots-filters.component.ts 3ms (unchanged) src/app/features/block-production/won-slots/side-panel/block-production-won-slots-side-panel.component.html 27ms (unchanged) src/app/features/block-production/won-slots/side-panel/block-production-won-slots-side-panel.component.scss 4ms (unchanged) src/app/features/block-production/won-slots/side-panel/block-production-won-slots-side-panel.component.ts 8ms (unchanged) src/app/features/block-production/won-slots/table/block-production-won-slots-table.component.html 7ms (unchanged) src/app/features/block-production/won-slots/table/block-production-won-slots-table.component.scss 3ms (unchanged) src/app/features/block-production/won-slots/table/block-production-won-slots-table.component.ts 6ms (unchanged) src/app/features/dashboard/dashboard-blocks-sync/dashboard-blocks-sync.component.html 9ms (unchanged) src/app/features/dashboard/dashboard-blocks-sync/dashboard-blocks-sync.component.scss 2ms (unchanged) src/app/features/dashboard/dashboard-blocks-sync/dashboard-blocks-sync.component.ts 8ms (unchanged) src/app/features/dashboard/dashboard-ledger/dashboard-ledger.component.html 26ms (unchanged) src/app/features/dashboard/dashboard-ledger/dashboard-ledger.component.scss 4ms (unchanged) src/app/features/dashboard/dashboard-ledger/dashboard-ledger.component.ts 14ms (unchanged) src/app/features/dashboard/dashboard-network/dashboard-network.component.html 5ms (unchanged) src/app/features/dashboard/dashboard-network/dashboard-network.component.scss 1ms (unchanged) src/app/features/dashboard/dashboard-network/dashboard-network.component.ts 2ms (unchanged) src/app/features/dashboard/dashboard-peers-minimal-table/dashboard-peers-minimal-table.component.html 3ms (unchanged) src/app/features/dashboard/dashboard-peers-minimal-table/dashboard-peers-minimal-table.component.scss 1ms (unchanged) src/app/features/dashboard/dashboard-peers-minimal-table/dashboard-peers-minimal-table.component.ts 2ms (unchanged) src/app/features/dashboard/dashboard.actions.ts 2ms (unchanged) src/app/features/dashboard/dashboard.component.html 3ms (unchanged) src/app/features/dashboard/dashboard.component.scss 3ms (unchanged) src/app/features/dashboard/dashboard.component.ts 7ms (unchanged) src/app/features/dashboard/dashboard.effects.ts 4ms (unchanged) src/app/features/dashboard/dashboard.module.ts 1ms (unchanged) src/app/features/dashboard/dashboard.reducer.ts 3ms (unchanged) src/app/features/dashboard/dashboard.routing.ts 1ms (unchanged) src/app/features/dashboard/dashboard.service.ts 5ms (unchanged) src/app/features/dashboard/dashboard.state.ts 3ms (unchanged) src/app/features/fuzzing/fuzzing-code/fuzzing-code.component.html 7ms (unchanged) src/app/features/fuzzing/fuzzing-code/fuzzing-code.component.scss 3ms (unchanged) src/app/features/fuzzing/fuzzing-code/fuzzing-code.component.ts 6ms (unchanged) src/app/features/fuzzing/fuzzing-directories-table/fuzzing-directories-table.component.html 2ms (unchanged) src/app/features/fuzzing/fuzzing-directories-table/fuzzing-directories-table.component.scss 0ms (unchanged) src/app/features/fuzzing/fuzzing-directories-table/fuzzing-directories-table.component.ts 4ms (unchanged) src/app/features/fuzzing/fuzzing-files-table/fuzzing-files-table.component.html 2ms (unchanged) src/app/features/fuzzing/fuzzing-files-table/fuzzing-files-table.component.scss 1ms (unchanged) src/app/features/fuzzing/fuzzing-files-table/fuzzing-files-table.component.ts 5ms (unchanged) src/app/features/fuzzing/fuzzing-toolbar/fuzzing-toolbar.component.html 3ms (unchanged) src/app/features/fuzzing/fuzzing-toolbar/fuzzing-toolbar.component.scss 2ms (unchanged) src/app/features/fuzzing/fuzzing-toolbar/fuzzing-toolbar.component.ts 3ms (unchanged) src/app/features/fuzzing/fuzzing.actions.ts 3ms (unchanged) src/app/features/fuzzing/fuzzing.component.html 3ms (unchanged) src/app/features/fuzzing/fuzzing.component.scss 1ms (unchanged) src/app/features/fuzzing/fuzzing.component.ts 3ms (unchanged) src/app/features/fuzzing/fuzzing.effects.ts 4ms (unchanged) src/app/features/fuzzing/fuzzing.module.ts 1ms (unchanged) src/app/features/fuzzing/fuzzing.reducer.ts 3ms (unchanged) src/app/features/fuzzing/fuzzing.routing.ts 1ms (unchanged) src/app/features/fuzzing/fuzzing.service.ts 8ms (unchanged) src/app/features/fuzzing/fuzzing.state.ts 2ms (unchanged) src/app/features/leaderboard/leaderboard-apply/leaderboard-apply.component.html 1ms (unchanged) src/app/features/leaderboard/leaderboard-apply/leaderboard-apply.component.scss 2ms (unchanged) src/app/features/leaderboard/leaderboard-apply/leaderboard-apply.component.ts 1ms (unchanged) src/app/features/leaderboard/leaderboard-details/leaderboard-details.component.html 1ms (unchanged) src/app/features/leaderboard/leaderboard-details/leaderboard-details.component.scss 2ms (unchanged) src/app/features/leaderboard/leaderboard-details/leaderboard-details.component.ts 1ms (unchanged) src/app/features/leaderboard/leaderboard-filters/leaderboard-filters.component.html 4ms (unchanged) src/app/features/leaderboard/leaderboard-filters/leaderboard-filters.component.scss 4ms (unchanged) src/app/features/leaderboard/leaderboard-filters/leaderboard-filters.component.ts 3ms (unchanged) src/app/features/leaderboard/leaderboard-footer/leaderboard-footer.component.html 2ms (unchanged) src/app/features/leaderboard/leaderboard-footer/leaderboard-footer.component.scss 2ms (unchanged) src/app/features/leaderboard/leaderboard-footer/leaderboard-footer.component.ts 1ms (unchanged) src/app/features/leaderboard/leaderboard-header/leaderboard-header.component.html 3ms (unchanged) src/app/features/leaderboard/leaderboard-header/leaderboard-header.component.scss 2ms (unchanged) src/app/features/leaderboard/leaderboard-header/leaderboard-header.component.ts 2ms (unchanged) src/app/features/leaderboard/leaderboard-impressum/leaderboard-impressum.component.html 1ms (unchanged) src/app/features/leaderboard/leaderboard-impressum/leaderboard-impressum.component.scss 2ms (unchanged) src/app/features/leaderboard/leaderboard-impressum/leaderboard-impressum.component.ts 1ms (unchanged) src/app/features/leaderboard/leaderboard-landing-page/leaderboard-landing-page.component.html 5ms (unchanged) src/app/features/leaderboard/leaderboard-landing-page/leaderboard-landing-page.component.scss 8ms (unchanged) src/app/features/leaderboard/leaderboard-landing-page/leaderboard-landing-page.component.ts 2ms (unchanged) src/app/features/leaderboard/leaderboard-page/leaderboard-page.component.html 6ms (unchanged) src/app/features/leaderboard/leaderboard-page/leaderboard-page.component.scss 3ms (unchanged) src/app/features/leaderboard/leaderboard-page/leaderboard-page.component.ts 4ms (unchanged) src/app/features/leaderboard/leaderboard-privacy-policy/leaderboard-privacy-policy.component.html 1ms (unchanged) src/app/features/leaderboard/leaderboard-privacy-policy/leaderboard-privacy-policy.component.scss 2ms (unchanged) src/app/features/leaderboard/leaderboard-privacy-policy/leaderboard-privacy-policy.component.ts 1ms (unchanged) src/app/features/leaderboard/leaderboard-table/leaderboard-table.component.html 8ms (unchanged) src/app/features/leaderboard/leaderboard-table/leaderboard-table.component.scss 3ms (unchanged) src/app/features/leaderboard/leaderboard-table/leaderboard-table.component.ts 3ms (unchanged) src/app/features/leaderboard/leaderboard-terms-and-conditions/leaderboard-terms-and-conditions.component.html 1ms (unchanged) src/app/features/leaderboard/leaderboard-terms-and-conditions/leaderboard-terms-and-conditions.component.scss 1ms (unchanged) src/app/features/leaderboard/leaderboard-terms-and-conditions/leaderboard-terms-and-conditions.component.ts 1ms (unchanged) src/app/features/leaderboard/leaderboard-title/leaderboard-title.component.html 1ms (unchanged) src/app/features/leaderboard/leaderboard-title/leaderboard-title.component.scss 1ms (unchanged) src/app/features/leaderboard/leaderboard-title/leaderboard-title.component.ts 2ms (unchanged) src/app/features/leaderboard/leaderboard.actions.ts 2ms (unchanged) src/app/features/leaderboard/leaderboard.effects.ts 2ms (unchanged) src/app/features/leaderboard/leaderboard.module.ts 1ms (unchanged) src/app/features/leaderboard/leaderboard.reducer.ts 3ms (unchanged) src/app/features/leaderboard/leaderboard.routing.ts 1ms (unchanged) src/app/features/leaderboard/leaderboard.service.ts 20ms (unchanged) src/app/features/leaderboard/leaderboard.state.ts 2ms (unchanged) src/app/features/mempool/add-transaction/mempool-add-transaction.component.html 1ms (unchanged) src/app/features/mempool/add-transaction/mempool-add-transaction.component.scss 0ms (unchanged) src/app/features/mempool/add-transaction/mempool-add-transaction.component.ts 1ms (unchanged) src/app/features/mempool/filters/mempool-filters.component.html 8ms (unchanged) src/app/features/mempool/filters/mempool-filters.component.scss 2ms (unchanged) src/app/features/mempool/filters/mempool-filters.component.ts 4ms (unchanged) src/app/features/mempool/mempool.actions.ts 2ms (unchanged) src/app/features/mempool/mempool.component.html 2ms (unchanged) src/app/features/mempool/mempool.component.scss 0ms (unchanged) src/app/features/mempool/mempool.component.ts 2ms (unchanged) src/app/features/mempool/mempool.effects.ts 3ms (unchanged) src/app/features/mempool/mempool.module.ts 1ms (unchanged) src/app/features/mempool/mempool.reducer.ts 3ms (unchanged) src/app/features/mempool/mempool.routing.ts 1ms (unchanged) src/app/features/mempool/mempool.service.ts 4ms (unchanged) src/app/features/mempool/mempool.state.ts 2ms (unchanged) src/app/features/mempool/side-panel/mempool-side-panel.component.html 4ms (unchanged) src/app/features/mempool/side-panel/mempool-side-panel.component.scss 0ms (unchanged) src/app/features/mempool/side-panel/mempool-side-panel.component.ts 3ms (unchanged) src/app/features/mempool/table/mempool-table.component.html 7ms (unchanged) src/app/features/mempool/table/mempool-table.component.scss 2ms (unchanged) src/app/features/mempool/table/mempool-table.component.ts 5ms (unchanged) src/app/features/mempool/warnings/mempool-warnings.component.html 1ms (unchanged) src/app/features/mempool/warnings/mempool-warnings.component.scss 0ms (unchanged) src/app/features/mempool/warnings/mempool-warnings.component.ts 1ms (unchanged) src/app/features/network/blocks/network-blocks-graph/network-blocks-graph.component.html 0ms (unchanged) src/app/features/network/blocks/network-blocks-graph/network-blocks-graph.component.scss 0ms (unchanged) src/app/features/network/blocks/network-blocks-graph/network-blocks-graph.component.ts 3ms (unchanged) src/app/features/network/blocks/network-blocks-side-panel/network-blocks-side-panel.component.html 2ms (unchanged) src/app/features/network/blocks/network-blocks-side-panel/network-blocks-side-panel.component.scss 1ms (unchanged) src/app/features/network/blocks/network-blocks-side-panel/network-blocks-side-panel.component.ts 2ms (unchanged) src/app/features/network/blocks/network-blocks-table/network-blocks-table.component.html 8ms (unchanged) src/app/features/network/blocks/network-blocks-table/network-blocks-table.component.scss 1ms (unchanged) src/app/features/network/blocks/network-blocks-table/network-blocks-table.component.ts 3ms (unchanged) src/app/features/network/blocks/network-blocks-toolbar/network-blocks-toolbar.component.html 7ms (unchanged) src/app/features/network/blocks/network-blocks-toolbar/network-blocks-toolbar.component.scss 1ms (unchanged) src/app/features/network/blocks/network-blocks-toolbar/network-blocks-toolbar.component.ts 3ms (unchanged) src/app/features/network/blocks/network-blocks.actions.ts 3ms (unchanged) src/app/features/network/blocks/network-blocks.component.html 2ms (unchanged) src/app/features/network/blocks/network-blocks.component.scss 0ms (unchanged) src/app/features/network/blocks/network-blocks.component.ts 3ms (unchanged) src/app/features/network/blocks/network-blocks.effects.ts 7ms (unchanged) src/app/features/network/blocks/network-blocks.module.ts 1ms (unchanged) src/app/features/network/blocks/network-blocks.reducer.ts 4ms (unchanged) src/app/features/network/blocks/network-blocks.routing.ts 1ms (unchanged) src/app/features/network/blocks/network-blocks.service.ts 4ms (unchanged) src/app/features/network/blocks/network-blocks.state.ts 2ms (unchanged) src/app/features/network/bootstrap-stats/network-bootstrap-stats.actions.ts 2ms (unchanged) src/app/features/network/bootstrap-stats/network-bootstrap-stats.component.html 2ms (unchanged) src/app/features/network/bootstrap-stats/network-bootstrap-stats.component.scss 0ms (unchanged) src/app/features/network/bootstrap-stats/network-bootstrap-stats.component.ts 2ms (unchanged) src/app/features/network/bootstrap-stats/network-bootstrap-stats.effects.ts 3ms (unchanged) src/app/features/network/bootstrap-stats/network-bootstrap-stats.module.ts 1ms (unchanged) src/app/features/network/bootstrap-stats/network-bootstrap-stats.reducer.ts 2ms (unchanged) src/app/features/network/bootstrap-stats/network-bootstrap-stats.routing.ts 1ms (unchanged) src/app/features/network/bootstrap-stats/network-bootstrap-stats.service.ts 3ms (unchanged) src/app/features/network/bootstrap-stats/network-bootstrap-stats.state.ts 2ms (unchanged) src/app/features/network/bootstrap-stats/side-panel/network-bootstrap-stats-side-panel.component.html 8ms (unchanged) src/app/features/network/bootstrap-stats/side-panel/network-bootstrap-stats-side-panel.component.scss 2ms (unchanged) src/app/features/network/bootstrap-stats/side-panel/network-bootstrap-stats-side-panel.component.ts 3ms (unchanged) src/app/features/network/bootstrap-stats/table/network-bootstrap-stats-table.component.html 8ms (unchanged) src/app/features/network/bootstrap-stats/table/network-bootstrap-stats-table.component.scss 0ms (unchanged) src/app/features/network/bootstrap-stats/table/network-bootstrap-stats-table.component.ts 4ms (unchanged) src/app/features/network/connections/network-connections-side-panel/network-connections-side-panel.component.html 4ms (unchanged) src/app/features/network/connections/network-connections-side-panel/network-connections-side-panel.component.scss 0ms (unchanged) src/app/features/network/connections/network-connections-side-panel/network-connections-side-panel.component.ts 2ms (unchanged) src/app/features/network/connections/network-connections-table/network-connections-table.component.html 5ms (unchanged) src/app/features/network/connections/network-connections-table/network-connections-table.component.scss 0ms (unchanged) src/app/features/network/connections/network-connections-table/network-connections-table.component.ts 4ms (unchanged) src/app/features/network/connections/network-connections.actions.ts 2ms (unchanged) src/app/features/network/connections/network-connections.component.html 2ms (unchanged) src/app/features/network/connections/network-connections.component.scss 0ms (unchanged) src/app/features/network/connections/network-connections.component.ts 2ms (unchanged) src/app/features/network/connections/network-connections.effects.ts 4ms (unchanged) src/app/features/network/connections/network-connections.module.ts 1ms (unchanged) src/app/features/network/connections/network-connections.reducer.ts 2ms (unchanged) src/app/features/network/connections/network-connections.routing.ts 2ms (unchanged) src/app/features/network/connections/network-connections.service.ts 3ms (unchanged) src/app/features/network/connections/network-connections.state.ts 1ms (unchanged) src/app/features/network/dht-graph/dht-graph.component.html 0ms (unchanged) src/app/features/network/dht-graph/dht-graph.component.scss 0ms (unchanged) src/app/features/network/dht-graph/dht-graph.component.ts 1ms (unchanged) src/app/features/network/dht-graph/dht-graph.module.ts 1ms (unchanged) src/app/features/network/dht-graph/dht-graph.routing.ts 1ms (unchanged) src/app/features/network/dht-graph/network-dht-graph-binary-tree/equal-distance-algorithm.ts 8ms (unchanged) src/app/features/network/dht-graph/network-dht-graph-binary-tree/minimum-distance-algorithm.ts 4ms (unchanged) src/app/features/network/dht-graph/network-dht-graph-binary-tree/network-dht-graph-binary-tree.component.html 1ms (unchanged) src/app/features/network/dht-graph/network-dht-graph-binary-tree/network-dht-graph-binary-tree.component.scss 1ms (unchanged) src/app/features/network/dht-graph/network-dht-graph-binary-tree/network-dht-graph-binary-tree.component.ts 15ms (unchanged) src/app/features/network/messages/network-messages-filters/network-messages-filters.component.html 9ms (unchanged) src/app/features/network/messages/network-messages-filters/network-messages-filters.component.scss 2ms (unchanged) src/app/features/network/messages/network-messages-filters/network-messages-filters.component.ts 10ms (unchanged) src/app/features/network/messages/network-messages-side-panel/network-messages-side-panel.component.html 13ms (unchanged) src/app/features/network/messages/network-messages-side-panel/network-messages-side-panel.component.scss 1ms (unchanged) src/app/features/network/messages/network-messages-side-panel/network-messages-side-panel.component.ts 6ms (unchanged) src/app/features/network/messages/network-messages-table-footer/network-messages-table-footer.component.html 7ms (unchanged) src/app/features/network/messages/network-messages-table-footer/network-messages-table-footer.component.scss 1ms (unchanged) src/app/features/network/messages/network-messages-table-footer/network-messages-table-footer.component.ts 10ms (unchanged) src/app/features/network/messages/network-messages-table/network-messages-table.component.html 5ms (unchanged) src/app/features/network/messages/network-messages-table/network-messages-table.component.scss 1ms (unchanged) src/app/features/network/messages/network-messages-table/network-messages-table.component.ts 10ms (unchanged) src/app/features/network/messages/network-messages.actions.ts 5ms (unchanged) src/app/features/network/messages/network-messages.component.html 3ms (unchanged) src/app/features/network/messages/network-messages.component.scss 0ms (unchanged) src/app/features/network/messages/network-messages.component.ts 3ms (unchanged) src/app/features/network/messages/network-messages.effects.ts 9ms (unchanged) src/app/features/network/messages/network-messages.module.ts 1ms (unchanged) src/app/features/network/messages/network-messages.reducer.ts 5ms (unchanged) src/app/features/network/messages/network-messages.routing.ts 1ms (unchanged) src/app/features/network/messages/network-messages.service.ts 6ms (unchanged) src/app/features/network/messages/network-messages.state.ts 2ms (unchanged) src/app/features/network/network.component.html 0ms (unchanged) src/app/features/network/network.component.scss 0ms (unchanged) src/app/features/network/network.component.ts 1ms (unchanged) src/app/features/network/network.guard.ts 2ms (unchanged) src/app/features/network/network.module.ts 1ms (unchanged) src/app/features/network/network.reducer.ts 1ms (unchanged) src/app/features/network/network.routing.ts 2ms (unchanged) src/app/features/network/network.state.ts 2ms (unchanged) src/app/features/network/node-dht/network-node-dht-line/network-node-dht-line.component.html 5ms (unchanged) src/app/features/network/node-dht/network-node-dht-line/network-node-dht-line.component.scss 3ms (unchanged) src/app/features/network/node-dht/network-node-dht-line/network-node-dht-line.component.ts 6ms (unchanged) src/app/features/network/node-dht/network-node-dht-side-panel/network-node-dht-side-panel.component.html 4ms (unchanged) src/app/features/network/node-dht/network-node-dht-side-panel/network-node-dht-side-panel.component.scss 0ms (unchanged) src/app/features/network/node-dht/network-node-dht-side-panel/network-node-dht-side-panel.component.ts 3ms (unchanged) src/app/features/network/node-dht/network-node-dht-table/network-node-dht-table.component.html 5ms (unchanged) src/app/features/network/node-dht/network-node-dht-table/network-node-dht-table.component.scss 1ms (unchanged) src/app/features/network/node-dht/network-node-dht-table/network-node-dht-table.component.ts 4ms (unchanged) src/app/features/network/node-dht/network-node-dht.actions.ts 2ms (unchanged) src/app/features/network/node-dht/network-node-dht.component.html 2ms (unchanged) src/app/features/network/node-dht/network-node-dht.component.scss 0ms (unchanged) src/app/features/network/node-dht/network-node-dht.component.ts 2ms (unchanged) src/app/features/network/node-dht/network-node-dht.effects.ts 3ms (unchanged) src/app/features/network/node-dht/network-node-dht.module.ts 1ms (unchanged) src/app/features/network/node-dht/network-node-dht.reducer.ts 2ms (unchanged) src/app/features/network/node-dht/network-node-dht.routing.ts 1ms (unchanged) src/app/features/network/node-dht/network-node-dht.service.ts 4ms (unchanged) src/app/features/network/node-dht/network-node-dht.state.ts 2ms (unchanged) src/app/features/network/splits/dashboard-splits-graph/dashboard-splits-graph.component.html 2ms (unchanged) src/app/features/network/splits/dashboard-splits-graph/dashboard-splits-graph.component.scss 1ms (unchanged) src/app/features/network/splits/dashboard-splits-graph/dashboard-splits-graph.component.ts 31ms (unchanged) src/app/features/network/splits/dashboard-splits-side-panel-table/dashboard-splits-side-panel-table.component.html 3ms (unchanged) src/app/features/network/splits/dashboard-splits-side-panel-table/dashboard-splits-side-panel-table.component.scss 1ms (unchanged) src/app/features/network/splits/dashboard-splits-side-panel-table/dashboard-splits-side-panel-table.component.ts 3ms (unchanged) src/app/features/network/splits/dashboard-splits-side-panel/dashboard-splits-side-panel.component.html 5ms (unchanged) src/app/features/network/splits/dashboard-splits-side-panel/dashboard-splits-side-panel.component.scss 0ms (unchanged) src/app/features/network/splits/dashboard-splits-side-panel/dashboard-splits-side-panel.component.ts 5ms (unchanged) src/app/features/network/splits/dashboard-splits-toolbar/dashboard-splits-toolbar.component.html 6ms (unchanged) src/app/features/network/splits/dashboard-splits-toolbar/dashboard-splits-toolbar.component.scss 0ms (unchanged) src/app/features/network/splits/dashboard-splits-toolbar/dashboard-splits-toolbar.component.ts 3ms (unchanged) src/app/features/network/splits/dashboard-splits.actions.ts 3ms (unchanged) src/app/features/network/splits/dashboard-splits.component.html 2ms (unchanged) src/app/features/network/splits/dashboard-splits.component.scss 0ms (unchanged) src/app/features/network/splits/dashboard-splits.component.ts 2ms (unchanged) src/app/features/network/splits/dashboard-splits.effects.ts 3ms (unchanged) src/app/features/network/splits/dashboard-splits.module.ts 1ms (unchanged) src/app/features/network/splits/dashboard-splits.reducer.ts 9ms (unchanged) src/app/features/network/splits/dashboard-splits.routing.ts 1ms (unchanged) src/app/features/network/splits/dashboard-splits.service.ts 18ms (unchanged) src/app/features/network/splits/dashboard-splits.state.ts 3ms (unchanged) src/app/features/network/splits/mock.ts 2ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap-blocks/nodes-bootstrap-blocks.component.html 5ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap-blocks/nodes-bootstrap-blocks.component.scss 2ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap-blocks/nodes-bootstrap-blocks.component.ts 3ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap-overview/nodes-bootstrap-overview.component.html 4ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap-overview/nodes-bootstrap-overview.component.scss 1ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap-overview/nodes-bootstrap-overview.component.ts 5ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap-side-panel/nodes-bootstrap-side-panel.component.html 5ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap-side-panel/nodes-bootstrap-side-panel.component.scss 1ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap-side-panel/nodes-bootstrap-side-panel.component.ts 3ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap-table/nodes-bootstrap-table.component.html 6ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap-table/nodes-bootstrap-table.component.scss 2ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap-table/nodes-bootstrap-table.component.ts 5ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap.actions.ts 2ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap.component.html 2ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap.component.scss 0ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap.component.ts 2ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap.effects.ts 3ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap.module.ts 1ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap.reducer.ts 2ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap.routing.ts 1ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap.service.ts 3ms (unchanged) src/app/features/nodes/bootstrap/nodes-bootstrap.state.ts 2ms (unchanged) src/app/features/nodes/live/nodes-live-blocks-map/nodes-live-blocks-map.component.html 4ms (unchanged) src/app/features/nodes/live/nodes-live-blocks-map/nodes-live-blocks-map.component.scss 4ms (unchanged) src/app/features/nodes/live/nodes-live-blocks-map/nodes-live-blocks-map.component.ts 2ms (unchanged) src/app/features/nodes/live/nodes-live-events-table/nodes-live-events-table.component.html 3ms (unchanged) src/app/features/nodes/live/nodes-live-events-table/nodes-live-events-table.component.scss 1ms (unchanged) src/app/features/nodes/live/nodes-live-events-table/nodes-live-events-table.component.ts 2ms (unchanged) src/app/features/nodes/live/nodes-live-filters/nodes-live-filters.component.html 2ms (unchanged) src/app/features/nodes/live/nodes-live-filters/nodes-live-filters.component.scss 1ms (unchanged) src/app/features/nodes/live/nodes-live-filters/nodes-live-filters.component.ts 2ms (unchanged) src/app/features/nodes/live/nodes-live-status-counts/nodes-live-status-counts.component.html 3ms (unchanged) src/app/features/nodes/live/nodes-live-status-counts/nodes-live-status-counts.component.scss 1ms (unchanged) src/app/features/nodes/live/nodes-live-status-counts/nodes-live-status-counts.component.ts 2ms (unchanged) src/app/features/nodes/live/nodes-live-toolbar/nodes-live-toolbar.component.html 6ms (unchanged) src/app/features/nodes/live/nodes-live-toolbar/nodes-live-toolbar.component.scss 1ms (unchanged) src/app/features/nodes/live/nodes-live-toolbar/nodes-live-toolbar.component.ts 3ms (unchanged) src/app/features/nodes/live/nodes-live.actions.ts 3ms (unchanged) src/app/features/nodes/live/nodes-live.component.html 2ms (unchanged) src/app/features/nodes/live/nodes-live.component.scss 0ms (unchanged) src/app/features/nodes/live/nodes-live.component.ts 2ms (unchanged) src/app/features/nodes/live/nodes-live.effects.ts 3ms (unchanged) src/app/features/nodes/live/nodes-live.module.ts 1ms (unchanged) src/app/features/nodes/live/nodes-live.reducer.ts 3ms (unchanged) src/app/features/nodes/live/nodes-live.routing.ts 1ms (unchanged) src/app/features/nodes/live/nodes-live.service.ts 3ms (unchanged) src/app/features/nodes/live/nodes-live.state.ts 2ms (unchanged) src/app/features/nodes/nodes.component.html 1ms (unchanged) src/app/features/nodes/nodes.component.scss 0ms (unchanged) src/app/features/nodes/nodes.component.ts 1ms (unchanged) src/app/features/nodes/nodes.module.ts 1ms (unchanged) src/app/features/nodes/nodes.reducer.ts 1ms (unchanged) src/app/features/nodes/nodes.routing.ts 2ms (unchanged) src/app/features/nodes/nodes.state.ts 1ms (unchanged) src/app/features/nodes/overview/nodes-overview-ledgers/nodes-overview-ledgers.component.html 19ms (unchanged) src/app/features/nodes/overview/nodes-overview-ledgers/nodes-overview-ledgers.component.scss 3ms (unchanged) src/app/features/nodes/overview/nodes-overview-ledgers/nodes-overview-ledgers.component.ts 3ms (unchanged) src/app/features/nodes/overview/nodes-overview-side-panel/nodes-overview-side-panel.component.html 5ms (unchanged) src/app/features/nodes/overview/nodes-overview-side-panel/nodes-overview-side-panel.component.scss 3ms (unchanged) src/app/features/nodes/overview/nodes-overview-side-panel/nodes-overview-side-panel.component.ts 4ms (unchanged) src/app/features/nodes/overview/nodes-overview-table/nodes-overview-table.component.html 7ms (unchanged) src/app/features/nodes/overview/nodes-overview-table/nodes-overview-table.component.scss 1ms (unchanged) src/app/features/nodes/overview/nodes-overview-table/nodes-overview-table.component.ts 4ms (unchanged) src/app/features/nodes/overview/nodes-overview-toolbar/nodes-overview-toolbar.component.html 3ms (unchanged) src/app/features/nodes/overview/nodes-overview-toolbar/nodes-overview-toolbar.component.scss 1ms (unchanged) src/app/features/nodes/overview/nodes-overview-toolbar/nodes-overview-toolbar.component.ts 1ms (unchanged) src/app/features/nodes/overview/nodes-overview.actions.ts 2ms (unchanged) src/app/features/nodes/overview/nodes-overview.component.html 2ms (unchanged) src/app/features/nodes/overview/nodes-overview.component.scss 0ms (unchanged) src/app/features/nodes/overview/nodes-overview.component.ts 2ms (unchanged) src/app/features/nodes/overview/nodes-overview.effects.ts 3ms (unchanged) src/app/features/nodes/overview/nodes-overview.module.ts 1ms (unchanged) src/app/features/nodes/overview/nodes-overview.reducer.ts 2ms (unchanged) src/app/features/nodes/overview/nodes-overview.routing.ts 1ms (unchanged) src/app/features/nodes/overview/nodes-overview.service.ts 8ms (unchanged) src/app/features/nodes/overview/nodes-overview.state.ts 1ms (unchanged) src/app/features/resources/memory/memory-resources-table/memory-resources-table.component.html 7ms (unchanged) src/app/features/resources/memory/memory-resources-table/memory-resources-table.component.scss 2ms (unchanged) src/app/features/resources/memory/memory-resources-table/memory-resources-table.component.ts 4ms (unchanged) src/app/features/resources/memory/memory-resources-toolbar/memory-resources-toolbar.component.html 6ms (unchanged) src/app/features/resources/memory/memory-resources-toolbar/memory-resources-toolbar.component.scss 1ms (unchanged) src/app/features/resources/memory/memory-resources-toolbar/memory-resources-toolbar.component.ts 4ms (unchanged) src/app/features/resources/memory/memory-resources-treemap/memory-resources-treemap.component.html 0ms (unchanged) src/app/features/resources/memory/memory-resources-treemap/memory-resources-treemap.component.scss 2ms (unchanged) src/app/features/resources/memory/memory-resources-treemap/memory-resources-treemap.component.ts 23ms (unchanged) src/app/features/resources/memory/memory-resources.actions.ts 2ms (unchanged) src/app/features/resources/memory/memory-resources.component.html 3ms (unchanged) src/app/features/resources/memory/memory-resources.component.scss 1ms (unchanged) src/app/features/resources/memory/memory-resources.component.ts 2ms (unchanged) src/app/features/resources/memory/memory-resources.effects.ts 2ms (unchanged) src/app/features/resources/memory/memory-resources.module.ts 1ms (unchanged) src/app/features/resources/memory/memory-resources.pipe.ts 1ms (unchanged) src/app/features/resources/memory/memory-resources.reducer.ts 4ms (unchanged) src/app/features/resources/memory/memory-resources.routing.ts 1ms (unchanged) src/app/features/resources/memory/memory-resources.service.ts 4ms (unchanged) src/app/features/resources/memory/memory-resources.state.ts 2ms (unchanged) src/app/features/resources/resources.component.html 1ms (unchanged) src/app/features/resources/resources.component.scss 0ms (unchanged) src/app/features/resources/resources.component.ts 1ms (unchanged) src/app/features/resources/resources.module.ts 1ms (unchanged) src/app/features/resources/resources.reducer.ts 1ms (unchanged) src/app/features/resources/resources.routing.ts 1ms (unchanged) src/app/features/resources/resources.state.ts 1ms (unchanged) src/app/features/snarks/scan-state/scan-state-details/scan-state-details.component.html 1ms (unchanged) src/app/features/snarks/scan-state/scan-state-details/scan-state-details.component.scss 0ms (unchanged) src/app/features/snarks/scan-state/scan-state-details/scan-state-details.component.ts 1ms (unchanged) src/app/features/snarks/scan-state/scan-state-job-details/scan-state-job-details.component.html 1ms (unchanged) src/app/features/snarks/scan-state/scan-state-job-details/scan-state-job-details.component.scss 0ms (unchanged) src/app/features/snarks/scan-state/scan-state-job-details/scan-state-job-details.component.ts 2ms (unchanged) src/app/features/snarks/scan-state/scan-state-side-panel/scan-state-side-panel.component.html 16ms (unchanged) src/app/features/snarks/scan-state/scan-state-side-panel/scan-state-side-panel.component.scss 1ms (unchanged) src/app/features/snarks/scan-state/scan-state-side-panel/scan-state-side-panel.component.ts 5ms (unchanged) src/app/features/snarks/scan-state/scan-state-toolbar/scan-state-toolbar.component.html 11ms (unchanged) src/app/features/snarks/scan-state/scan-state-toolbar/scan-state-toolbar.component.scss 3ms (unchanged) src/app/features/snarks/scan-state/scan-state-toolbar/scan-state-toolbar.component.ts 6ms (unchanged) src/app/features/snarks/scan-state/scan-state-tree-chart/scan-state-tree-chart.component.html 2ms (unchanged) src/app/features/snarks/scan-state/scan-state-tree-chart/scan-state-tree-chart.component.scss 1ms (unchanged) src/app/features/snarks/scan-state/scan-state-tree-chart/scan-state-tree-chart.component.ts 26ms (unchanged) src/app/features/snarks/scan-state/scan-state-tree-list/scan-state-tree-list.component.html 14ms (unchanged) src/app/features/snarks/scan-state/scan-state-tree-list/scan-state-tree-list.component.scss 2ms (unchanged) src/app/features/snarks/scan-state/scan-state-tree-list/scan-state-tree-list.component.ts 7ms (unchanged) src/app/features/snarks/scan-state/scan-state.actions.ts 3ms (unchanged) src/app/features/snarks/scan-state/scan-state.component.html 3ms (unchanged) src/app/features/snarks/scan-state/scan-state.component.scss 0ms (unchanged) src/app/features/snarks/scan-state/scan-state.component.ts 4ms (unchanged) src/app/features/snarks/scan-state/scan-state.effects.ts 4ms (unchanged) src/app/features/snarks/scan-state/scan-state.module.ts 1ms (unchanged) src/app/features/snarks/scan-state/scan-state.reducer.ts 3ms (unchanged) src/app/features/snarks/scan-state/scan-state.routing.ts 1ms (unchanged) src/app/features/snarks/scan-state/scan-state.service.ts 6ms (unchanged) src/app/features/snarks/scan-state/scan-state.state.ts 2ms (unchanged) src/app/features/snarks/snarks.component.html 1ms (unchanged) src/app/features/snarks/snarks.component.scss 0ms (unchanged) src/app/features/snarks/snarks.component.ts 1ms (unchanged) src/app/features/snarks/snarks.module.ts 1ms (unchanged) src/app/features/snarks/snarks.reducer.ts 1ms (unchanged) src/app/features/snarks/snarks.routing.ts 2ms (unchanged) src/app/features/snarks/snarks.state.ts 1ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-details-accounts/snarks-work-pool-details-accounts.component.html 3ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-details-accounts/snarks-work-pool-details-accounts.component.scss 1ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-details-accounts/snarks-work-pool-details-accounts.component.ts 3ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-details-overview/snarks-work-pool-details-overview.component.html 1ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-details-overview/snarks-work-pool-details-overview.component.scss 0ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-details-overview/snarks-work-pool-details-overview.component.ts 1ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-details-specs/snarks-work-pool-details-specs.component.html 1ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-details-specs/snarks-work-pool-details-specs.component.scss 0ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-details-specs/snarks-work-pool-details-specs.component.ts 2ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-details/snarks-work-pool-details.component.html 4ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-details/snarks-work-pool-details.component.scss 1ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-details/snarks-work-pool-details.component.ts 4ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-side-panel/snarks-work-pool-side-panel.component.html 4ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-side-panel/snarks-work-pool-side-panel.component.scss 0ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-side-panel/snarks-work-pool-side-panel.component.ts 4ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-statistics/snarks-work-pool-statistics.component.html 2ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-statistics/snarks-work-pool-statistics.component.scss 0ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-statistics/snarks-work-pool-statistics.component.ts 3ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-table/snarks-work-pool-table.component.html 8ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-table/snarks-work-pool-table.component.scss 2ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-table/snarks-work-pool-table.component.ts 5ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-toolbar/snarks-work-pool-toolbar.component.html 4ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-toolbar/snarks-work-pool-toolbar.component.scss 1ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool-toolbar/snarks-work-pool-toolbar.component.ts 2ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool.actions.ts 3ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool.component.html 2ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool.component.scss 0ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool.component.ts 2ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool.effects.ts 5ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool.module.ts 1ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool.reducer.ts 3ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool.routing.ts 1ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool.service.ts 4ms (unchanged) src/app/features/snarks/work-pool/snarks-work-pool.state.ts 2ms (unchanged) src/app/features/state/actions/state-actions-graph-list/state-actions-graph-list.component.html 6ms (unchanged) src/app/features/state/actions/state-actions-graph-list/state-actions-graph-list.component.scss 1ms (unchanged) src/app/features/state/actions/state-actions-graph-list/state-actions-graph-list.component.ts 3ms (unchanged) src/app/features/state/actions/state-actions-side-panel/state-actions-side-panel.component.html 7ms (unchanged) src/app/features/state/actions/state-actions-side-panel/state-actions-side-panel.component.scss 1ms (unchanged) src/app/features/state/actions/state-actions-side-panel/state-actions-side-panel.component.ts 4ms (unchanged) src/app/features/state/actions/state-actions-toolbar/state-actions-toolbar.component.html 10ms (unchanged) src/app/features/state/actions/state-actions-toolbar/state-actions-toolbar.component.scss 2ms (unchanged) src/app/features/state/actions/state-actions-toolbar/state-actions-toolbar.component.ts 4ms (unchanged) src/app/features/state/actions/state-actions.actions.ts 3ms (unchanged) src/app/features/state/actions/state-actions.component.html 2ms (unchanged) src/app/features/state/actions/state-actions.component.scss 0ms (unchanged) src/app/features/state/actions/state-actions.component.ts 3ms (unchanged) src/app/features/state/actions/state-actions.effects.ts 4ms (unchanged) src/app/features/state/actions/state-actions.module.ts 1ms (unchanged) src/app/features/state/actions/state-actions.reducer.ts 3ms (unchanged) src/app/features/state/actions/state-actions.routing.ts 1ms (unchanged) src/app/features/state/actions/state-actions.service.ts 11ms (unchanged) src/app/features/state/actions/state-actions.state.ts 3ms (unchanged) src/app/features/state/state.component.html 0ms (unchanged) src/app/features/state/state.component.scss 0ms (unchanged) src/app/features/state/state.component.ts 1ms (unchanged) src/app/features/state/state.module.ts 1ms (unchanged) src/app/features/state/state.reducer.ts 1ms (unchanged) src/app/features/state/state.routing.ts 1ms (unchanged) src/app/features/state/state.state.ts 1ms (unchanged) src/app/features/web-node/web-node-file-upload/web-node-file-upload.component.html 8ms (unchanged) src/app/features/web-node/web-node-file-upload/web-node-file-upload.component.scss 2ms (unchanged) src/app/features/web-node/web-node-file-upload/web-node-file-upload.component.ts 6ms (unchanged) src/app/features/web-node/web-node-initialization/web-node-initialization.component.html 6ms (unchanged) src/app/features/web-node/web-node-initialization/web-node-initialization.component.scss 3ms (unchanged) src/app/features/web-node/web-node-initialization/web-node-initialization.component.ts 16ms (unchanged) src/app/features/web-node/web-node-not-supported/web-node-not-supported.component.html 5ms (unchanged) src/app/features/web-node/web-node-not-supported/web-node-not-supported.component.scss 2ms (unchanged) src/app/features/web-node/web-node-not-supported/web-node-not-supported.component.ts 3ms (unchanged) src/app/features/web-node/web-node.component.html 2ms (unchanged) src/app/features/web-node/web-node.component.scss 0ms (unchanged) src/app/features/web-node/web-node.component.ts 3ms (unchanged) src/app/features/web-node/web-node.module.ts 1ms (unchanged) src/app/features/web-node/web-node.routing.ts 1ms (unchanged) src/app/layout/block-production-pill/block-production-pill.component.html 3ms (unchanged) src/app/layout/block-production-pill/block-production-pill.component.scss 5ms (unchanged) src/app/layout/block-production-pill/block-production-pill.component.ts 4ms (unchanged) src/app/layout/env-build-modal/env-build-modal.component.html 2ms (unchanged) src/app/layout/env-build-modal/env-build-modal.component.scss 0ms (unchanged) src/app/layout/env-build-modal/env-build-modal.component.ts 1ms (unchanged) src/app/layout/error-preview/error-list/error-list.component.html 4ms (unchanged) src/app/layout/error-preview/error-list/error-list.component.scss 1ms (unchanged) src/app/layout/error-preview/error-list/error-list.component.ts 2ms (unchanged) src/app/layout/error-preview/error-preview.actions.ts 1ms (unchanged) src/app/layout/error-preview/error-preview.component.html 3ms (unchanged) src/app/layout/error-preview/error-preview.component.scss 1ms (unchanged) src/app/layout/error-preview/error-preview.component.ts 4ms (unchanged) src/app/layout/error-preview/error-preview.reducer.ts 1ms (unchanged) src/app/layout/error-preview/error-preview.state.ts 1ms (unchanged) src/app/layout/menu-tabs/menu-tabs.component.html 9ms (unchanged) src/app/layout/menu-tabs/menu-tabs.component.scss 1ms (unchanged) src/app/layout/menu-tabs/menu-tabs.component.ts 6ms (unchanged) src/app/layout/menu/menu.component.html 13ms (unchanged) src/app/layout/menu/menu.component.scss 6ms (unchanged) src/app/layout/menu/menu.component.ts 7ms (unchanged) src/app/layout/new-node/new-node.component.html 8ms (unchanged) src/app/layout/new-node/new-node.component.scss 1ms (unchanged) src/app/layout/new-node/new-node.component.ts 7ms (unchanged) src/app/layout/node-picker/node-picker.component.html 8ms (unchanged) src/app/layout/node-picker/node-picker.component.scss 2ms (unchanged) src/app/layout/node-picker/node-picker.component.ts 4ms (unchanged) src/app/layout/server-status/server-status.component.html 18ms (unchanged) src/app/layout/server-status/server-status.component.scss 5ms (unchanged) src/app/layout/server-status/server-status.component.ts 8ms (unchanged) src/app/layout/submenu-tabs/submenu-tabs.component.html 4ms (unchanged) src/app/layout/submenu-tabs/submenu-tabs.component.scss 1ms (unchanged) src/app/layout/submenu-tabs/submenu-tabs.component.ts 4ms (unchanged) src/app/layout/toolbar/loading.reducer.ts 4ms (unchanged) src/app/layout/toolbar/toolbar.component.html 4ms (unchanged) src/app/layout/toolbar/toolbar.component.scss 2ms (unchanged) src/app/layout/toolbar/toolbar.component.ts 4ms (unchanged) src/app/layout/uptime-pill/uptime-pill.component.html 2ms (unchanged) src/app/layout/uptime-pill/uptime-pill.component.scss 2ms (unchanged) src/app/layout/uptime-pill/uptime-pill.component.ts 2ms (unchanged) src/app/layout/web-node-landing-page/web-node-landing-page.component.html 4ms (unchanged) src/app/layout/web-node-landing-page/web-node-landing-page.component.scss 6ms (unchanged) src/app/layout/web-node-landing-page/web-node-landing-page.component.ts 2ms (unchanged) src/app/shared/base-classes/mina-rust-base.effect.ts 2ms (unchanged) src/app/shared/base-classes/mina-table-rust-wrapper.class.ts 1ms (unchanged) src/app/shared/base-classes/mina-table-wrapper.class.ts 2ms (unchanged) src/app/shared/base-classes/store-dispatcher.class.ts 1ms (unchanged) src/app/shared/components/mina-card/mina-card.component.html 3ms (unchanged) src/app/shared/components/mina-card/mina-card.component.scss 1ms (unchanged) src/app/shared/components/mina-card/mina-card.component.ts 1ms (unchanged) src/app/shared/components/mina-table/mina-table.component.html 9ms (unchanged) src/app/shared/components/mina-table/mina-table.component.scss 6ms (unchanged) src/app/shared/components/mina-table/mina-table.component.ts 8ms (unchanged) src/app/shared/constants/config.ts 3ms (unchanged) src/app/shared/constants/mina.ts 0ms (unchanged) src/app/shared/constants/store-functions.ts 5ms (unchanged) src/app/shared/enums/routes.enum.ts 1ms (unchanged) src/app/shared/guards/landing-page.guard.ts 2ms (unchanged) src/app/shared/helpers/date.helper.ts 4ms (unchanged) src/app/shared/helpers/ledger.helper.ts 11ms (unchanged) src/app/shared/helpers/mina.helper.ts 1ms (unchanged) src/app/shared/helpers/transaction.helper.ts 2ms (unchanged) src/app/shared/helpers/webnode.helper.ts 2ms (unchanged) src/app/shared/loading-spinner/loading-spinner.component.html 1ms (unchanged) src/app/shared/loading-spinner/loading-spinner.component.scss 1ms (unchanged) src/app/shared/loading-spinner/loading-spinner.component.ts 1ms (unchanged) src/app/shared/pagination/pagination.component.html 6ms (unchanged) src/app/shared/pagination/pagination.component.scss 1ms (unchanged) src/app/shared/pagination/pagination.component.ts 3ms (unchanged) src/app/shared/shared.module.ts 1ms (unchanged) src/app/shared/types/app/app-env-build.type.ts 1ms (unchanged) src/app/shared/types/app/app-menu.type.ts 1ms (unchanged) src/app/shared/types/app/app-node-details.type.ts 1ms (unchanged) src/app/shared/types/benchmarks/transactions/benchmarks-transaction.type.ts 1ms (unchanged) src/app/shared/types/benchmarks/transactions/benchmarks-zkapp.type.ts 1ms (unchanged) src/app/shared/types/benchmarks/wallets/benchmarks-mempool-tx.type.ts 1ms (unchanged) src/app/shared/types/benchmarks/wallets/benchmarks-wallet-transaction.type.ts 1ms (unchanged) src/app/shared/types/benchmarks/wallets/benchmarks-wallet.type.ts 1ms (unchanged) src/app/shared/types/benchmarks/wallets/sent-transactions-stats.type.ts 1ms (unchanged) src/app/shared/types/block-production/overview/block-production-overview-all-stats.type.ts 1ms (unchanged) src/app/shared/types/block-production/overview/block-production-overview-epoch-details.type.ts 1ms (unchanged) src/app/shared/types/block-production/overview/block-production-overview-epoch.type.ts 1ms (unchanged) src/app/shared/types/block-production/overview/block-production-overview-filters.type.ts 1ms (unchanged) src/app/shared/types/block-production/overview/block-production-overview-slot.type.ts 1ms (unchanged) src/app/shared/types/block-production/overview/block-production-overview-window.type.ts 1ms (unchanged) src/app/shared/types/block-production/won-slots/block-production-won-slots-epoch.type.ts 1ms (unchanged) src/app/shared/types/block-production/won-slots/block-production-won-slots-filters.type.ts 1ms (unchanged) src/app/shared/types/block-production/won-slots/block-production-won-slots-slot.type.ts 2ms (unchanged) src/app/shared/types/core/environment/mina-env.type.ts 2ms (unchanged) src/app/shared/types/core/mina/mina.type.ts 1ms (unchanged) src/app/shared/types/dashboard/dashboard-peers-stats.type.ts 1ms (unchanged) src/app/shared/types/dashboard/dashboard-rpc-stats.type.ts 1ms (unchanged) src/app/shared/types/dashboard/dashboard.peer.ts 1ms (unchanged) src/app/shared/types/error-preview/mina-error-type.enum.ts 1ms (unchanged) src/app/shared/types/error-preview/mina-error.type.ts 1ms (unchanged) src/app/shared/types/fuzzing/fuzzing-directory.type.ts 1ms (unchanged) src/app/shared/types/fuzzing/fuzzing-file-details.type.ts 1ms (unchanged) src/app/shared/types/fuzzing/fuzzing-file.type.ts 1ms (unchanged) src/app/shared/types/fuzzing/fuzzing-line-counter.type.ts 1ms (unchanged) src/app/shared/types/fuzzing/fuzzing-line.type.ts 1ms (unchanged) src/app/shared/types/leaderboard/heartbeat-summary.type.ts 1ms (unchanged) src/app/shared/types/leaderboard/heartbeat.type.ts 1ms (unchanged) src/app/shared/types/ledger/ledger.type.ts 2ms (unchanged) src/app/shared/types/mempool/mempool-filters.type.ts 1ms (unchanged) src/app/shared/types/mempool/mempool-transaction.type.ts 4ms (unchanged) src/app/shared/types/network/blocks-ipc/network-block-ipc.type.ts 1ms (unchanged) src/app/shared/types/network/blocks/network-block.type.ts 1ms (unchanged) src/app/shared/types/network/bootstrap-stats/network-bootstrap-stats-request.type.ts 1ms (unchanged) src/app/shared/types/network/connections/network-connection.type.ts 1ms (unchanged) src/app/shared/types/network/messages/network-message.type.ts 1ms (unchanged) src/app/shared/types/network/messages/network-messages-connection.type.ts 1ms (unchanged) src/app/shared/types/network/messages/network-messages-direction.enum.ts 1ms (unchanged) src/app/shared/types/network/messages/network-messages-filter-group.type.ts 1ms (unchanged) src/app/shared/types/network/messages/network-messages-filter-types.enum.ts 1ms (unchanged) src/app/shared/types/network/messages/network-messages-filter.type.ts 1ms (unchanged) src/app/shared/types/network/node-dht/network-node-dht-bucket.type.ts 1ms (unchanged) src/app/shared/types/network/node-dht/network-node-dht.type.ts 1ms (unchanged) src/app/shared/types/network/splits/dashboard-node-count.type.ts 1ms (unchanged) src/app/shared/types/network/splits/dashboard-splits-link.type.ts 1ms (unchanged) src/app/shared/types/network/splits/dashboard-splits-peer.type.ts 1ms (unchanged) src/app/shared/types/network/splits/dashboard-splits-set.type.ts 1ms (unchanged) src/app/shared/types/network/splits/dashboard-splits.type.ts 1ms (unchanged) src/app/shared/types/nodes/bootstrap/nodes-bootstrap-node.type.ts 1ms (unchanged) src/app/shared/types/nodes/dashboard/nodes-overview-block.type.ts 1ms (unchanged) src/app/shared/types/nodes/dashboard/nodes-overview-ledger.type.ts 1ms (unchanged) src/app/shared/types/nodes/dashboard/nodes-overview-node.type.ts 2ms (unchanged) src/app/shared/types/nodes/live/nodes-live-block-event.type.ts 1ms (unchanged) src/app/shared/types/nodes/live/nodes-live-node.type.ts 1ms (unchanged) src/app/shared/types/resources/memory/memory-resource.type.ts 1ms (unchanged) src/app/shared/types/resources/memory/memory-resources-name.type.ts 1ms (unchanged) src/app/shared/types/resources/memory/treemap-view.type.ts 1ms (unchanged) src/app/shared/types/snarks/scan-state/scan-state-block.type.ts 1ms (unchanged) src/app/shared/types/snarks/scan-state/scan-state-leaf.type.ts 1ms (unchanged) src/app/shared/types/snarks/scan-state/scan-state-transaction.type.ts 1ms (unchanged) src/app/shared/types/snarks/scan-state/scan-state-tree.type.ts 1ms (unchanged) src/app/shared/types/snarks/scan-state/scan-state-working-snarker.type.ts 1ms (unchanged) src/app/shared/types/snarks/work-pool/work-pool-commitment.type.ts 1ms (unchanged) src/app/shared/types/snarks/work-pool/work-pool-detail.type.ts 0ms (unchanged) src/app/shared/types/snarks/work-pool/work-pool-snark.type.ts 1ms (unchanged) src/app/shared/types/snarks/work-pool/work-pool-specs.type.ts 1ms (unchanged) src/app/shared/types/snarks/work-pool/work-pool.type.ts 1ms (unchanged) src/app/shared/types/state/actions/state-action-column.type.ts 1ms (unchanged) src/app/shared/types/state/actions/state-action-group-action.type.ts 1ms (unchanged) src/app/shared/types/state/actions/state-action-group.type.ts 1ms (unchanged) src/app/shared/types/state/actions/state-actions-stats.type.ts 1ms (unchanged) src/assets/environments/block-producers.js 19ms (unchanged) src/assets/environments/compose-producer.js 2ms (unchanged) src/assets/environments/compose.js 1ms (unchanged) src/assets/environments/env.js 1ms (unchanged) src/assets/environments/leaderboard.js 2ms (unchanged) src/assets/environments/producer.js 1ms (unchanged) src/assets/environments/staging.js 1ms (unchanged) src/assets/environments/webnode.js 1ms (unchanged) src/assets/o1js/bootstrap.js 2ms (unchanged) src/assets/o1js/coi-serviceworker.js 9ms (unchanged) src/assets/o1js/dist/o1js-wrapper.js 238ms (unchanged) src/assets/o1js/package-lock.json 54ms (unchanged) src/assets/o1js/package.json 1ms (unchanged) src/assets/o1js/replace-assertion.js 2ms (unchanged) src/assets/o1js/src/index.ts 1ms (unchanged) src/assets/o1js/src/zk-app/zk-app.ts 8ms (unchanged) src/assets/o1js/tsconfig.json 1ms (unchanged) src/assets/o1js/webpack.config.js 2ms (unchanged) src/assets/reports/index.json 0ms (unchanged) src/assets/styles/leaderboard-variables.scss 2ms (unchanged) src/assets/styles/openmina.scss 44ms (unchanged) src/environments/environment.fuzzing.ts 1ms (unchanged) src/environments/environment.local.ts 2ms (unchanged) src/environments/environment.prod.ts 1ms (unchanged) src/environments/environment.producer.ts 1ms (unchanged) src/environments/environment.ts 6ms (unchanged) src/environments/environment.webnodelocal.ts 1ms (unchanged) src/index.html 10ms (unchanged) src/main.server.ts 1ms (unchanged) src/main.ts 2ms (unchanged) src/styles.scss 3ms (unchanged) --- frontend/src/app/app.actions.ts | 40 +- frontend/src/app/app.component.html | 54 +- frontend/src/app/app.component.scss | 1 - frontend/src/app/app.component.ts | 70 +- frontend/src/app/app.config.ts | 111 +- frontend/src/app/app.effects.ts | 203 ++- frontend/src/app/app.module.server.ts | 5 +- frontend/src/app/app.reducer.ts | 55 +- frontend/src/app/app.routing.ts | 42 +- frontend/src/app/app.service.ts | 82 +- frontend/src/app/app.setup.ts | 28 +- frontend/src/app/app.state.ts | 8 +- .../app/core/helpers/file-progress.helper.ts | 5 +- .../src/app/core/services/config.service.ts | 11 +- .../app/core/services/firestore.service.ts | 28 +- .../src/app/core/services/rust.service.ts | 27 +- .../src/app/core/services/sentry.service.ts | 149 +- .../src/app/core/services/web-node.service.ts | 185 +- .../benchmarks/benchmarks.component.ts | 15 +- .../features/benchmarks/benchmarks.module.ts | 9 +- .../features/benchmarks/benchmarks.reducer.ts | 8 +- .../features/benchmarks/benchmarks.routing.ts | 5 +- .../features/benchmarks/benchmarks.state.ts | 21 +- .../benchmarks-wallets-table.component.html | 12 +- .../benchmarks-wallets-table.component.ts | 31 +- .../benchmarks-wallets-toolbar.component.html | 113 +- .../benchmarks-wallets-toolbar.component.scss | 10 +- .../benchmarks-wallets-toolbar.component.ts | 126 +- .../wallets/benchmarks-wallets-zk.service.ts | 39 +- ...marks-wallets-zkapp-toolbar.component.html | 110 +- ...marks-wallets-zkapp-toolbar.component.scss | 10 +- ...chmarks-wallets-zkapp-toolbar.component.ts | 96 +- .../wallets/benchmarks-wallets.actions.ts | 120 +- .../wallets/benchmarks-wallets.component.html | 3 +- .../wallets/benchmarks-wallets.component.ts | 57 +- .../wallets/benchmarks-wallets.effects.ts | 148 +- .../wallets/benchmarks-wallets.module.ts | 13 +- .../wallets/benchmarks-wallets.reducer.ts | 227 ++- .../wallets/benchmarks-wallets.service.ts | 89 +- .../wallets/benchmarks-wallets.state.ts | 51 +- .../block-production.component.ts | 13 +- .../block-production.guard.ts | 14 +- .../block-production.module.ts | 10 +- .../block-production.reducer.ts | 9 +- .../block-production.routing.ts | 10 +- .../block-production.state.ts | 27 +- .../block-production-overview.actions.ts | 81 +- .../block-production-overview.component.html | 23 +- .../block-production-overview.component.ts | 79 +- .../block-production-overview.effects.ts | 188 +- .../block-production-overview.module.ts | 20 +- .../block-production-overview.reducer.ts | 41 +- .../block-production-overview.routing.ts | 4 +- .../block-production-overview.service.ts | 247 +-- .../block-production-overview.state.ts | 53 +- ...ction-overview-epoch-graphs.component.html | 108 +- ...duction-overview-epoch-graphs.component.ts | 75 +- ...duction-overview-side-panel.component.html | 100 +- ...duction-overview-side-panel.component.scss | 11 +- ...roduction-overview-side-panel.component.ts | 141 +- ...ction-overview-slot-details.component.html | 15 +- ...duction-overview-slot-details.component.ts | 26 +- ...k-production-overview-slots.component.html | 14 +- ...ock-production-overview-slots.component.ts | 285 ++- ...production-overview-toolbar.component.html | 65 +- ...k-production-overview-toolbar.component.ts | 126 +- ...-production-won-slots-epoch.component.html | 2 +- ...ck-production-won-slots-epoch.component.ts | 57 +- .../block-production-won-slots.actions.ts | 48 +- .../block-production-won-slots.component.html | 41 +- .../block-production-won-slots.component.scss | 8 +- .../block-production-won-slots.component.ts | 89 +- .../block-production-won-slots.effects.ts | 163 +- .../block-production-won-slots.module.ts | 23 +- .../block-production-won-slots.reducer.ts | 57 +- .../block-production-won-slots.service.ts | 236 ++- .../block-production-won-slots.state.ts | 21 +- ...-production-won-slots-cards.component.html | 72 +- ...ck-production-won-slots-cards.component.ts | 165 +- ...roduction-won-slots-filters.component.html | 47 +- ...-production-won-slots-filters.component.ts | 54 +- ...uction-won-slots-side-panel.component.html | 137 +- ...uction-won-slots-side-panel.component.scss | 22 +- ...oduction-won-slots-side-panel.component.ts | 165 +- ...-production-won-slots-table.component.html | 34 +- ...-production-won-slots-table.component.scss | 4 +- ...ck-production-won-slots-table.component.ts | 157 +- .../dashboard-blocks-sync.component.html | 90 +- .../dashboard-blocks-sync.component.scss | 13 +- .../dashboard-blocks-sync.component.ts | 182 +- .../dashboard-ledger.component.html | 184 +- .../dashboard-ledger.component.scss | 13 +- .../dashboard-ledger.component.ts | 419 +++-- .../dashboard-network.component.html | 41 +- .../dashboard-network.component.scss | 14 +- .../dashboard-network.component.ts | 30 +- ...shboard-peers-minimal-table.component.html | 8 +- ...shboard-peers-minimal-table.component.scss | 4 +- ...dashboard-peers-minimal-table.component.ts | 29 +- .../features/dashboard/dashboard.actions.ts | 21 +- .../dashboard/dashboard.component.html | 19 +- .../dashboard/dashboard.component.scss | 13 +- .../features/dashboard/dashboard.component.ts | 244 ++- .../features/dashboard/dashboard.effects.ts | 110 +- .../features/dashboard/dashboard.module.ts | 1 - .../features/dashboard/dashboard.reducer.ts | 43 +- .../features/dashboard/dashboard.routing.ts | 6 +- .../features/dashboard/dashboard.service.ts | 113 +- .../app/features/dashboard/dashboard.state.ts | 47 +- .../fuzzing-code/fuzzing-code.component.html | 57 +- .../fuzzing-code/fuzzing-code.component.ts | 100 +- .../fuzzing-directories-table.component.ts | 91 +- .../fuzzing-files-table.component.html | 1 - .../fuzzing-files-table.component.ts | 92 +- .../fuzzing-toolbar.component.html | 34 +- .../fuzzing-toolbar.component.ts | 43 +- .../app/features/fuzzing/fuzzing.actions.ts | 35 +- .../features/fuzzing/fuzzing.component.html | 33 +- .../features/fuzzing/fuzzing.component.scss | 12 +- .../app/features/fuzzing/fuzzing.component.ts | 48 +- .../app/features/fuzzing/fuzzing.effects.ts | 108 +- .../app/features/fuzzing/fuzzing.module.ts | 6 +- .../app/features/fuzzing/fuzzing.reducer.ts | 28 +- .../app/features/fuzzing/fuzzing.service.ts | 91 +- .../src/app/features/fuzzing/fuzzing.state.ts | 41 +- .../leaderboard-apply.component.scss | 5 +- .../leaderboard-apply.component.ts | 14 +- .../leaderboard-details.component.scss | 2 +- .../leaderboard-details.component.ts | 14 +- .../leaderboard-filters.component.html | 44 +- .../leaderboard-filters.component.scss | 3 +- .../leaderboard-filters.component.ts | 59 +- .../leaderboard-footer.component.html | 19 +- .../leaderboard-footer.component.scss | 4 +- .../leaderboard-footer.component.ts | 14 +- .../leaderboard-header.component.html | 46 +- .../leaderboard-header.component.scss | 2 +- .../leaderboard-header.component.ts | 66 +- .../leaderboard-impressum.component.scss | 2 +- .../leaderboard-impressum.component.ts | 14 +- .../leaderboard-landing-page.component.html | 111 +- .../leaderboard-landing-page.component.scss | 13 +- .../leaderboard-landing-page.component.ts | 31 +- .../leaderboard-page.component.html | 45 +- .../leaderboard-page.component.scss | 2 +- .../leaderboard-page.component.ts | 94 +- .../leaderboard-privacy-policy.component.scss | 2 +- .../leaderboard-privacy-policy.component.ts | 14 +- .../leaderboard-table.component.html | 55 +- .../leaderboard-table.component.scss | 10 +- .../leaderboard-table.component.ts | 49 +- ...rboard-terms-and-conditions.component.scss | 2 +- ...derboard-terms-and-conditions.component.ts | 14 +- .../leaderboard-title.component.scss | 2 +- .../leaderboard-title.component.ts | 29 +- .../leaderboard/leaderboard.actions.ts | 22 +- .../leaderboard/leaderboard.effects.ts | 30 +- .../leaderboard/leaderboard.module.ts | 5 +- .../leaderboard/leaderboard.reducer.ts | 44 +- .../leaderboard/leaderboard.service.ts | 156 +- .../features/leaderboard/leaderboard.state.ts | 19 +- .../mempool-add-transaction.component.ts | 14 +- .../filters/mempool-filters.component.html | 61 +- .../filters/mempool-filters.component.scss | 1 - .../filters/mempool-filters.component.ts | 68 +- .../app/features/mempool/mempool.actions.ts | 22 +- .../features/mempool/mempool.component.html | 17 +- .../app/features/mempool/mempool.component.ts | 30 +- .../app/features/mempool/mempool.effects.ts | 44 +- .../app/features/mempool/mempool.module.ts | 5 +- .../app/features/mempool/mempool.reducer.ts | 31 +- .../app/features/mempool/mempool.service.ts | 36 +- .../src/app/features/mempool/mempool.state.ts | 15 +- .../mempool-side-panel.component.html | 26 +- .../mempool-side-panel.component.ts | 44 +- .../table/mempool-table.component.html | 41 +- .../table/mempool-table.component.scss | 4 +- .../mempool/table/mempool-table.component.ts | 78 +- .../warnings/mempool-warnings.component.ts | 14 +- .../network-blocks-graph.component.ts | 35 +- .../network-blocks-side-panel.component.html | 10 +- .../network-blocks-side-panel.component.scss | 3 +- .../network-blocks-side-panel.component.ts | 26 +- .../network-blocks-table.component.html | 53 +- .../network-blocks-table.component.ts | 35 +- .../network-blocks-toolbar.component.html | 64 +- .../network-blocks-toolbar.component.ts | 39 +- .../network/blocks/network-blocks.actions.ts | 43 +- .../blocks/network-blocks.component.html | 15 +- .../blocks/network-blocks.component.ts | 58 +- .../network/blocks/network-blocks.effects.ts | 150 +- .../network/blocks/network-blocks.module.ts | 10 +- .../network/blocks/network-blocks.reducer.ts | 47 +- .../network/blocks/network-blocks.service.ts | 63 +- .../network/blocks/network-blocks.state.ts | 36 +- .../network-bootstrap-stats.actions.ts | 46 +- .../network-bootstrap-stats.component.html | 15 +- .../network-bootstrap-stats.component.ts | 53 +- .../network-bootstrap-stats.effects.ts | 76 +- .../network-bootstrap-stats.module.ts | 9 +- .../network-bootstrap-stats.reducer.ts | 20 +- .../network-bootstrap-stats.service.ts | 33 +- .../network-bootstrap-stats.state.ts | 28 +- ...-bootstrap-stats-side-panel.component.html | 67 +- ...rk-bootstrap-stats-side-panel.component.ts | 92 +- ...twork-bootstrap-stats-table.component.html | 34 +- ...network-bootstrap-stats-table.component.ts | 102 +- ...work-connections-side-panel.component.html | 26 +- ...etwork-connections-side-panel.component.ts | 55 +- .../network-connections-table.component.html | 32 +- .../network-connections-table.component.ts | 70 +- .../network-connections.actions.ts | 39 +- .../network-connections.component.html | 15 +- .../network-connections.component.ts | 66 +- .../network-connections.effects.ts | 122 +- .../connections/network-connections.module.ts | 6 +- .../network-connections.reducer.ts | 6 +- .../network-connections.service.ts | 35 +- .../connections/network-connections.state.ts | 16 +- .../network/dht-graph/dht-graph.component.ts | 28 +- .../network/dht-graph/dht-graph.module.ts | 15 +- .../equal-distance-algorithm.ts | 57 +- .../minimum-distance-algorithm.ts | 44 +- ...twork-dht-graph-binary-tree.component.html | 7 +- ...network-dht-graph-binary-tree.component.ts | 100 +- .../network-messages-filters.component.html | 82 +- .../network-messages-filters.component.ts | 260 ++- ...network-messages-side-panel.component.html | 99 +- .../network-messages-side-panel.component.ts | 161 +- ...twork-messages-table-footer.component.html | 71 +- ...network-messages-table-footer.component.ts | 166 +- .../network-messages-table.component.html | 27 +- .../network-messages-table.component.ts | 148 +- .../messages/network-messages.actions.ts | 107 +- .../messages/network-messages.component.html | 23 +- .../messages/network-messages.component.ts | 46 +- .../messages/network-messages.effects.ts | 326 ++-- .../messages/network-messages.module.ts | 31 +- .../messages/network-messages.reducer.ts | 79 +- .../messages/network-messages.service.ts | 108 +- .../messages/network-messages.state.ts | 42 +- .../app/features/network/network.component.ts | 13 +- .../src/app/features/network/network.guard.ts | 5 +- .../app/features/network/network.module.ts | 10 +- .../app/features/network/network.reducer.ts | 59 +- .../app/features/network/network.routing.ts | 36 +- .../src/app/features/network/network.state.ts | 41 +- .../network-node-dht-line.component.html | 32 +- .../network-node-dht-line.component.ts | 132 +- ...network-node-dht-side-panel.component.html | 34 +- .../network-node-dht-side-panel.component.ts | 55 +- .../network-node-dht-table.component.html | 29 +- .../network-node-dht-table.component.ts | 94 +- .../node-dht/network-node-dht.actions.ts | 40 +- .../node-dht/network-node-dht.component.html | 15 +- .../node-dht/network-node-dht.component.ts | 49 +- .../node-dht/network-node-dht.effects.ts | 85 +- .../node-dht/network-node-dht.module.ts | 5 +- .../node-dht/network-node-dht.reducer.ts | 36 +- .../node-dht/network-node-dht.routing.ts | 3 +- .../node-dht/network-node-dht.service.ts | 47 +- .../node-dht/network-node-dht.state.ts | 32 +- .../dashboard-splits-graph.component.html | 6 +- .../dashboard-splits-graph.component.ts | 531 ++++-- ...ard-splits-side-panel-table.component.html | 6 +- ...board-splits-side-panel-table.component.ts | 57 +- ...dashboard-splits-side-panel.component.html | 36 +- .../dashboard-splits-side-panel.component.ts | 108 +- .../dashboard-splits-toolbar.component.html | 47 +- .../dashboard-splits-toolbar.component.ts | 53 +- .../splits/dashboard-splits.actions.ts | 44 +- .../splits/dashboard-splits.component.html | 14 +- .../splits/dashboard-splits.component.ts | 30 +- .../splits/dashboard-splits.effects.ts | 98 +- .../network/splits/dashboard-splits.module.ts | 7 +- .../splits/dashboard-splits.reducer.ts | 97 +- .../splits/dashboard-splits.service.ts | 147 +- .../network/splits/dashboard-splits.state.ts | 74 +- .../src/app/features/network/splits/mock.ts | 126 +- .../nodes-bootstrap-blocks.component.html | 39 +- .../nodes-bootstrap-blocks.component.ts | 74 +- .../nodes-bootstrap-overview.component.html | 2 +- .../nodes-bootstrap-overview.component.ts | 110 +- .../nodes-bootstrap-side-panel.component.html | 38 +- .../nodes-bootstrap-side-panel.component.scss | 11 +- .../nodes-bootstrap-side-panel.component.ts | 63 +- .../nodes-bootstrap-table.component.html | 13 +- .../nodes-bootstrap-table.component.ts | 85 +- .../bootstrap/nodes-bootstrap.actions.ts | 35 +- .../bootstrap/nodes-bootstrap.component.html | 15 +- .../bootstrap/nodes-bootstrap.component.ts | 40 +- .../bootstrap/nodes-bootstrap.effects.ts | 55 +- .../nodes/bootstrap/nodes-bootstrap.module.ts | 7 +- .../bootstrap/nodes-bootstrap.reducer.ts | 15 +- .../bootstrap/nodes-bootstrap.service.ts | 94 +- .../nodes/bootstrap/nodes-bootstrap.state.ts | 24 +- .../nodes-live-blocks-map.component.html | 39 +- .../nodes-live-blocks-map.component.scss | 4 +- .../nodes-live-blocks-map.component.ts | 21 +- .../nodes-live-events-table.component.html | 3 +- .../nodes-live-events-table.component.scss | 1 - .../nodes-live-events-table.component.ts | 41 +- .../nodes-live-filters.component.html | 12 +- .../nodes-live-filters.component.scss | 1 - .../nodes-live-filters.component.ts | 18 +- .../nodes-live-status-counts.component.html | 6 +- .../nodes-live-status-counts.component.ts | 18 +- .../nodes-live-toolbar.component.html | 56 +- .../nodes-live-toolbar.component.ts | 85 +- .../features/nodes/live/nodes-live.actions.ts | 28 +- .../nodes/live/nodes-live.component.html | 17 +- .../nodes/live/nodes-live.component.ts | 46 +- .../features/nodes/live/nodes-live.effects.ts | 57 +- .../features/nodes/live/nodes-live.module.ts | 6 +- .../features/nodes/live/nodes-live.reducer.ts | 63 +- .../features/nodes/live/nodes-live.service.ts | 42 +- .../features/nodes/live/nodes-live.state.ts | 32 +- .../src/app/features/nodes/nodes.component.ts | 14 +- .../src/app/features/nodes/nodes.module.ts | 10 +- .../src/app/features/nodes/nodes.reducer.ts | 42 +- .../src/app/features/nodes/nodes.routing.ts | 15 +- .../src/app/features/nodes/nodes.state.ts | 25 +- .../nodes-overview-ledgers.component.html | 207 ++- .../nodes-overview-ledgers.component.ts | 56 +- .../nodes-overview-side-panel.component.html | 30 +- .../nodes-overview-side-panel.component.scss | 4 +- .../nodes-overview-side-panel.component.ts | 82 +- .../nodes-overview-table.component.html | 14 +- .../nodes-overview-table.component.ts | 104 +- .../nodes-overview-toolbar.component.html | 37 +- .../nodes-overview-toolbar.component.ts | 22 +- .../nodes/overview/nodes-overview.actions.ts | 37 +- .../overview/nodes-overview.component.html | 15 +- .../overview/nodes-overview.component.ts | 45 +- .../nodes/overview/nodes-overview.effects.ts | 77 +- .../nodes/overview/nodes-overview.module.ts | 41 +- .../nodes/overview/nodes-overview.reducer.ts | 37 +- .../nodes/overview/nodes-overview.service.ts | 242 ++- .../nodes/overview/nodes-overview.state.ts | 20 +- .../memory-resources-table.component.html | 51 +- .../memory-resources-table.component.ts | 61 +- .../memory-resources-toolbar.component.html | 54 +- .../memory-resources-toolbar.component.ts | 118 +- .../memory-resources-treemap.component.scss | 4 +- .../memory-resources-treemap.component.ts | 391 ++-- .../memory/memory-resources.actions.ts | 25 +- .../memory/memory-resources.component.html | 27 +- .../memory/memory-resources.component.ts | 57 +- .../memory/memory-resources.effects.ts | 53 +- .../memory/memory-resources.module.ts | 9 +- .../resources/memory/memory-resources.pipe.ts | 4 +- .../memory/memory-resources.reducer.ts | 18 +- .../memory/memory-resources.service.ts | 67 +- .../memory/memory-resources.state.ts | 28 +- .../features/resources/resources.component.ts | 14 +- .../features/resources/resources.module.ts | 13 +- .../features/resources/resources.reducer.ts | 20 +- .../features/resources/resources.routing.ts | 5 +- .../app/features/resources/resources.state.ts | 21 +- .../scan-state-details.component.ts | 14 +- .../scan-state-job-details.component.html | 5 +- .../scan-state-job-details.component.ts | 34 +- .../scan-state-side-panel.component.html | 156 +- .../scan-state-side-panel.component.ts | 101 +- .../scan-state-toolbar.component.html | 138 +- .../scan-state-toolbar.component.ts | 98 +- .../scan-state-tree-chart.component.html | 10 +- .../scan-state-tree-chart.component.scss | 14 +- .../scan-state-tree-chart.component.ts | 275 ++- .../scan-state-tree-list.component.html | 192 +- .../scan-state-tree-list.component.scss | 4 +- .../scan-state-tree-list.component.ts | 119 +- .../snarks/scan-state/scan-state.actions.ts | 27 +- .../scan-state/scan-state.component.html | 17 +- .../snarks/scan-state/scan-state.component.ts | 75 +- .../snarks/scan-state/scan-state.effects.ts | 87 +- .../snarks/scan-state/scan-state.module.ts | 10 +- .../snarks/scan-state/scan-state.reducer.ts | 27 +- .../snarks/scan-state/scan-state.routing.ts | 4 +- .../snarks/scan-state/scan-state.service.ts | 94 +- .../snarks/scan-state/scan-state.state.ts | 40 +- .../app/features/snarks/snarks.component.ts | 14 +- .../src/app/features/snarks/snarks.module.ts | 12 +- .../src/app/features/snarks/snarks.reducer.ts | 29 +- .../src/app/features/snarks/snarks.routing.ts | 10 +- .../src/app/features/snarks/snarks.state.ts | 22 +- ...-work-pool-details-accounts.component.html | 28 +- ...ks-work-pool-details-accounts.component.ts | 29 +- ...-work-pool-details-overview.component.html | 5 +- ...ks-work-pool-details-overview.component.ts | 27 +- ...rks-work-pool-details-specs.component.html | 10 +- ...narks-work-pool-details-specs.component.ts | 49 +- .../snarks-work-pool-details.component.html | 28 +- .../snarks-work-pool-details.component.ts | 69 +- ...snarks-work-pool-side-panel.component.html | 77 +- .../snarks-work-pool-side-panel.component.ts | 71 +- ...snarks-work-pool-statistics.component.html | 6 +- .../snarks-work-pool-statistics.component.ts | 50 +- .../snarks-work-pool-table.component.html | 55 +- .../snarks-work-pool-table.component.scss | 2 - .../snarks-work-pool-table.component.ts | 63 +- .../snarks-work-pool-toolbar.component.html | 24 +- .../snarks-work-pool-toolbar.component.scss | 1 - .../snarks-work-pool-toolbar.component.ts | 33 +- .../work-pool/snarks-work-pool.actions.ts | 53 +- .../work-pool/snarks-work-pool.component.html | 15 +- .../work-pool/snarks-work-pool.component.ts | 30 +- .../work-pool/snarks-work-pool.effects.ts | 127 +- .../work-pool/snarks-work-pool.module.ts | 15 +- .../work-pool/snarks-work-pool.reducer.ts | 42 +- .../work-pool/snarks-work-pool.routing.ts | 1 - .../work-pool/snarks-work-pool.service.ts | 58 +- .../work-pool/snarks-work-pool.state.ts | 36 +- .../state-actions-graph-list.component.html | 49 +- .../state-actions-graph-list.component.scss | 4 +- .../state-actions-graph-list.component.ts | 68 +- .../state-actions-side-panel.component.html | 32 +- .../state-actions-side-panel.component.ts | 74 +- .../state-actions-toolbar.component.html | 106 +- .../state-actions-toolbar.component.ts | 99 +- .../state/actions/state-actions.actions.ts | 36 +- .../actions/state-actions.component.html | 15 +- .../state/actions/state-actions.component.ts | 35 +- .../state/actions/state-actions.effects.ts | 96 +- .../state/actions/state-actions.module.ts | 3 +- .../state/actions/state-actions.reducer.ts | 50 +- .../state/actions/state-actions.routing.ts | 4 +- .../state/actions/state-actions.service.ts | 183 +- .../state/actions/state-actions.state.ts | 56 +- .../app/features/state/state.component.html | 2 +- .../src/app/features/state/state.component.ts | 14 +- .../src/app/features/state/state.module.ts | 12 +- .../src/app/features/state/state.reducer.ts | 20 +- .../src/app/features/state/state.routing.ts | 9 +- .../src/app/features/state/state.state.ts | 17 +- .../web-node-file-upload.component.html | 136 +- .../web-node-file-upload.component.scss | 7 +- .../web-node-file-upload.component.ts | 88 +- .../web-node-initialization.component.html | 46 +- .../web-node-initialization.component.scss | 4 +- .../web-node-initialization.component.ts | 269 +-- .../web-node-not-supported.component.html | 61 +- .../web-node-not-supported.component.ts | 30 +- .../features/web-node/web-node.component.html | 9 +- .../features/web-node/web-node.component.ts | 61 +- .../app/features/web-node/web-node.module.ts | 6 +- .../block-production-pill.component.html | 11 +- .../block-production-pill.component.scss | 20 +- .../block-production-pill.component.ts | 102 +- .../env-build-modal.component.html | 10 +- .../env-build-modal.component.ts | 20 +- .../error-list/error-list.component.html | 15 +- .../error-list/error-list.component.ts | 20 +- .../error-preview/error-preview.actions.ts | 8 +- .../error-preview.component.html | 30 +- .../error-preview/error-preview.component.ts | 67 +- .../error-preview/error-preview.reducer.ts | 12 +- .../error-preview/error-preview.state.ts | 3 +- .../layout/menu-tabs/menu-tabs.component.html | 60 +- .../layout/menu-tabs/menu-tabs.component.scss | 10 +- .../layout/menu-tabs/menu-tabs.component.ts | 115 +- .../src/app/layout/menu/menu.component.html | 137 +- .../src/app/layout/menu/menu.component.scss | 42 +- .../src/app/layout/menu/menu.component.ts | 68 +- .../layout/new-node/new-node.component.html | 104 +- .../layout/new-node/new-node.component.scss | 4 +- .../app/layout/new-node/new-node.component.ts | 65 +- .../node-picker/node-picker.component.html | 97 +- .../node-picker/node-picker.component.scss | 4 +- .../node-picker/node-picker.component.ts | 71 +- .../server-status.component.html | 126 +- .../server-status.component.scss | 14 +- .../server-status/server-status.component.ts | 231 ++- .../submenu-tabs/submenu-tabs.component.html | 20 +- .../submenu-tabs/submenu-tabs.component.ts | 57 +- .../src/app/layout/toolbar/loading.reducer.ts | 59 +- .../app/layout/toolbar/toolbar.component.html | 21 +- .../app/layout/toolbar/toolbar.component.ts | 65 +- .../uptime-pill/uptime-pill.component.html | 15 +- .../uptime-pill/uptime-pill.component.scss | 1 - .../uptime-pill/uptime-pill.component.ts | 44 +- .../web-node-landing-page.component.html | 61 +- .../web-node-landing-page.component.scss | 10 +- .../web-node-landing-page.component.ts | 24 +- .../base-classes/mina-rust-base.effect.ts | 35 +- .../mina-table-rust-wrapper.class.ts | 6 +- .../base-classes/mina-table-wrapper.class.ts | 31 +- .../base-classes/store-dispatcher.class.ts | 7 +- .../mina-card/mina-card.component.html | 16 +- .../mina-card/mina-card.component.ts | 14 +- .../mina-table/mina-table.component.html | 71 +- .../mina-table/mina-table.component.scss | 7 +- .../mina-table/mina-table.component.ts | 85 +- frontend/src/app/shared/constants/config.ts | 43 +- .../app/shared/constants/store-functions.ts | 115 +- .../app/shared/guards/landing-page.guard.ts | 7 +- .../src/app/shared/helpers/date.helper.ts | 13 +- .../src/app/shared/helpers/ledger.helper.ts | 59 +- .../src/app/shared/helpers/mina.helper.ts | 10 +- .../app/shared/helpers/transaction.helper.ts | 8 +- .../src/app/shared/helpers/webnode.helper.ts | 7 +- .../loading-spinner.component.html | 10 +- .../pagination/pagination.component.html | 64 +- .../shared/pagination/pagination.component.ts | 23 +- frontend/src/app/shared/shared.module.ts | 23 +- .../block-production-overview-epoch.type.ts | 12 +- .../block-production-won-slots-slot.type.ts | 2 +- .../types/core/environment/mina-env.type.ts | 18 +- .../fuzzing/fuzzing-line-counter.type.ts | 6 +- .../app/shared/types/ledger/ledger.type.ts | 1 - .../types/mempool/mempool-transaction.type.ts | 1 - .../snarks/scan-state/scan-state-leaf.type.ts | 2 +- .../work-pool/work-pool-commitment.type.ts | 2 +- .../snarks/work-pool/work-pool-detail.type.ts | 2 +- .../snarks/work-pool/work-pool-snark.type.ts | 2 +- .../assets/environments/block-producers.js | 8 +- .../src/assets/environments/leaderboard.js | 13 +- frontend/src/assets/environments/producer.js | 2 +- frontend/src/assets/environments/staging.js | 14 +- frontend/src/assets/environments/webnode.js | 22 +- frontend/src/assets/o1js/bootstrap.js | 2 +- frontend/src/assets/o1js/coi-serviceworker.js | 79 +- frontend/src/assets/o1js/dist/o1js-wrapper.js | 251 +-- frontend/src/assets/o1js/replace-assertion.js | 4 +- frontend/src/assets/o1js/src/index.ts | 5 +- frontend/src/assets/o1js/src/zk-app/zk-app.ts | 49 +- frontend/src/assets/o1js/tsconfig.json | 2 +- frontend/src/assets/o1js/webpack.config.js | 10 +- frontend/src/assets/reports/index.json | 4 +- .../assets/styles/leaderboard-variables.scss | 37 +- frontend/src/assets/styles/openmina.scss | 1599 ++++++++--------- .../src/environments/environment.fuzzing.ts | 1 - .../src/environments/environment.local.ts | 1 - frontend/src/environments/environment.ts | 11 +- .../environments/environment.webnodelocal.ts | 1 - frontend/src/index.html | 168 +- frontend/src/main.ts | 10 +- frontend/src/styles.scss | 9 +- 538 files changed, 18505 insertions(+), 10193 deletions(-) diff --git a/frontend/src/app/app.actions.ts b/frontend/src/app/app.actions.ts index 59afd73900..9a1c1d0584 100644 --- a/frontend/src/app/app.actions.ts +++ b/frontend/src/app/app.actions.ts @@ -10,19 +10,43 @@ export const APP_PREFIX = 'App'; const type = (type: T) => createType(APP_PREFIX, null, type); const init = createAction(type('Init')); -const initSuccess = createAction(type('Init Success'), props<{ activeNode: MinaNode, nodes: MinaNode[] }>()); +const initSuccess = createAction( + type('Init Success'), + props<{ activeNode: MinaNode; nodes: MinaNode[] }>(), +); -const changeActiveNode = createAction(type('Change Active Node'), props<{ node: MinaNode }>()); +const changeActiveNode = createAction( + type('Change Active Node'), + props<{ node: MinaNode }>(), +); const getNodeDetails = createAction(type('Get Node Details')); -const getNodeDetailsSuccess = createAction(type('Get Node Details Success'), props<{ details: AppNodeDetails }>()); +const getNodeDetailsSuccess = createAction( + type('Get Node Details Success'), + props<{ details: AppNodeDetails }>(), +); const getNodeEnvBuild = createAction(type('Get Node Env Build')); -const getNodeEnvBuildSuccess = createAction(type('Get Node Env Build Success'), props<{ envBuild: AppEnvBuild }>()); -const deleteNode = createAction(type('Delete Node'), props<{ node: MinaNode }>()); +const getNodeEnvBuildSuccess = createAction( + type('Get Node Env Build Success'), + props<{ envBuild: AppEnvBuild }>(), +); +const deleteNode = createAction( + type('Delete Node'), + props<{ node: MinaNode }>(), +); const addNode = createAction(type('Add Node'), props<{ node: MinaNode }>()); -const changeMenuCollapsing = createAction(type('Change Menu Collapsing'), props<{ isCollapsing: boolean }>()); -const changeSubMenus = createAction(type('Change Sub Menus'), props<{ subMenus: string[] }>()); -const toggleMobile = createAction(type('Toggle Mobile'), props<{ isMobile: boolean }>()); +const changeMenuCollapsing = createAction( + type('Change Menu Collapsing'), + props<{ isCollapsing: boolean }>(), +); +const changeSubMenus = createAction( + type('Change Sub Menus'), + props<{ subMenus: string[] }>(), +); +const toggleMobile = createAction( + type('Toggle Mobile'), + props<{ isMobile: boolean }>(), +); const toggleMenuOpening = createAction(type('Toggle Menu Opening')); export const AppActions = { diff --git a/frontend/src/app/app.component.html b/frontend/src/app/app.component.html index e8ff3c4ce6..f7193b287c 100644 --- a/frontend/src/app/app.component.html +++ b/frontend/src/app/app.component.html @@ -3,44 +3,56 @@ } @else { - + } } @else if (showLoadingWebNodePage$ | async) { } @else if (showLeaderboardPage$ | async) { } @else if (loaded) { - + @if (isDesktop) { - +
} - + @if (!hideToolbar) { } -
+
@if (!isDesktop) { - + } diff --git a/frontend/src/app/app.component.scss b/frontend/src/app/app.component.scss index 06dc34f8aa..97f171f072 100644 --- a/frontend/src/app/app.component.scss +++ b/frontend/src/app/app.component.scss @@ -79,7 +79,6 @@ mat-sidenav-content { margin-bottom: 4px; border-top-right-radius: 6px; - &.uptime { $toolbar: 130px; height: calc(100% - #{$toolbar} - #{$subMenus} - #{$tabs}); diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts index 7e9e464969..2a49da7c64 100644 --- a/frontend/src/app/app.component.ts +++ b/frontend/src/app/app.component.ts @@ -57,11 +57,29 @@ declare var AOS: any; ], }) export class AppComponent extends StoreDispatcher implements OnInit { - readonly menu$: Observable = this.select$(AppSelectors.menu); - readonly showLandingPage$: Observable = this.select$(getMergedRoute).pipe(filter(Boolean), map((route: MergedRoute) => route.url === '/' || route.url.startsWith('/?'))); - readonly showLoadingWebNodePage$: Observable = this.select$(getMergedRoute).pipe(filter(Boolean), map((route: MergedRoute) => route.url.startsWith(`/${Routes.LOADING_WEB_NODE}`))); - readonly showLeaderboardPage$: Observable = this.select$(getMergedRoute).pipe(filter(Boolean), map((route: MergedRoute) => route.url.startsWith(`/${Routes.LEADERBOARD}`))); + readonly showLandingPage$: Observable = this.select$( + getMergedRoute, + ).pipe( + filter(Boolean), + map( + (route: MergedRoute) => route.url === '/' || route.url.startsWith('/?'), + ), + ); + readonly showLoadingWebNodePage$: Observable = this.select$( + getMergedRoute, + ).pipe( + filter(Boolean), + map((route: MergedRoute) => + route.url.startsWith(`/${Routes.LOADING_WEB_NODE}`), + ), + ); + readonly showLeaderboardPage$: Observable = this.select$( + getMergedRoute, + ).pipe( + filter(Boolean), + map((route: MergedRoute) => route.url.startsWith(`/${Routes.LEADERBOARD}`)), + ); subMenusLength: number = 0; hideToolbar: boolean = CONFIG.hideToolbar; showLeaderboard: boolean = CONFIG.showLeaderboard; @@ -70,9 +88,11 @@ export class AppComponent extends StoreDispatcher implements OnInit { private nodeUpdateSubscription: Subscription | null = null; - constructor(private breakpointObserver: BreakpointObserver, - private router: Router, - private webNodeService: WebNodeService) { + constructor( + private breakpointObserver: BreakpointObserver, + private router: Router, + private webNodeService: WebNodeService, + ) { AOS.init(); super(); @@ -91,17 +111,28 @@ export class AppComponent extends StoreDispatcher implements OnInit { localStorage.setItem('webnodeArgs', args); } } - this.select(getMergedRoute, () => { - this.loaded = true; - this.detect(); - }, filter(Boolean), take(1)); + this.select( + getMergedRoute, + () => { + this.loaded = true; + this.detect(); + }, + filter(Boolean), + take(1), + ); if (CONFIG.showLeaderboard && CONFIG.showWebNodeLandingPage) { /* frontend with some landing page */ - this.select(getMergedRoute, () => { - this.initAppFunctionalities(); - }, filter((route: MergedRoute) => route?.url.startsWith('/loading-web-node')), take(1)); - + this.select( + getMergedRoute, + () => { + this.initAppFunctionalities(); + }, + filter((route: MergedRoute) => + route?.url.startsWith('/loading-web-node'), + ), + take(1), + ); } else if (!CONFIG.showLeaderboard && !CONFIG.showWebNodeLandingPage) { /* normal frontend (no landing pages) */ this.initAppFunctionalities(); @@ -114,9 +145,14 @@ export class AppComponent extends StoreDispatcher implements OnInit { } private initAppFunctionalities(): void { - if (this.webNodeService.hasWebNodeConfig() && !this.webNodeService.isWebNodeLoaded()) { + if ( + this.webNodeService.hasWebNodeConfig() && + !this.webNodeService.isWebNodeLoaded() + ) { if (!getWindow()?.location.href.includes(`/${Routes.LOADING_WEB_NODE}`)) { - this.router.navigate([Routes.LOADING_WEB_NODE], { queryParamsHandling: 'preserve' }); + this.router.navigate([Routes.LOADING_WEB_NODE], { + queryParamsHandling: 'preserve', + }); } } this.dispatch2(AppActions.init()); diff --git a/frontend/src/app/app.config.ts b/frontend/src/app/app.config.ts index d0d7107dd4..d9a400cff0 100644 --- a/frontend/src/app/app.config.ts +++ b/frontend/src/app/app.config.ts @@ -1,19 +1,44 @@ -import { ApplicationConfig, ErrorHandler, importProvidersFrom, Injectable, LOCALE_ID } from '@angular/core'; +import { + ApplicationConfig, + ErrorHandler, + importProvidersFrom, + Injectable, + LOCALE_ID, +} from '@angular/core'; import { provideRouter, Router } from '@angular/router'; import { provideAnimations } from '@angular/platform-browser/animations'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { provideClientHydration, withIncrementalHydration } from '@angular/platform-browser'; +import { + provideHttpClient, + withInterceptorsFromDi, +} from '@angular/common/http'; +import { + provideClientHydration, + withIncrementalHydration, +} from '@angular/platform-browser'; import { provideStore } from '@ngrx/store'; import { EffectsModule, provideEffects } from '@ngrx/effects'; -import { provideRouterStore, routerReducer, RouterStateSerializer } from '@ngrx/router-store'; +import { + provideRouterStore, + routerReducer, + RouterStateSerializer, +} from '@ngrx/router-store'; import { provideStoreDevtools } from '@ngrx/store-devtools'; import * as Sentry from '@sentry/angular'; import { registerLocaleData } from '@angular/common'; -import { GlobalErrorHandlerService, MergedRouterStateSerializer, safelyExecuteInBrowser, THEME_PROVIDER } from '@openmina/shared'; +import { + GlobalErrorHandlerService, + MergedRouterStateSerializer, + safelyExecuteInBrowser, + THEME_PROVIDER, +} from '@openmina/shared'; import { SETTINGS } from '@angular/fire/compat/firestore'; import { initializeApp, provideFirebaseApp } from '@angular/fire/app'; import { CONFIG } from '@shared/constants/config'; -import { getAnalytics, provideAnalytics, ScreenTrackingService } from '@angular/fire/analytics'; +import { + getAnalytics, + provideAnalytics, + ScreenTrackingService, +} from '@angular/fire/analytics'; import { getPerformance, providePerformance } from '@angular/fire/performance'; import { getFirestore, provideFirestore } from '@angular/fire/firestore'; import localeFr from '@angular/common/locales/fr'; @@ -53,17 +78,20 @@ export class AppGlobalErrorhandler implements ErrorHandler { }; // Regular error listener - window.addEventListener('error', (event: ErrorEvent) => { - event.preventDefault(); - this.handleError(event.error); - }, { capture: true }); + window.addEventListener( + 'error', + (event: ErrorEvent) => { + event.preventDefault(); + this.handleError(event.error); + }, + { capture: true }, + ); // Override console.error with proper error extraction const originalConsoleError = console.error; console.error = (...args) => { // Find the actual error object in the arguments - const error = args.find(arg => arg instanceof Error) || - args.join(' '); + const error = args.find(arg => arg instanceof Error) || args.join(' '); this.handleError(error); originalConsoleError.apply(console, args); @@ -75,9 +103,16 @@ export class AppGlobalErrorhandler implements ErrorHandler { const originalInstantiateStreaming = WebAssembly.instantiateStreaming; if (originalInstantiateStreaming) { - WebAssembly.instantiateStreaming = async function (response: any, importObject?: any): Promise { + WebAssembly.instantiateStreaming = async function ( + response: any, + importObject?: any, + ): Promise { try { - return await originalInstantiateStreaming.call(WebAssembly, response, importObject); + return await originalInstantiateStreaming.call( + WebAssembly, + response, + importObject, + ); } catch (error) { self.handleError(error); throw error; @@ -86,9 +121,16 @@ export class AppGlobalErrorhandler implements ErrorHandler { } const originalInstantiate = WebAssembly.instantiate; - WebAssembly.instantiate = async function (moduleObject: any, importObject?: any): Promise { + WebAssembly.instantiate = async function ( + moduleObject: any, + importObject?: any, + ): Promise { try { - return await originalInstantiate.call(WebAssembly, moduleObject, importObject); + return await originalInstantiate.call( + WebAssembly, + moduleObject, + importObject, + ); } catch (error) { self.handleError(error); throw error; @@ -123,38 +165,47 @@ const firebaseProviders = [ provideFirestore(() => getFirestore()), ]; - export const appConfig: ApplicationConfig = { providers: [ provideRouter(generateRoutes()), provideAnimations(), provideClientHydration(withIncrementalHydration()), provideHttpClient(withInterceptorsFromDi()), - provideStore({ - ...reducers, - router: routerReducer, - } as any, { - metaReducers, - runtimeChecks: { - strictStateImmutability: true, - strictActionImmutability: true, - strictActionWithinNgZone: true, - strictStateSerializability: true, + provideStore( + { + ...reducers, + router: routerReducer, + } as any, + { + metaReducers, + runtimeChecks: { + strictStateImmutability: true, + strictActionImmutability: true, + strictActionWithinNgZone: true, + strictStateSerializability: true, + }, }, - }), + ), provideRouterStore({ stateKey: 'router' }), { provide: RouterStateSerializer, useClass: MergedRouterStateSerializer, }, provideEffects(AppEffects), - !CONFIG.production ? provideStoreDevtools({ maxAge: 150, connectInZone: true }) : [], + !CONFIG.production + ? provideStoreDevtools({ maxAge: 150, connectInZone: true }) + : [], importProvidersFrom(EffectsModule.forRoot()), // Your custom providers THEME_PROVIDER, { provide: LOCALE_ID, useValue: 'en' }, { provide: ErrorHandler, useValue: Sentry.createErrorHandler() }, - { provide: ErrorHandler, useClass: AppGlobalErrorhandler, deps: [GlobalErrorHandlerService], multi: false }, + { + provide: ErrorHandler, + useClass: AppGlobalErrorhandler, + deps: [GlobalErrorHandlerService], + multi: false, + }, { provide: Sentry.TraceService, deps: [Router] }, ...(CONFIG.globalConfig.firebase ? firebaseProviders : []), ], diff --git a/frontend/src/app/app.effects.ts b/frontend/src/app/app.effects.ts index 26fbade7ec..3313d02ab6 100644 --- a/frontend/src/app/app.effects.ts +++ b/frontend/src/app/app.effects.ts @@ -2,11 +2,18 @@ import { Injectable } from '@angular/core'; import { MinaState, selectMinaState } from '@app/app.setup'; import { Actions, createEffect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; -import { createNonDispatchableEffect, Effect, removeParamsFromURL } from '@openmina/shared'; +import { + createNonDispatchableEffect, + Effect, + removeParamsFromURL, +} from '@openmina/shared'; import { filter, map, mergeMap, of, switchMap, tap } from 'rxjs'; import { AppActions } from '@app/app.actions'; import { Router } from '@angular/router'; -import { FeatureType, MinaNode } from '@shared/types/core/environment/mina-env.type'; +import { + FeatureType, + MinaNode, +} from '@shared/types/core/environment/mina-env.type'; import { AppService } from '@app/app.service'; import { getFirstFeature, isFeatureEnabled } from '@shared/constants/config'; import { RustService } from '@core/services/rust.service'; @@ -18,7 +25,6 @@ import { AppNodeStatus } from '@shared/types/app/app-node-details.type'; @Injectable() export class AppEffects extends BaseEffect { - readonly init$: Effect; readonly initSuccess$: Effect; readonly onNodeChange$: Effect; @@ -27,92 +33,121 @@ export class AppEffects extends BaseEffect { private requestInProgress: boolean = false; - constructor(private actions$: Actions, - private appService: AppService, - private rustNode: RustService, - private router: Router, - private webNodeService: WebNodeService, - store: Store) { + constructor( + private actions$: Actions, + private appService: AppService, + private rustNode: RustService, + private router: Router, + private webNodeService: WebNodeService, + store: Store, + ) { super(store, selectMinaState); - this.init$ = createEffect(() => this.actions$.pipe( - ofType(AppActions.init), - switchMap(() => this.appService.getNodes()), - switchMap((nodes: MinaNode[]) => this.appService.getActiveNode(nodes).pipe( - tap((activeNode: MinaNode) => this.rustNode.changeRustNode(activeNode)), - map((activeNode: MinaNode) => ({ activeNode, nodes })), - )), - map((payload: { activeNode: MinaNode, nodes: MinaNode[] }) => AppActions.initSuccess(payload)), - )); + this.init$ = createEffect(() => + this.actions$.pipe( + ofType(AppActions.init), + switchMap(() => this.appService.getNodes()), + switchMap((nodes: MinaNode[]) => + this.appService.getActiveNode(nodes).pipe( + tap((activeNode: MinaNode) => + this.rustNode.changeRustNode(activeNode), + ), + map((activeNode: MinaNode) => ({ activeNode, nodes })), + ), + ), + map((payload: { activeNode: MinaNode; nodes: MinaNode[] }) => + AppActions.initSuccess(payload), + ), + ), + ); - this.initSuccess$ = createEffect(() => this.actions$.pipe( - ofType(AppActions.initSuccess), - this.latestActionState(), - switchMap(({ state }) => { - if (state.app.activeNode.isWebNode) { - return this.webNodeService.loadWasm$().pipe( - switchMap(() => this.webNodeService.startWasm$()), - ); - } - return of({}); - }), - map(() => AppActions.getNodeEnvBuild()), - )); + this.initSuccess$ = createEffect(() => + this.actions$.pipe( + ofType(AppActions.initSuccess), + this.latestActionState(), + switchMap(({ state }) => { + if (state.app.activeNode.isWebNode) { + return this.webNodeService + .loadWasm$() + .pipe(switchMap(() => this.webNodeService.startWasm$())); + } + return of({}); + }), + map(() => AppActions.getNodeEnvBuild()), + ), + ); - this.onNodeChange$ = createNonDispatchableEffect(() => this.actions$.pipe( - ofType(AppActions.changeActiveNode), - this.latestActionState(), - tap(({ state }) => { - this.rustNode.changeRustNode(state.app.activeNode); - const activePage = removeParamsFromURL(this.router.url.split('/')[1]) as FeatureType; - this.router.navigate([], { - queryParams: { node: state.app.activeNode.name }, - queryParamsHandling: 'merge', - }); - if (!isFeatureEnabled(state.app.activeNode, activePage)) { - this.router.navigate([getFirstFeature(state.app.activeNode)]); - } - }), - switchMap(({ state }) => { - if (state.app.activeNode.isWebNode) { - return this.webNodeService.loadWasm$().pipe( - switchMap(() => this.webNodeService.startWasm$()), - ); - } - return of({}); - }), - switchMap(() => [AppActions.getNodeDetails(), AppActions.getNodeEnvBuild()]), - )); + this.onNodeChange$ = createNonDispatchableEffect(() => + this.actions$.pipe( + ofType(AppActions.changeActiveNode), + this.latestActionState(), + tap(({ state }) => { + this.rustNode.changeRustNode(state.app.activeNode); + const activePage = removeParamsFromURL( + this.router.url.split('/')[1], + ) as FeatureType; + this.router.navigate([], { + queryParams: { node: state.app.activeNode.name }, + queryParamsHandling: 'merge', + }); + if (!isFeatureEnabled(state.app.activeNode, activePage)) { + this.router.navigate([getFirstFeature(state.app.activeNode)]); + } + }), + switchMap(({ state }) => { + if (state.app.activeNode.isWebNode) { + return this.webNodeService + .loadWasm$() + .pipe(switchMap(() => this.webNodeService.startWasm$())); + } + return of({}); + }), + switchMap(() => [ + AppActions.getNodeDetails(), + AppActions.getNodeEnvBuild(), + ]), + ), + ); - this.getNodeEnvBuild$ = createEffect(() => this.actions$.pipe( - ofType(AppActions.getNodeEnvBuild), - mergeMap(() => this.appService.getEnvBuild()), - map(envBuild => AppActions.getNodeEnvBuildSuccess({ envBuild })), - catchErrorAndRepeat2(MinaErrorType.RUST, AppActions.getNodeEnvBuildSuccess({ envBuild: undefined })), - )); + this.getNodeEnvBuild$ = createEffect(() => + this.actions$.pipe( + ofType(AppActions.getNodeEnvBuild), + mergeMap(() => this.appService.getEnvBuild()), + map(envBuild => AppActions.getNodeEnvBuildSuccess({ envBuild })), + catchErrorAndRepeat2( + MinaErrorType.RUST, + AppActions.getNodeEnvBuildSuccess({ envBuild: undefined }), + ), + ), + ); - this.getNodeDetails$ = createEffect(() => this.actions$.pipe( - ofType(AppActions.getNodeDetails), - filter(() => !this.requestInProgress), - tap(() => this.requestInProgress = true), - switchMap(() => this.appService.getActiveNodeDetails()), - map(details => AppActions.getNodeDetailsSuccess({ details })), - catchErrorAndRepeat2(MinaErrorType.GENERIC, AppActions.getNodeDetailsSuccess({ - details: { - status: AppNodeStatus.OFFLINE, - blockHeight: null, - blockTime: null, - peersConnected: 0, - peersDisconnected: 0, - peersConnecting: 0, - transactions: 0, - snarks: 0, - producingBlockAt: null, - producingBlockGlobalSlot: null, - producingBlockStatus: null, - }, - })), - tap(() => this.requestInProgress = false), - )); + this.getNodeDetails$ = createEffect(() => + this.actions$.pipe( + ofType(AppActions.getNodeDetails), + filter(() => !this.requestInProgress), + tap(() => (this.requestInProgress = true)), + switchMap(() => this.appService.getActiveNodeDetails()), + map(details => AppActions.getNodeDetailsSuccess({ details })), + catchErrorAndRepeat2( + MinaErrorType.GENERIC, + AppActions.getNodeDetailsSuccess({ + details: { + status: AppNodeStatus.OFFLINE, + blockHeight: null, + blockTime: null, + peersConnected: 0, + peersDisconnected: 0, + peersConnecting: 0, + transactions: 0, + snarks: 0, + producingBlockAt: null, + producingBlockGlobalSlot: null, + producingBlockStatus: null, + }, + }), + ), + tap(() => (this.requestInProgress = false)), + ), + ); } } diff --git a/frontend/src/app/app.module.server.ts b/frontend/src/app/app.module.server.ts index 416f4bcd02..637413dfa5 100644 --- a/frontend/src/app/app.module.server.ts +++ b/frontend/src/app/app.module.server.ts @@ -5,10 +5,7 @@ import { appConfig } from '@app/app.config'; const serverConfig = { ...appConfig, - providers: [ - ...appConfig.providers, - provideServerRendering(), - ], + providers: [...appConfig.providers, provideServerRendering()], }; export default () => bootstrapApplication(AppComponent, serverConfig); diff --git a/frontend/src/app/app.reducer.ts b/frontend/src/app/app.reducer.ts index de4c8bb694..430b3982a7 100644 --- a/frontend/src/app/app.reducer.ts +++ b/frontend/src/app/app.reducer.ts @@ -7,7 +7,9 @@ import { getLocalStorage } from '@openmina/shared'; const initialState: AppState = { menu: { - collapsed: JSON.parse(getLocalStorage()?.getItem('menu_collapsed') ?? 'false') || false, + collapsed: + JSON.parse(getLocalStorage()?.getItem('menu_collapsed') ?? 'false') || + false, isMobile: false, open: true, }, @@ -31,9 +33,19 @@ const initialState: AppState = { export const appReducer = createReducer( initialState, - on(AppActions.initSuccess, (state, { activeNode, nodes }) => ({ ...state, activeNode, nodes })), - on(AppActions.changeActiveNode, (state, { node }) => ({ ...state, activeNode: node })), - on(AppActions.getNodeDetailsSuccess, (state, { details }) => ({ ...state, activeNodeDetails: details })), + on(AppActions.initSuccess, (state, { activeNode, nodes }) => ({ + ...state, + activeNode, + nodes, + })), + on(AppActions.changeActiveNode, (state, { node }) => ({ + ...state, + activeNode: node, + })), + on(AppActions.getNodeDetailsSuccess, (state, { details }) => ({ + ...state, + activeNodeDetails: details, + })), on(AppActions.changeMenuCollapsing, (state, { isCollapsing }) => { getLocalStorage()?.setItem('menu_collapsed', JSON.stringify(isCollapsing)); return { ...state, menu: { ...state.menu, collapsed: isCollapsing } }; @@ -42,17 +54,38 @@ export const appReducer = createReducer( ...state, menu: { ...state.menu, isMobile, open: !isMobile }, })), - on(AppActions.toggleMenuOpening, (state) => ({ ...state, menu: { ...state.menu, open: !state.menu.open } })), + on(AppActions.toggleMenuOpening, state => ({ + ...state, + menu: { ...state.menu, open: !state.menu.open }, + })), on(AppActions.addNode, (state, { node }) => { - const customNodes = JSON.parse(getLocalStorage()?.getItem('custom_nodes') ?? '[]'); - getLocalStorage()?.setItem('custom_nodes', JSON.stringify([node, ...customNodes])); + const customNodes = JSON.parse( + getLocalStorage()?.getItem('custom_nodes') ?? '[]', + ); + getLocalStorage()?.setItem( + 'custom_nodes', + JSON.stringify([node, ...customNodes]), + ); return { ...state, nodes: [node, ...state.nodes] }; }), on(AppActions.deleteNode, (state, { node }) => { - const customNodes = JSON.parse(getLocalStorage()?.getItem('custom_nodes') ?? '[]'); - getLocalStorage()?.setItem('custom_nodes', JSON.stringify(customNodes.filter((n: MinaNode) => n.name !== node.name))); + const customNodes = JSON.parse( + getLocalStorage()?.getItem('custom_nodes') ?? '[]', + ); + getLocalStorage()?.setItem( + 'custom_nodes', + JSON.stringify(customNodes.filter((n: MinaNode) => n.name !== node.name)), + ); const nodes = state.nodes.filter(n => n.name !== node.name); - return { ...state, nodes, activeNode: state.activeNode?.name === node.name ? nodes[0] : state.activeNode }; + return { + ...state, + nodes, + activeNode: + state.activeNode?.name === node.name ? nodes[0] : state.activeNode, + }; }), - on(AppActions.getNodeEnvBuildSuccess, (state, { envBuild }) => ({ ...state, envBuild })), + on(AppActions.getNodeEnvBuildSuccess, (state, { envBuild }) => ({ + ...state, + envBuild, + })), ); diff --git a/frontend/src/app/app.routing.ts b/frontend/src/app/app.routing.ts index 449caad3fc..1a099baeb4 100644 --- a/frontend/src/app/app.routing.ts +++ b/frontend/src/app/app.routing.ts @@ -20,68 +20,80 @@ 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'; - export function generateRoutes(): Routes { const routes: Routes = [ { path: 'dashboard', - loadChildren: () => import('@dashboard/dashboard.module').then(m => m.DashboardModule), + loadChildren: () => + import('@dashboard/dashboard.module').then(m => m.DashboardModule), title: DASHBOARD_TITLE, canActivate: [landingPageGuard], }, { path: 'nodes', - loadChildren: () => import('@nodes/nodes.module').then(m => m.NodesModule), + loadChildren: () => + import('@nodes/nodes.module').then(m => m.NodesModule), title: NODES_TITLE, // canActivate: [FeatureGuard], }, { path: 'resources', - loadChildren: () => import('@resources/resources.module').then(m => m.ResourcesModule), + loadChildren: () => + import('@resources/resources.module').then(m => m.ResourcesModule), title: RESOURCES_TITLE, }, { path: 'network', - loadChildren: () => import('@network/network.module').then(m => m.NetworkModule), + loadChildren: () => + import('@network/network.module').then(m => m.NetworkModule), title: NETWORK_TITLE, }, { path: 'state', - loadChildren: () => import('@state/state.module').then(m => m.StateModule), + loadChildren: () => + import('@state/state.module').then(m => m.StateModule), title: STATE_TITLE, canActivate: [landingPageGuard], }, { path: 'snarks', - loadChildren: () => import('@snarks/snarks.module').then(m => m.SnarksModule), + loadChildren: () => + import('@snarks/snarks.module').then(m => m.SnarksModule), title: SNARKS_TITLE, }, { path: 'block-production', - loadChildren: () => import('@block-production/block-production.module').then(m => m.BlockProductionModule), + loadChildren: () => + import('@block-production/block-production.module').then( + m => m.BlockProductionModule, + ), title: BLOCK_PRODUCTION_TITLE, canActivate: [landingPageGuard], }, { path: 'mempool', - loadChildren: () => import('@mempool/mempool.module').then(m => m.MempoolModule), + loadChildren: () => + import('@mempool/mempool.module').then(m => m.MempoolModule), title: MEMPOOL_TITLE, canActivate: [landingPageGuard], }, { path: 'benchmarks', - loadChildren: () => import('@benchmarks/benchmarks.module').then(m => m.BenchmarksModule), + loadChildren: () => + import('@benchmarks/benchmarks.module').then(m => m.BenchmarksModule), title: BENCHMARKS_TITLE, canActivate: [landingPageGuard], }, { path: 'fuzzing', - loadChildren: () => import('@fuzzing/fuzzing.module').then(m => m.FuzzingModule), + loadChildren: () => + import('@fuzzing/fuzzing.module').then(m => m.FuzzingModule), title: FUZZING_TITLE, }, { path: 'loading-web-node', - loadChildren: () => import('@web-node/web-node.module').then(m => m.WebNodeModule), + loadChildren: () => + import('@web-node/web-node.module').then(m => m.WebNodeModule), title: WEBNODE_TITLE, canActivate: [landingPageGuard], }, @@ -89,7 +101,10 @@ export function generateRoutes(): Routes { if (CONFIG.showLeaderboard) { routes.push({ path: '', - loadChildren: () => import('@leaderboard/leaderboard.module').then(m => m.LeaderboardModule), + loadChildren: () => + import('@leaderboard/leaderboard.module').then( + m => m.LeaderboardModule, + ), }); } else if (CONFIG.showWebNodeLandingPage) { routes.push({ @@ -108,7 +123,6 @@ export function generateRoutes(): Routes { ]; } - @NgModule({ imports: [ RouterModule.forRoot(generateRoutes(), { diff --git a/frontend/src/app/app.service.ts b/frontend/src/app/app.service.ts index 9694db4997..ccdc34f929 100644 --- a/frontend/src/app/app.service.ts +++ b/frontend/src/app/app.service.ts @@ -3,12 +3,13 @@ import { map, Observable, of, tap } from 'rxjs'; import { MinaNode } from '@shared/types/core/environment/mina-env.type'; import { CONFIG } from '@shared/constants/config'; import { RustService } from '@core/services/rust.service'; -import { AppNodeDetails, AppNodeStatus } from '@shared/types/app/app-node-details.type'; +import { + AppNodeDetails, + AppNodeStatus, +} from '@shared/types/app/app-node-details.type'; import { getNetwork } from '@shared/helpers/mina.helper'; import { getLocalStorage, nanOrElse, ONE_MILLION } from '@openmina/shared'; -import { - BlockProductionWonSlotsStatus, -} from '@shared/types/block-production/won-slots/block-production-won-slots-slot.type'; +import { BlockProductionWonSlotsStatus } from '@shared/types/block-production/won-slots/block-production-won-slots-slot.type'; import { AppEnvBuild } from '@shared/types/app/app-env-build.type'; import { SentryService } from '@core/services/sentry.service'; import { WebNodeService } from '@core/services/web-node.service'; @@ -17,13 +18,13 @@ import { WebNodeService } from '@core/services/web-node.service'; providedIn: 'root', }) export class AppService { - private previousProducedBlock: BlockProductionAttempt; - constructor(private rust: RustService, - private sentryService: SentryService, - private webnodeService: WebNodeService) { - } + constructor( + private rust: RustService, + private sentryService: SentryService, + private webnodeService: WebNodeService, + ) {} getActiveNode(nodes: MinaNode[]): Observable { const nodeName = new URL(location.href).searchParams.get('node'); @@ -44,25 +45,38 @@ export class AppService { } getActiveNodeDetails(): Observable { - return this.rust.get('/status') - .pipe( - tap((data: NodeDetailsResponse) => this.notifyPrevBlockChanged(data)), - map((data: NodeDetailsResponse): AppNodeDetails => ({ - status: this.getStatus(data), - blockHeight: data.transition_frontier.best_tip?.height, - blockTime: data.transition_frontier.sync.time, - peersConnected: data.peers.filter(p => p.connection_status === 'Connected').length, - peersDisconnected: data.peers.filter(p => p.connection_status === 'Disconnected').length, - peersConnecting: data.peers.filter(p => p.connection_status === 'Connecting').length, - snarks: data.snark_pool.snarks, - transactions: data.transaction_pool.transactions, - chainId: data.chain_id, - network: getNetwork(data.chain_id), - producingBlockAt: nanOrElse(data.current_block_production_attempt?.won_slot.slot_time / ONE_MILLION, null), - producingBlockGlobalSlot: data.current_block_production_attempt?.won_slot.global_slot, - producingBlockStatus: data.current_block_production_attempt?.status, - } as AppNodeDetails)), - ); + return this.rust.get('/status').pipe( + tap((data: NodeDetailsResponse) => this.notifyPrevBlockChanged(data)), + map( + (data: NodeDetailsResponse): AppNodeDetails => + ({ + status: this.getStatus(data), + blockHeight: data.transition_frontier.best_tip?.height, + blockTime: data.transition_frontier.sync.time, + peersConnected: data.peers.filter( + p => p.connection_status === 'Connected', + ).length, + peersDisconnected: data.peers.filter( + p => p.connection_status === 'Disconnected', + ).length, + peersConnecting: data.peers.filter( + p => p.connection_status === 'Connecting', + ).length, + snarks: data.snark_pool.snarks, + transactions: data.transaction_pool.transactions, + chainId: data.chain_id, + network: getNetwork(data.chain_id), + producingBlockAt: nanOrElse( + data.current_block_production_attempt?.won_slot.slot_time / + ONE_MILLION, + null, + ), + producingBlockGlobalSlot: + data.current_block_production_attempt?.won_slot.global_slot, + producingBlockStatus: data.current_block_production_attempt?.status, + }) as AppNodeDetails, + ), + ); } private notifyPrevBlockChanged(data: NodeDetailsResponse): void { @@ -78,10 +92,15 @@ export class AppService { ].includes(status); if ( - this.previousProducedBlock && data.previous_block_production_attempt - && isInProduction(this.previousProducedBlock.status) !== isInProduction(data.previous_block_production_attempt.status) + this.previousProducedBlock && + data.previous_block_production_attempt && + isInProduction(this.previousProducedBlock.status) !== + isInProduction(data.previous_block_production_attempt.status) ) { - this.sentryService.updateProducedBlock(data.previous_block_production_attempt, this.webnodeService.publicKey); + this.sentryService.updateProducedBlock( + data.previous_block_production_attempt, + this.webnodeService.publicKey, + ); } this.previousProducedBlock = data.previous_block_production_attempt; } @@ -138,7 +157,6 @@ export interface Times { discarded: any; } - interface TransitionFrontier { best_tip: BestTip; sync: Sync; diff --git a/frontend/src/app/app.setup.ts b/frontend/src/app/app.setup.ts index 252fba90f8..76f2103041 100644 --- a/frontend/src/app/app.setup.ts +++ b/frontend/src/app/app.setup.ts @@ -8,7 +8,10 @@ import { appReducer } from '@app/app.reducer'; import { APP_KEY } from '@app/app.actions'; import { AppState } from '@app/app.state'; -import { loadingReducer, LoadingState } from '@app/layout/toolbar/loading.reducer'; +import { + loadingReducer, + LoadingState, +} from '@app/layout/toolbar/loading.reducer'; import { dashboardReducer } from '@dashboard/dashboard.reducer'; import { DashboardAction } from '@dashboard/dashboard.actions'; @@ -26,7 +29,10 @@ import { StateState } from '@state/state.state'; import { SnarksAction, snarksReducer } from '@snarks/snarks.reducer'; import { SnarksState } from '@snarks/snarks.state'; -import { ResourcesAction, resourcesReducer } from '@resources/resources.reducer'; +import { + ResourcesAction, + resourcesReducer, +} from '@resources/resources.reducer'; import { ResourcesState } from '@resources/resources.state'; import { blockProductionReducer } from '@block-production/block-production.reducer'; @@ -58,16 +64,14 @@ export interface MinaState { leaderboard: LeaderboardState; } -type MinaAction = - & ErrorPreviewAction - & DashboardAction - & NetworkAction - & NodesAction - & ResourcesAction - & StateAction - & SnarksAction - & FuzzingAction - ; +type MinaAction = ErrorPreviewAction & + DashboardAction & + NetworkAction & + NodesAction & + ResourcesAction & + StateAction & + SnarksAction & + FuzzingAction; export const reducers: ActionReducerMap = { [APP_KEY]: appReducer, diff --git a/frontend/src/app/app.state.ts b/frontend/src/app/app.state.ts index 5899469521..419cb33976 100644 --- a/frontend/src/app/app.state.ts +++ b/frontend/src/app/app.state.ts @@ -13,10 +13,10 @@ export interface AppState { envBuild: AppEnvBuild | undefined; } -const select = (selector: (state: AppState) => T): MemoizedSelector => createSelector( - (state: MinaState): AppState => state.app, - selector, -); +const select = ( + selector: (state: AppState) => T, +): MemoizedSelector => + createSelector((state: MinaState): AppState => state.app, selector); const menu = select(state => state.menu); const nodes = select(state => state.nodes); diff --git a/frontend/src/app/core/helpers/file-progress.helper.ts b/frontend/src/app/core/helpers/file-progress.helper.ts index fed9a8d31f..869d1c4da1 100644 --- a/frontend/src/app/core/helpers/file-progress.helper.ts +++ b/frontend/src/app/core/helpers/file-progress.helper.ts @@ -57,7 +57,8 @@ class AssetMonitor { } receivedLength += value.length; - downloadInfo.progress = (receivedLength / downloadInfo.totalSize) * 100; + downloadInfo.progress = + (receivedLength / downloadInfo.totalSize) * 100; self.emitProgress(downloadInfo); } catch (error) { downloadInfo.status = 'error'; @@ -88,7 +89,7 @@ class AssetMonitor { duration: downloadInfo.duration, startTime: downloadInfo.startTime, endTime: downloadInfo.endTime, - downloaded: downloadInfo.progress * downloadInfo.totalSize / 100, + downloaded: (downloadInfo.progress * downloadInfo.totalSize) / 100, }); } } diff --git a/frontend/src/app/core/services/config.service.ts b/frontend/src/app/core/services/config.service.ts index 3b5e6080a4..b492f80484 100644 --- a/frontend/src/app/core/services/config.service.ts +++ b/frontend/src/app/core/services/config.service.ts @@ -9,19 +9,20 @@ import { filter } from 'rxjs'; providedIn: 'root', }) export class ConfigService { - private node: MinaNode; - constructor(private store: Store) { this.listenToNodeChanging(); } + constructor(private store: Store) { + this.listenToNodeChanging(); + } private listenToNodeChanging(): void { - this.store.select(AppSelectors.activeNode) + this.store + .select(AppSelectors.activeNode) .pipe(filter(Boolean)) - .subscribe((node: MinaNode) => this.node = node); + .subscribe((node: MinaNode) => (this.node = node)); } get DEBUGGER(): string { return this.node.debugger; } - } diff --git a/frontend/src/app/core/services/firestore.service.ts b/frontend/src/app/core/services/firestore.service.ts index 9f3f6e047f..9fe6639497 100644 --- a/frontend/src/app/core/services/firestore.service.ts +++ b/frontend/src/app/core/services/firestore.service.ts @@ -7,22 +7,24 @@ import { SentryService } from '@core/services/sentry.service'; providedIn: 'root', }) export class FirestoreService { - private cloudFunctionUrl = 'https://us-central1-webnode-gtm-test.cloudfunctions.net/handleValidationAndStore'; + private cloudFunctionUrl = + 'https://us-central1-webnode-gtm-test.cloudfunctions.net/handleValidationAndStore'; - constructor(private sentryService: SentryService, - private http: HttpClient) { } + constructor( + private sentryService: SentryService, + private http: HttpClient, + ) {} addHeartbeat(data: any): Observable { console.log('Posting to cloud function:', data); - return this.http.post(this.cloudFunctionUrl, { data }) - .pipe( - // tap(() => { - // this.sentryService.updateHeartbeat(data, data.submitter); - // }), - catchError(error => { - console.error('Error while posting heartbeat', error); - return of(null); - }), - ); + return this.http.post(this.cloudFunctionUrl, { data }).pipe( + // tap(() => { + // this.sentryService.updateHeartbeat(data, data.submitter); + // }), + catchError(error => { + console.error('Error while posting heartbeat', error); + return of(null); + }), + ); } } diff --git a/frontend/src/app/core/services/rust.service.ts b/frontend/src/app/core/services/rust.service.ts index 4a3fe69be5..2d10401d67 100644 --- a/frontend/src/app/core/services/rust.service.ts +++ b/frontend/src/app/core/services/rust.service.ts @@ -8,11 +8,12 @@ import { WebNodeService } from '@core/services/web-node.service'; providedIn: 'root', }) export class RustService { - private node: MinaNode; - constructor(private http: HttpClient, - private webNodeService: WebNodeService) {} + constructor( + private http: HttpClient, + private webNodeService: WebNodeService, + ) {} changeRustNode(node: MinaNode): void { this.node = node; @@ -32,20 +33,24 @@ export class RustService { get(path: string): Observable { if (this.node.isWebNode) { - return this.getFromWebNode(path).pipe(map((response: any) => { - // console.log(path, response); - return response; - })); + return this.getFromWebNode(path).pipe( + map((response: any) => { + // console.log(path, response); + return response; + }), + ); } return this.http.get(this.URL + path); } post(path: string, body: B): Observable { if (this.node.isWebNode) { - return this.postToWebNode(path, body).pipe(map((response: any) => { - // console.log(path, response); - return response; - })); + return this.postToWebNode(path, body).pipe( + map((response: any) => { + // console.log(path, response); + return response; + }), + ); } return this.http.post(this.URL + path, body); } diff --git a/frontend/src/app/core/services/sentry.service.ts b/frontend/src/app/core/services/sentry.service.ts index 2007879b57..7949b0f028 100644 --- a/frontend/src/app/core/services/sentry.service.ts +++ b/frontend/src/app/core/services/sentry.service.ts @@ -1,25 +1,22 @@ import { Injectable } from '@angular/core'; import { NodesOverviewLedger, - NodesOverviewLedgerStepState + NodesOverviewLedgerStepState, } from '@shared/types/nodes/dashboard/nodes-overview-ledger.type'; import * as Sentry from '@sentry/angular'; import { NodesOverviewBlock, - NodesOverviewNodeBlockStatus + NodesOverviewNodeBlockStatus, } from '@shared/types/nodes/dashboard/nodes-overview-block.type'; import { lastItem, ONE_BILLION } from '@openmina/shared'; import { getElapsedTime } from '@shared/helpers/date.helper'; -import { - BlockProductionWonSlotsSlot -} from '@shared/types/block-production/won-slots/block-production-won-slots-slot.type'; +import { BlockProductionWonSlotsSlot } from '@shared/types/block-production/won-slots/block-production-won-slots-slot.type'; import { BlockProductionAttempt } from '@app/app.service'; @Injectable({ providedIn: 'root', }) export class SentryService { - private ledgerIsSynced: boolean = false; private blockIsSynced: boolean = false; private ledgerSyncedTime: number; @@ -34,7 +31,8 @@ export class SentryService { const syncDetails = { stakingLedger: { fetchHashes: ledger.stakingEpoch.snarked.fetchHashesDuration + 's', - fetchAccounts: ledger.stakingEpoch.snarked.fetchAccountsDuration + 's', + fetchAccounts: + ledger.stakingEpoch.snarked.fetchAccountsDuration + 's', }, nextEpochLedger: { fetchHashes: ledger.nextEpoch.snarked.fetchHashesDuration + 's', @@ -50,13 +48,20 @@ export class SentryService { }, }; - const syncedIn = Math.round((ledger.rootStaged.staged.reconstructEnd - ledger.stakingEpoch.snarked.fetchHashesStart) / ONE_BILLION); + const syncedIn = Math.round( + (ledger.rootStaged.staged.reconstructEnd - + ledger.stakingEpoch.snarked.fetchHashesStart) / + ONE_BILLION, + ); this.ledgerSyncedTime = syncedIn; Sentry.captureMessage(`Ledger synced in ${getElapsedTime(syncedIn)}`, { level: 'info', tags: { - type: 'webnode', subType: 'sync.ledger', publicKey, duration: syncedIn + type: 'webnode', + subType: 'sync.ledger', + publicKey, + duration: syncedIn, }, contexts: { ledger: syncDetails }, fingerprint: this.fingerprint, @@ -64,36 +69,54 @@ export class SentryService { } } - updateBlockSyncStatus(blocks: NodesOverviewBlock[], startTime: number, publicKey: string): void { + updateBlockSyncStatus( + blocks: NodesOverviewBlock[], + startTime: number, + publicKey: string, + ): void { if (this.blockIsSynced) { return; } - const blocksSynced = blocks.every(b => b.status === NodesOverviewNodeBlockStatus.APPLIED); + 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; this.blockSyncedTime = Math.round((Date.now() - startTime) / 1000); - Sentry.captureMessage(`Last 290 blocks synced in ${getElapsedTime(this.blockSyncedTime)}`, { - level: 'info', - tags: { - type: 'webnode', subType: 'sync.block', publicKey, duration: this.blockSyncedTime + Sentry.captureMessage( + `Last 290 blocks synced in ${getElapsedTime(this.blockSyncedTime)}`, + { + level: 'info', + tags: { + type: 'webnode', + subType: 'sync.block', + publicKey, + duration: this.blockSyncedTime, + }, + contexts: { blocks: { bestTipBlock, root } }, + fingerprint: this.fingerprint, }, - contexts: { blocks: { bestTipBlock, root } }, - fingerprint: this.fingerprint, - }); + ); const syncTotal = this.ledgerSyncedTime + this.blockSyncedTime; setTimeout(() => { - Sentry.captureMessage(`Web Node Synced in ${getElapsedTime(syncTotal)}`, { - level: 'info', - tags: { - type: 'webnode', subType: 'sync.total', publicKey, duration: syncTotal + Sentry.captureMessage( + `Web Node Synced in ${getElapsedTime(syncTotal)}`, + { + level: 'info', + tags: { + type: 'webnode', + subType: 'sync.total', + publicKey, + duration: syncTotal, + }, + fingerprint: this.fingerprint, }, - fingerprint: this.fingerprint, - }); + ); }, 2000); } } @@ -101,43 +124,87 @@ export class SentryService { updatePeersConnected(seconds: number, publicKey: string): void { Sentry.captureMessage(`Web Node connected in ${seconds.toFixed(1)}s`, { level: 'info', - tags: { type: 'webnode', subType: 'sync.peers', publicKey, duration: seconds }, + tags: { + type: 'webnode', + subType: 'sync.peers', + publicKey, + duration: seconds, + }, fingerprint: this.fingerprint, }); } - updateProducedBlock(attempt: BlockProductionAttempt, publicKey: string): void { + updateProducedBlock( + attempt: BlockProductionAttempt, + publicKey: string, + ): void { const times = { - stagedLedgerDiffCreate: !attempt.times.staged_ledger_diff_create_end || !attempt.times.staged_ledger_diff_create_start - ? 0 : (attempt.times.staged_ledger_diff_create_end - attempt.times.staged_ledger_diff_create_start) / ONE_BILLION, - produced: !attempt.times.produced || !attempt.times.staged_ledger_diff_create_end - ? 0 : (attempt.times.produced - attempt.times.staged_ledger_diff_create_end) / ONE_BILLION, - proofCreate: !attempt.times.proof_create_end || !attempt.times.proof_create_start - ? 0 : (attempt.times.proof_create_end - attempt.times.proof_create_start) / ONE_BILLION, + stagedLedgerDiffCreate: + !attempt.times.staged_ledger_diff_create_end || + !attempt.times.staged_ledger_diff_create_start + ? 0 + : (attempt.times.staged_ledger_diff_create_end - + attempt.times.staged_ledger_diff_create_start) / + ONE_BILLION, + produced: + !attempt.times.produced || !attempt.times.staged_ledger_diff_create_end + ? 0 + : (attempt.times.produced - + attempt.times.staged_ledger_diff_create_end) / + ONE_BILLION, + proofCreate: + !attempt.times.proof_create_end || !attempt.times.proof_create_start + ? 0 + : (attempt.times.proof_create_end - + attempt.times.proof_create_start) / + ONE_BILLION, }; - Sentry.captureMessage(`Block Production Finished (${attempt.status}) - ` + attempt.block?.height, { - level: 'info', - tags: { type: 'webnode', subType: 'block.production', publicKey, duration: times.stagedLedgerDiffCreate + times.produced + times.proofCreate }, - fingerprint: this.fingerprint, - contexts: { block: this.flattenObject(attempt) }, - }); + Sentry.captureMessage( + `Block Production Finished (${attempt.status}) - ` + + attempt.block?.height, + { + level: 'info', + tags: { + type: 'webnode', + subType: 'block.production', + publicKey, + duration: + times.stagedLedgerDiffCreate + times.produced + times.proofCreate, + }, + fingerprint: this.fingerprint, + contexts: { block: this.flattenObject(attempt) }, + }, + ); } updateHeartbeat(data: any, publicKey: string): void { Sentry.captureMessage('Heartbeat', { level: 'info', tags: { type: 'webnode', subType: 'heartbeat', publicKey }, - contexts: { heartbeat: { payload: data.payload, signatureField: data.signature.field, signatureScalar: data.signature.scalar } }, + contexts: { + heartbeat: { + payload: data.payload, + signatureField: data.signature.field, + signatureScalar: data.signature.scalar, + }, + }, fingerprint: this.fingerprint, }); } - private flattenObject(obj: Record, prefix: string = ''): Record { + private flattenObject( + obj: Record, + prefix: string = '', + ): Record { return Object.keys(obj).reduce((acc: Record, key: string) => { const prefixedKey = prefix ? `${prefix}.${key}` : key; - if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) { + if ( + typeof obj[key] === 'object' && + obj[key] !== null && + !Array.isArray(obj[key]) + ) { const nestedObj = this.flattenObject(obj[key], prefixedKey); Object.assign(acc, nestedObj); } else { diff --git a/frontend/src/app/core/services/web-node.service.ts b/frontend/src/app/core/services/web-node.service.ts index df2f81057e..597153e6c2 100644 --- a/frontend/src/app/core/services/web-node.service.ts +++ b/frontend/src/app/core/services/web-node.service.ts @@ -1,7 +1,27 @@ import { Injectable } from '@angular/core'; -import { BehaviorSubject, catchError, EMPTY, filter, from, fromEvent, map, merge, Observable, of, switchMap, tap, throwError, timer } from 'rxjs'; +import { + BehaviorSubject, + catchError, + EMPTY, + filter, + from, + fromEvent, + map, + merge, + Observable, + of, + switchMap, + tap, + throwError, + timer, +} from 'rxjs'; import base from 'base-x'; -import { any, isBrowser, safelyExecuteInBrowser, getLocalStorage } from '@openmina/shared'; +import { + any, + isBrowser, + safelyExecuteInBrowser, + getLocalStorage, +} from '@openmina/shared'; import { HttpClient } from '@angular/common/http'; import { sendSentryEvent } from '@shared/helpers/webnode.helper'; import { DashboardPeerStatus } from '@shared/types/dashboard/dashboard.peer'; @@ -21,26 +41,32 @@ export interface PrivateStake { providedIn: 'root', }) export class WebNodeService { - - private readonly webnode$: BehaviorSubject = new BehaviorSubject(null); + private readonly webnode$: BehaviorSubject = new BehaviorSubject( + null, + ); private readonly wasm$: BehaviorSubject = new BehaviorSubject(null); - private webNodeKeyPair: { publicKey: string, privateKey: string }; + private webNodeKeyPair: { publicKey: string; privateKey: string }; private webNodeNetwork: String; private webNodeStartTime: number; private sentryEvents: any = {}; - readonly webnodeProgress$: BehaviorSubject = new BehaviorSubject(''); + readonly webnodeProgress$: BehaviorSubject = + new BehaviorSubject(''); memory: WebAssembly.MemoryDescriptor; privateStake: PrivateStake; noBlockProduction: boolean = false; - constructor(private http: HttpClient, - private firestore: FirestoreService, - private sentryService: SentryService) { + constructor( + private http: HttpClient, + private firestore: FirestoreService, + private sentryService: SentryService, + ) { FileProgressHelper.initDownloadProgress(); - const basex = base('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'); + const basex = base( + '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz', + ); safelyExecuteInBrowser(() => { any(window).bs58btc = { encode: (buffer: Uint8Array | number[]) => 'z' + basex.encode(buffer), @@ -82,10 +108,22 @@ export class WebNodeService { switchMap(() => { const DEFAULT_NETWORK = 'devnet'; if (!args) { - return this.http.get<{ publicKey: string, privateKey: string }>('assets/webnode/web-node-secrets.json') - .pipe(map(blockProducer => ({ blockProducer, network: DEFAULT_NETWORK }))); + return this.http + .get<{ + publicKey: string; + privateKey: string; + }>('assets/webnode/web-node-secrets.json') + .pipe( + map(blockProducer => ({ + blockProducer, + network: DEFAULT_NETWORK, + })), + ); } - const data = { network: args['network'] || DEFAULT_NETWORK, blockProducer: {} as any }; + const data = { + network: args['network'] || DEFAULT_NETWORK, + blockProducer: {} as any, + }; if (!!args['block_producer']) { data['blockProducer'] = { privateKey: args['block_producer'].sec_key, @@ -106,55 +144,63 @@ export class WebNodeService { startWasm$(): Observable { if (isBrowser()) { - return of(any(window).webnode) - .pipe( - switchMap((wasm: any) => { - this.wasm$.next(wasm); - return from(wasm.default(undefined, new WebAssembly.Memory(this.memory))) - .pipe(map(() => wasm)); - }), - switchMap((wasm) => { - this.webnodeProgress$.next('Loaded'); - const urls = (() => { - if (typeof this.webNodeNetwork === 'number') { - const url = `${window.location.origin}/clusters/${this.webNodeNetwork}/`; - return { - seeds: url + 'seeds', - genesisConfig: url + 'genesis/config', - }; - } else { - return { - seeds: 'https://bootnodes.minaprotocol.com/networks/devnet-webrtc.txt', - }; - } - })(); - console.log('webnode config:', !!this.webNodeKeyPair.privateKey, this.webNodeNetwork, urls); - let privateKey = this.privateStake ? [this.privateStake.stake, this.privateStake.password] : this.webNodeKeyPair.privateKey; - if (this.noBlockProduction) { - privateKey = null; + return of(any(window).webnode).pipe( + switchMap((wasm: any) => { + this.wasm$.next(wasm); + return from( + wasm.default(undefined, new WebAssembly.Memory(this.memory)), + ).pipe(map(() => wasm)); + }), + switchMap(wasm => { + this.webnodeProgress$.next('Loaded'); + const urls = (() => { + if (typeof this.webNodeNetwork === 'number') { + const url = `${window.location.origin}/clusters/${this.webNodeNetwork}/`; + return { + seeds: url + 'seeds', + genesisConfig: url + 'genesis/config', + }; + } else { + return { + seeds: + 'https://bootnodes.minaprotocol.com/networks/devnet-webrtc.txt', + }; } + })(); + console.log( + 'webnode config:', + !!this.webNodeKeyPair.privateKey, + this.webNodeNetwork, + urls, + ); + let privateKey = this.privateStake + ? [this.privateStake.stake, this.privateStake.password] + : this.webNodeKeyPair.privateKey; + if (this.noBlockProduction) { + privateKey = null; + } - return from(wasm.run(privateKey, urls.seeds, urls.genesisConfig)); - }), - tap((webnode: any) => { - any(window).webnode = webnode; - this.webnode$.next(webnode); - this.webnodeProgress$.next('Started'); - }), - catchError((error) => { - sendSentryEvent('WebNode failed to start: ' + error.message); - return throwError(() => new Error(error.message)); - }), - switchMap(() => this.webnode$.asObservable()), - filter(() => CONFIG.globalConfig.heartbeats), - switchMap(() => timer(0, 60000)), - switchMap(() => this.heartBeat$), - switchMap(heartBeat => this.firestore.addHeartbeat(heartBeat)), - catchError(error => { - console.log('Error from heartbeat api:', error); - return of(null); - }), - ); + return from(wasm.run(privateKey, urls.seeds, urls.genesisConfig)); + }), + tap((webnode: any) => { + any(window).webnode = webnode; + this.webnode$.next(webnode); + this.webnodeProgress$.next('Started'); + }), + catchError(error => { + sendSentryEvent('WebNode failed to start: ' + error.message); + return throwError(() => new Error(error.message)); + }), + switchMap(() => this.webnode$.asObservable()), + filter(() => CONFIG.globalConfig.heartbeats), + switchMap(() => timer(0, 60000)), + switchMap(() => this.heartBeat$), + switchMap(heartBeat => this.firestore.addHeartbeat(heartBeat)), + catchError(error => { + console.log('Error from heartbeat api:', error); + return of(null); + }), + ); } return EMPTY; } @@ -185,7 +231,12 @@ export class WebNodeService { // if (!this.sentryEvents.sentPeersEvent && peers.length > 0) { // this.sentryEvents.sentPeersEvent = true; // } - if (!this.sentryEvents.firstPeerConnected && peers.some((p: any) => p.connection_status === DashboardPeerStatus.CONNECTED)) { + if ( + !this.sentryEvents.firstPeerConnected && + peers.some( + (p: any) => p.connection_status === DashboardPeerStatus.CONNECTED, + ) + ) { const seconds = (Date.now() - this.webNodeStartTime) / 1000; this.sentryService.updatePeersConnected(seconds, this.publicKey); this.sentryEvents.firstPeerConnected = true; @@ -212,21 +263,27 @@ export class WebNodeService { get accounts$(): Observable { return this.webnode$.asObservable().pipe( filter(Boolean), - switchMap(webnode => from(any(webnode).ledger().latest().accounts().all())), + switchMap(webnode => + from(any(webnode).ledger().latest().accounts().all()), + ), ); } get bestChainUserCommands$(): Observable { return this.webnode$.asObservable().pipe( filter(Boolean), - switchMap(webnode => from(any(webnode).transition_frontier().best_chain().user_commands())), + switchMap(webnode => + from(any(webnode).transition_frontier().best_chain().user_commands()), + ), ); } sendPayment$(payment: any): Observable { return this.webnode$.asObservable().pipe( filter(Boolean), - switchMap(webnode => from(any(webnode).transaction_pool().inject().payment(payment))), + switchMap(webnode => + from(any(webnode).transaction_pool().inject().payment(payment)), + ), ); } diff --git a/frontend/src/app/features/benchmarks/benchmarks.component.ts b/frontend/src/app/features/benchmarks/benchmarks.component.ts index 18690b913e..40063835c4 100644 --- a/frontend/src/app/features/benchmarks/benchmarks.component.ts +++ b/frontend/src/app/features/benchmarks/benchmarks.component.ts @@ -3,16 +3,15 @@ import { BenchmarksWalletsService } from '@benchmarks/wallets/benchmarks-wallets import { ONE_BILLION } from '@openmina/shared'; @Component({ - selector: 'mina-benchmarks', - templateUrl: './benchmarks.component.html', - styleUrls: ['./benchmarks.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, - host: { class: 'flex-column h-100' }, - standalone: false + selector: 'mina-benchmarks', + templateUrl: './benchmarks.component.html', + styleUrls: ['./benchmarks.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + host: { class: 'flex-column h-100' }, + standalone: false, }) export class BenchmarksComponent implements OnInit { - - constructor(private service: BenchmarksWalletsService) { } + constructor(private service: BenchmarksWalletsService) {} ngOnInit(): void { // setTimeout(() => { diff --git a/frontend/src/app/features/benchmarks/benchmarks.module.ts b/frontend/src/app/features/benchmarks/benchmarks.module.ts index 1be959d280..77e9d794f8 100644 --- a/frontend/src/app/features/benchmarks/benchmarks.module.ts +++ b/frontend/src/app/features/benchmarks/benchmarks.module.ts @@ -2,13 +2,8 @@ import { NgModule } from '@angular/core'; import { BenchmarksComponent } from './benchmarks.component'; import { BenchmarksRouting } from '@benchmarks/benchmarks.routing'; - @NgModule({ - declarations: [ - BenchmarksComponent, - ], - imports: [ - BenchmarksRouting, - ], + declarations: [BenchmarksComponent], + imports: [BenchmarksRouting], }) export class BenchmarksModule {} diff --git a/frontend/src/app/features/benchmarks/benchmarks.reducer.ts b/frontend/src/app/features/benchmarks/benchmarks.reducer.ts index 2827ee169d..1fbae32193 100644 --- a/frontend/src/app/features/benchmarks/benchmarks.reducer.ts +++ b/frontend/src/app/features/benchmarks/benchmarks.reducer.ts @@ -3,7 +3,7 @@ import { ActionReducer, combineReducers } from '@ngrx/store'; import * as fromWallets from '@benchmarks/wallets/benchmarks-wallets.reducer'; - -export const benchmarksReducer: ActionReducer = combineReducers({ - wallets: fromWallets.reducer, -}); +export const benchmarksReducer: ActionReducer = + combineReducers({ + wallets: fromWallets.reducer, + }); diff --git a/frontend/src/app/features/benchmarks/benchmarks.routing.ts b/frontend/src/app/features/benchmarks/benchmarks.routing.ts index 3e1f4a637f..492f268231 100644 --- a/frontend/src/app/features/benchmarks/benchmarks.routing.ts +++ b/frontend/src/app/features/benchmarks/benchmarks.routing.ts @@ -10,7 +10,10 @@ const routes: Routes = [ children: [ { path: 'wallets', - loadChildren: () => import('@benchmarks/wallets/benchmarks-wallets.module').then(m => m.BenchmarksWalletsModule), + loadChildren: () => + import('@benchmarks/wallets/benchmarks-wallets.module').then( + m => m.BenchmarksWalletsModule, + ), title: BENCHMARKS_TITLE, }, { diff --git a/frontend/src/app/features/benchmarks/benchmarks.state.ts b/frontend/src/app/features/benchmarks/benchmarks.state.ts index b11f7cb100..8e35594a2b 100644 --- a/frontend/src/app/features/benchmarks/benchmarks.state.ts +++ b/frontend/src/app/features/benchmarks/benchmarks.state.ts @@ -1,4 +1,8 @@ -import { createFeatureSelector, createSelector, MemoizedSelector } from '@ngrx/store'; +import { + createFeatureSelector, + createSelector, + MemoizedSelector, +} from '@ngrx/store'; import { MinaState } from '@app/app.setup'; import { BenchmarksWalletsState } from '@benchmarks/wallets/benchmarks-wallets.state'; @@ -6,10 +10,13 @@ export interface BenchmarksState { wallets: BenchmarksWalletsState; } -const select = (selector: (state: BenchmarksState) => T): MemoizedSelector => createSelector( - selectBenchmarksState, - selector, -); +const select = ( + selector: (state: BenchmarksState) => T, +): MemoizedSelector => + createSelector(selectBenchmarksState, selector); -export const selectBenchmarksState = createFeatureSelector('benchmarks'); -export const selectBenchmarksWalletsState = select((state: BenchmarksState): BenchmarksWalletsState => state.wallets); +export const selectBenchmarksState = + createFeatureSelector('benchmarks'); +export const selectBenchmarksWalletsState = select( + (state: BenchmarksState): BenchmarksWalletsState => state.wallets, +); diff --git a/frontend/src/app/features/benchmarks/wallets/benchmarks-wallets-table/benchmarks-wallets-table.component.html b/frontend/src/app/features/benchmarks/wallets/benchmarks-wallets-table/benchmarks-wallets-table.component.html index fe75965322..29c2793a27 100644 --- a/frontend/src/app/features/benchmarks/wallets/benchmarks-wallets-table/benchmarks-wallets-table.component.html +++ b/frontend/src/app/features/benchmarks/wallets/benchmarks-wallets-table/benchmarks-wallets-table.component.html @@ -2,15 +2,19 @@ - + - {{ row.minaTokens | number:'1.0-3':'fr' }} + {{ row.minaTokens | number: '1.0-3' : 'fr' }} {{ row.nonce }} {{ row.lastTxTime || '-' }} {{ row.lastTxMemo || '-' | truncateMid }} - {{ row.lastTxStatus || '-' }} + + {{ row.lastTxStatus || '-' }} + {{ row.successTx }} success, {{ row.failedTx }} failed diff --git a/frontend/src/app/features/benchmarks/wallets/benchmarks-wallets-table/benchmarks-wallets-table.component.ts b/frontend/src/app/features/benchmarks/wallets/benchmarks-wallets-table/benchmarks-wallets-table.component.ts index c9e75cb3db..de6dc9a931 100644 --- a/frontend/src/app/features/benchmarks/wallets/benchmarks-wallets-table/benchmarks-wallets-table.component.ts +++ b/frontend/src/app/features/benchmarks/wallets/benchmarks-wallets-table/benchmarks-wallets-table.component.ts @@ -6,15 +6,17 @@ import { TableColumnList } from '@openmina/shared'; import { MinaTableRustWrapper } from '@shared/base-classes/mina-table-rust-wrapper.class'; @Component({ - selector: 'mina-benchmarks-wallets-table', - templateUrl: './benchmarks-wallets-table.component.html', - styleUrls: ['./benchmarks-wallets-table.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, - host: { class: 'flex-column h-100' }, - standalone: false + selector: 'mina-benchmarks-wallets-table', + templateUrl: './benchmarks-wallets-table.component.html', + styleUrls: ['./benchmarks-wallets-table.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + host: { class: 'flex-column h-100' }, + standalone: false, }) -export class BenchmarksWalletsTableComponent extends MinaTableRustWrapper implements OnInit { - +export class BenchmarksWalletsTableComponent + extends MinaTableRustWrapper + implements OnInit +{ protected readonly tableHeads: TableColumnList = [ { name: 'public key' }, { name: 'balance' }, @@ -35,10 +37,13 @@ export class BenchmarksWalletsTableComponent extends MinaTableRustWrapper { - this.table.rows = wallets; - this.table.detect(); - }, filter(wallets => wallets.length > 0)); + this.select( + selectBenchmarksWallets, + (wallets: BenchmarksWallet[]) => { + this.table.rows = wallets; + this.table.detect(); + }, + filter(wallets => wallets.length > 0), + ); } } - diff --git a/frontend/src/app/features/benchmarks/wallets/benchmarks-wallets-toolbar/benchmarks-wallets-toolbar.component.html b/frontend/src/app/features/benchmarks/wallets/benchmarks-wallets-toolbar/benchmarks-wallets-toolbar.component.html index 099ebdc2ba..5ff1851f69 100644 --- a/frontend/src/app/features/benchmarks/wallets/benchmarks-wallets-toolbar/benchmarks-wallets-toolbar.component.html +++ b/frontend/src/app/features/benchmarks/wallets/benchmarks-wallets-toolbar/benchmarks-wallets-toolbar.component.html @@ -1,66 +1,109 @@
-
- - +
transactions with
- +
MINA amount and
- +
MINA fee from
- -
-
-
Sent Tx. overview: {{ successSentTransactions }} - success, {{ failSentTransactions }} failed +
+ Sent Tx. overview: {{ successSentTransactions }} success, + {{ failSentTransactions }} failed
-