Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(guardian-prover-health-check-ui): switch to address routes instead of id #16846

Merged
merged 7 commits into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 0 additions & 33 deletions .github/workflows/guardian-prover-health-check-ui-preview.yml

This file was deleted.

30 changes: 0 additions & 30 deletions .github/workflows/guardian-prover-health-check-ui-production.yml

This file was deleted.

43 changes: 43 additions & 0 deletions .github/workflows/guardian-ui-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Build and Deploy Guardians UI to Vercel

on:
workflow_call:
inputs:
environment:
type: string
required: true
flags:
type: string
required: true
vercel_org_id:
type: string
required: true
vercel_project_id:
type: string
required: true

env:
VERCEL_ORG_ID: ${{ inputs.vercel_org_id }}
VERCEL_PROJECT_ID: ${{ inputs.vercel_project_id }}

jobs:
build-deploy:
runs-on: [taiko-runner]
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install pnpm dependencies
uses: ./.github/actions/install-pnpm-dependencies

- name: Install Vercel CLI
run: pnpm add --global vercel@latest

- name: Pull Vercel Environment Information
run: vercel pull --yes --environment=${{ inputs.environment }} --token=${{ secrets.VERCEL_TOKEN }}

- name: Build Project Artifacts
run: vercel build ${{ inputs.flags }} --token=${{ secrets.VERCEL_TOKEN }}

- name: Deploy Project Artifacts to Vercel
run: vercel deploy --prebuilt ${{ inputs.flags }} --token=${{ secrets.VERCEL_TOKEN }}
37 changes: 37 additions & 0 deletions .github/workflows/guardian-ui.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Guardian UI CI/CD

on:
push:
branches-ignore:
- release-please-*
paths:
- "packages/guardian-prover-health-check-ui/**"

jobs:
# Deployment name follow the pattern: deploy_<appname(bridge-ui)>_<network(devnet|hekla|mainnet)>_<environment(preview|production)>
deploy_guardian-ui_hekla_preview:
if: ${{ !github.ref_name == 'main' }}
uses: ./.github/workflows/guardian-ui-deploy.yml
with:
environment: "preview"
flags: ""
vercel_org_id: ${{ secrets.VERCEL_ORG_ID }}
vercel_project_id: ${{ secrets.VERCEL_PROJECT_ID_GUARDIAN_PROVER_HEALTH_CHECK_UI_HEKLA }}

deploy_guardian-ui_devnet_preview:
if: ${{ !github.ref_name == 'main' }}
uses: ./.github/workflows/guardian-ui-deploy.yml
with:
environment: "preview"
flags: ""
vercel_org_id: ${{ secrets.VERCEL_ORG_ID }}
vercel_project_id: ${{ secrets.VERCEL_PROJECT_ID_GUARDIAN_PROVER_HEALTH_CHECK_UI_INTERNAL }}

deploy_guardian-ui_hekla_production:
if: ${{ github.ref_name == 'main' && startsWith(github.ref, 'refs/tags/guardian-prover-health-check-ui-') }}
uses: ./.github/workflows/guardian-ui-deploy.yml
with:
environment: "production"
flags: "--prod"
vercel_org_id: ${{ secrets.VERCEL_ORG_ID }}
vercel_project_id: ${{ secrets.VERCEL_PROJECT_ID_GUARDIAN_PROVER_HEALTH_CHECK_UI_HEKLA }}
3 changes: 0 additions & 3 deletions packages/guardian-prover-health-check-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
"name": "guardian-prover-health-check-ui",
"version": "0.1.0",
"private": true,
"engines": {
"node": "^20.0.0"
},
"scripts": {
"dev": "vite dev",
"build": "vite build",
Expand Down
1 change: 1 addition & 0 deletions packages/guardian-prover-health-check-ui/src/app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const configuredNetworks = ['hekla', 'devnet']
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,12 @@
{$loading ? 'collapse-close' : ''}
bg-base-200"
>
<input type="checkbox" id={`guardian-${guardianProver.id}`} class="peer" bind:checked={flipped} />
<input
type="checkbox"
id={`guardian-${guardianProver.address}`}
class="peer"
bind:checked={flipped}
/>
<div class="collapse-title text-xl font-medium f-row">
<div class="f-row min-w-[150px] items-center gap-4">
{#if $loading}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

const openDetails = (guardianProver: Guardian) => {
$selectedGuardianProver = guardianProver;
goto(guardianProver.id.toString());
goto(guardianProver.address);
};

onMount(async () => {
Expand All @@ -39,7 +39,7 @@

<GuardianProverTableHeader />
<div class="space-y-[8px]">
{#each dataToDisplay as guardianProver (guardianProver.id)}
{#each dataToDisplay as guardianProver (guardianProver.address)}
<GuardianProverTableRow
{guardianProver}
on:click={() => openDetails(guardianProver)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@ import type {
UptimeResponse
} from '$lib/types';
import axios from 'axios';
import type { Address } from 'viem';

export async function fetchGuardianProverHealthChecksFromApi(
baseURL: string,
page: number,
size: number,
guardianProverId?: number
guardianProverAddress?: Address
): Promise<PageResponse<HealthCheck>> {
let url;
if (guardianProverId) {
url = `${baseURL}/${healthCheckRoute}/${guardianProverId}`;
if (guardianProverAddress) {
url = `${baseURL}/${healthCheckRoute}/${guardianProverAddress}`;
} else {
url = `${baseURL}/${healthCheckRoute}`;
}
Expand All @@ -39,9 +40,9 @@ export async function fetchGuardianProverHealthChecksFromApi(

export async function fetchLatestGuardianProverHealthCheckFromApi(
baseURL: string,
guardianProverId: number
guardianProverAddress: Address
): Promise<HealthCheck> {
const url = `${baseURL}/${livenessRoute}/${guardianProverId}`;
const url = `${baseURL}/${livenessRoute}/${guardianProverAddress}`;

const resp = await axios.get<HealthCheck>(url);

Expand All @@ -50,25 +51,25 @@ export async function fetchLatestGuardianProverHealthCheckFromApi(

export async function fetchUptimeFromApi(
baseURL: string,
guardianProverId: number
guardianProverAddress: Address
): Promise<number> {
const url = `${baseURL}/${uptimeRoute}/${guardianProverId}`;
const url = `${baseURL}/${uptimeRoute}/${guardianProverAddress}`;

const resp = await axios.get<UptimeResponse>(url);

return resp.data.uptime;
}

export async function fetchStartupDataFromApi(baseURL: string, guardianProverId: number) {
const url = `${baseURL}/${mostRecentStartupRoute}/${guardianProverId}`;
export async function fetchStartupDataFromApi(baseURL: string, guardianProverAddress: Address) {
const url = `${baseURL}/${mostRecentStartupRoute}/${guardianProverAddress}`;

const resp = await axios.get<StartupResponse>(url);

return resp.data;
}

export async function fetchNodeInfoFromApi(baseURL: string, guardianProverId: number) {
const url = `${baseURL}/${nodeInfoRoute}/${guardianProverId}`;
export async function fetchNodeInfoFromApi(baseURL: string, guardianProverAddress: Address) {
const url = `${baseURL}/${nodeInfoRoute}/${guardianProverAddress}`;

const resp = await axios.get<NodeInfoResponse>(url);

Expand Down
25 changes: 15 additions & 10 deletions packages/guardian-prover-health-check-ui/src/lib/dataFetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ async function initializeGuardians() {
const guardiansMap = await loadGuardians();
const rawGuardians: Guardian[] = Object.entries(guardiansMap).map(([address, name], index) => ({
name: name,
address: address,
address: address as Address,
id: index + 1, // add +1 as guardian contract numbers starts at 1
latestHealthCheck: null,
alive: GuardianProverStatus.UNKNOWN,
Expand All @@ -108,25 +108,28 @@ async function fetchGuardians() {
totalGuardianProvers.set(existingGuardians?.length);

const guardianFetchPromises = existingGuardians.map(async (newGuardian) => {
const guardian = existingGuardians.find((g) => g.id === newGuardian.id) || {
const guardian = existingGuardians.find((g) => g.address === newGuardian.address) || {
...newGuardian,
latestHealthCheck: null,
uptime: 0,
balance: '0',
alive: GuardianProverStatus.UNKNOWN
};
console.log('fetching guardian info for', guardian.address, guardian.id);

guardian.name = await getPseudonym(guardian.address);

console.log("getting balance for", guardian.name, guardian.id, guardian.address);

const [status, uptime, balance] = await Promise.all([
fetchLatestGuardianProverHealthCheckFromApi(
import.meta.env.VITE_GUARDIAN_PROVER_API_URL,
guardian.id
guardian.address
),
fetchUptimeFromApi(import.meta.env.VITE_GUARDIAN_PROVER_API_URL, guardian.id),
fetchUptimeFromApi(import.meta.env.VITE_GUARDIAN_PROVER_API_URL, guardian.address),
publicClient.getBalance({ address: guardian.address as Address })

]);

guardian.balance = formatEther(balance);
console.log('balance', guardian.name, guardian.balance);

guardian.latestHealthCheck = status;
guardian.uptime = Math.min(uptime, 100);
Expand All @@ -137,6 +140,8 @@ async function fetchGuardians() {
const updatedGuardians = await Promise.all(guardianFetchPromises);
guardianProvers.set(updatedGuardians);
lastGuardianFetchTimestamp.set(Date.now());
console.log('updatedGuardians', updatedGuardians);

}

async function fetchSignedBlockStats() {
Expand Down Expand Up @@ -183,14 +188,15 @@ async function fetchStats(): Promise<void> {
const guardians = get(guardianProvers);

const updatedGuardiansPromises = guardians.map(async (guardian) => {
console.log('fetching stats for', guardian.address)
const startupDataFetch = fetchStartupDataFromApi(
import.meta.env.VITE_GUARDIAN_PROVER_API_URL,
guardian.id
guardian.address
);

const nodeInfoFetch = fetchNodeInfoFromApi(
import.meta.env.VITE_GUARDIAN_PROVER_API_URL,
guardian.id
guardian.address
);

const [startupData, nodeInfo] = await Promise.all([startupDataFetch, nodeInfoFetch]);
Expand All @@ -204,7 +210,6 @@ async function fetchStats(): Promise<void> {
revision: startupData.revision
};

console.log('versions', versions);

const blockInfo: BlockInfo = {
latestL1BlockNumber: nodeInfo.latestL1BlockNumber,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { configuredNetworks } from "$config";

export async function loadGuardians(): Promise<{ [address: string]: string }> {
const network = import.meta.env.VITE_NETWORK_CONFIG;
if (!network)
throw new Error('Network not configured. Please set VITE_NETWORK_CONFIG in .env file.');
const path = `/config/${network}/guardians.json`;
const response = await fetch(path);
if (!response.ok) {
throw new Error(`Failed to load ${path}: ${response.statusText}`);
}
return response.json();
const network = import.meta.env.VITE_NETWORK_CONFIG;
if (!network) {
throw new Error('Network not configured. Please set VITE_NETWORK_CONFIG in .env file. Currently supported networks: ' + configuredNetworks.join(', '));
}
const path = `/config/${network}/guardians.json`;
const response = await fetch(path);
if (!response.ok) {
throw new Error(`Failed to load ${path}: ${response.statusText}`);
}
return response.json();
}

4 changes: 3 additions & 1 deletion packages/guardian-prover-health-check-ui/src/lib/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { Address } from "viem";

export type SignedBlock = {
blockHash: string;
signature: string;
Expand Down Expand Up @@ -63,7 +65,7 @@ export type PageResponse<T> = {

export type Guardian = {
name: string;
address: string;
address: Address;
id: number;
latestHealthCheck: HealthCheck;
alive: GuardianProverStatus;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@

$: if (get(guardianProvers)) {
selected = $guardianProvers.find(
(guardianProver) => Number(guardianProver.id) === parseInt(data.slug)
(guardianProver) => Number(guardianProver.address) === parseInt(data.slug)
);
} else {
refreshData().then(() => {
get(guardianProvers).map((prover) => {
if (Number(prover.id) === parseInt(data.slug)) {
if (prover.address === data.slug) {
selected = prover;
selectedGuardianProver.set(selected);
}
Expand Down
Loading