diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..6033a68 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,75 @@ +name: CI + +on: + pull_request: + push: + branches: [main] + workflow_dispatch: + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v4 + with: + path: ~/.cache/biome + key: biome-${{ runner.os }}-${{ hashFiles('biome.json') }} + restore-keys: biome-${{ runner.os }}- + - uses: biomejs/setup-biome@v2 + with: + version: 2.1.2 + - run: biome ci --linter-enabled=true --formatter-enabled=true + + typecheck: + runs-on: ubuntu-latest + defaults: + run: + working-directory: frontend + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 10 + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + cache-dependency-path: frontend/pnpm-lock.yaml + - run: pnpm install --frozen-lockfile + - run: pnpm typecheck + + build: + runs-on: ubuntu-latest + defaults: + run: + working-directory: frontend + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 10 + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + cache-dependency-path: frontend/pnpm-lock.yaml + - run: pnpm install --frozen-lockfile + - run: pnpm build + + rust: + runs-on: ubuntu-latest + # Match the backend Dockerfile's build image so bindgen sees a libclang + # new enough for the upstream C23 (`constexpr`) headers from monad-bft. + container: rust:1.91-slim + steps: + - name: Install build dependencies + run: | + apt-get update + apt-get install -y git curl gcc g++ cmake pkg-config libssl-dev libclang-dev libzstd-dev libhugetlbfs-dev + - uses: actions/checkout@v4 + - run: rustup component add rustfmt clippy + - uses: Swatinem/rust-cache@v2 + - run: cargo fmt --all --check + - run: cargo clippy --all-targets --all-features -- -D warnings + - run: cargo build --all-targets diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index a45e8ad..0000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Lint - -on: - pull_request: - -jobs: - lint: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Cache Biome - uses: actions/cache@v4 - with: - path: ~/.cache/biome - key: biome-${{ runner.os }}-${{ hashFiles('biome.json') }} - restore-keys: | - biome-${{ runner.os }}- - - name: Setup Biome - uses: biomejs/setup-biome@v2 - with: - version: 2.1.2 - - name: Run Biome - run: biome ci --linter-enabled=true --formatter-enabled=true diff --git a/frontend/components/network-activity-tracker/tps-chart.tsx b/frontend/components/network-activity-tracker/tps-chart.tsx index 1394b5a..f86efd4 100644 --- a/frontend/components/network-activity-tracker/tps-chart.tsx +++ b/frontend/components/network-activity-tracker/tps-chart.tsx @@ -1,6 +1,7 @@ 'use client' import Image from 'next/image' +import { useEffect, useState } from 'react' import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from 'recharts' import { type ChartConfig, @@ -21,11 +22,28 @@ const chartConfig = { }, } satisfies ChartConfig +/** Visible time window, matching the TPS history kept by useTps */ +const WINDOW_MS = 5 * 60 * 1000 + export function TpsChart() { const { currentTps, peakTps, history } = useTps() const totalTransactions = useTotalTransactions() const hasData = history.length > 0 + // Advance a "now" clock every animation frame so the time-windowed X axis + // domain slides continuously. New points enter smoothly from the right edge + // instead of popping in a discrete category slot. + const [now, setNow] = useState(() => Date.now()) + useEffect(() => { + let frame: number + const tick = () => { + setNow(Date.now()) + frame = requestAnimationFrame(tick) + } + frame = requestAnimationFrame(tick) + return () => cancelAnimationFrame(frame) + }, []) + return (
@@ -77,6 +95,10 @@ export function TpsChart() { = 10'} - cpu: [arm64] - os: [darwin] '@next/swc-darwin-x64@16.2.6': resolution: {integrity: sha512-v/YLBHIY132Ced3puBJ7YJKw1lqsCrgcNo2aRJlCEyQrrCeRJlvGlnmxhPxNQI3KE3N1DN5r9TPNPvka3nq5RQ==} - '@next/swc-darwin-x64@16.2.6': - resolution: {integrity: sha512-v/YLBHIY132Ced3puBJ7YJKw1lqsCrgcNo2aRJlCEyQrrCeRJlvGlnmxhPxNQI3KE3N1DN5r9TPNPvka3nq5RQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] '@next/swc-linux-arm64-gnu@16.2.6': resolution: {integrity: sha512-RPOvqlYBbcQjkz9VQQDZ2T2bARIjXZV1KFlt+V2Mr6SW/e4I9fcKsaA0hdyf2FHoTlsV2xnBd5Y912rP/1Ce6w==} - '@next/swc-linux-arm64-gnu@16.2.6': - resolution: {integrity: sha512-RPOvqlYBbcQjkz9VQQDZ2T2bARIjXZV1KFlt+V2Mr6SW/e4I9fcKsaA0hdyf2FHoTlsV2xnBd5Y912rP/1Ce6w==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - libc: [glibc] - libc: [glibc] '@next/swc-linux-arm64-musl@16.2.6': resolution: {integrity: sha512-URUTu1+dMkxJsPFgm+OeEvq9wf5sujw0EvgYy80TDGHTSLTnIHeqb0Eu8A3sC95IRgjejQL+kC4mw+4yPxiAXA==} - '@next/swc-linux-arm64-musl@16.2.6': - resolution: {integrity: sha512-URUTu1+dMkxJsPFgm+OeEvq9wf5sujw0EvgYy80TDGHTSLTnIHeqb0Eu8A3sC95IRgjejQL+kC4mw+4yPxiAXA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - libc: [musl] - libc: [musl] '@next/swc-linux-x64-gnu@16.2.6': resolution: {integrity: sha512-DOj182mPV8G3UkrayLoREM5YEYI+Dk5wv7Ox9xl1fFibAELEsFD0lDPfHIeILlutMMfdyhlzYPELG3peuKaurw==} - '@next/swc-linux-x64-gnu@16.2.6': - resolution: {integrity: sha512-DOj182mPV8G3UkrayLoREM5YEYI+Dk5wv7Ox9xl1fFibAELEsFD0lDPfHIeILlutMMfdyhlzYPELG3peuKaurw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - libc: [glibc] - libc: [glibc] '@next/swc-linux-x64-musl@16.2.6': resolution: {integrity: sha512-HKQ5SP/V/ub73UvF7n/zeJlxk2kLmtL7Wzrg4WfmkjmNos5onJ2tKu7yZOPdL18A6Svfn3max29ym+ry7NkK4g==} - '@next/swc-linux-x64-musl@16.2.6': - resolution: {integrity: sha512-HKQ5SP/V/ub73UvF7n/zeJlxk2kLmtL7Wzrg4WfmkjmNos5onJ2tKu7yZOPdL18A6Svfn3max29ym+ry7NkK4g==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - libc: [musl] - libc: [musl] '@next/swc-win32-arm64-msvc@16.2.6': resolution: {integrity: sha512-LZXpTlPyS5v7HhSmnvsLGP3iIYgYOBnc8r8ArlT55sGHV89bR2HlDdBjWQ+PY6SJMmk8TuVGFuxalnP3k/0Dwg==} - '@next/swc-win32-arm64-msvc@16.2.6': - resolution: {integrity: sha512-LZXpTlPyS5v7HhSmnvsLGP3iIYgYOBnc8r8ArlT55sGHV89bR2HlDdBjWQ+PY6SJMmk8TuVGFuxalnP3k/0Dwg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] '@next/swc-win32-x64-msvc@16.2.6': resolution: {integrity: sha512-F0+4i0h9J6C4eE3EAPWsoCk7UW/dbzOjyzxY0qnDUOYFu6FFmdZ6l97/XdV3/Nz3VYyO7UWjyEJUXkGqcoXfMA==} - '@next/swc-win32-x64-msvc@16.2.6': - resolution: {integrity: sha512-F0+4i0h9J6C4eE3EAPWsoCk7UW/dbzOjyzxY0qnDUOYFu6FFmdZ6l97/XdV3/Nz3VYyO7UWjyEJUXkGqcoXfMA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] '@noble/ciphers@1.3.0': resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} @@ -878,7 +812,6 @@ packages: cpu: [arm64] os: [linux] libc: [glibc] - libc: [glibc] '@tailwindcss/oxide-linux-arm64-musl@4.1.17': resolution: {integrity: sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg==} @@ -886,7 +819,6 @@ packages: cpu: [arm64] os: [linux] libc: [musl] - libc: [musl] '@tailwindcss/oxide-linux-x64-gnu@4.1.17': resolution: {integrity: sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ==} @@ -894,7 +826,6 @@ packages: cpu: [x64] os: [linux] libc: [glibc] - libc: [glibc] '@tailwindcss/oxide-linux-x64-musl@4.1.17': resolution: {integrity: sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ==} @@ -902,7 +833,6 @@ packages: cpu: [x64] os: [linux] libc: [musl] - libc: [musl] '@tailwindcss/oxide-wasm32-wasi@4.1.17': resolution: {integrity: sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg==} @@ -1084,56 +1014,48 @@ packages: cpu: [arm64] os: [linux] libc: [glibc] - libc: [glibc] '@unrs/resolver-binding-linux-arm64-musl@1.11.1': resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} cpu: [arm64] os: [linux] libc: [musl] - libc: [musl] '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} cpu: [ppc64] os: [linux] libc: [glibc] - libc: [glibc] '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} cpu: [riscv64] os: [linux] libc: [glibc] - libc: [glibc] '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} cpu: [riscv64] os: [linux] libc: [musl] - libc: [musl] '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} cpu: [s390x] os: [linux] libc: [glibc] - libc: [glibc] '@unrs/resolver-binding-linux-x64-gnu@1.11.1': resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} cpu: [x64] os: [linux] libc: [glibc] - libc: [glibc] '@unrs/resolver-binding-linux-x64-musl@1.11.1': resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} cpu: [x64] os: [linux] libc: [musl] - libc: [musl] '@unrs/resolver-binding-wasm32-wasi@1.11.1': resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} @@ -1275,10 +1197,6 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - baseline-browser-mapping@2.10.24: - resolution: {integrity: sha512-I2NkZOOrj2XuguvWCK6OVh9GavsNjZjK908Rq3mIBK25+GD8vPX5w2WdxVqnQ7xx3SrZJiCiZFu+/Oz50oSYSA==} - engines: {node: '>=6.0.0'} - hasBin: true baseline-browser-mapping@2.8.32: resolution: {integrity: sha512-OPz5aBThlyLFgxyhdwf/s2+8ab3OvT7AdTNvKHBwpXomIYeXqpUUuT8LrdtxZSsWJ4R4CU1un4XGh5Ez3nlTpw==} @@ -2024,7 +1942,6 @@ packages: cpu: [arm64] os: [linux] libc: [glibc] - libc: [glibc] lightningcss-linux-arm64-musl@1.30.2: resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} @@ -2032,7 +1949,6 @@ packages: cpu: [arm64] os: [linux] libc: [musl] - libc: [musl] lightningcss-linux-x64-gnu@1.30.2: resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} @@ -2040,7 +1956,6 @@ packages: cpu: [x64] os: [linux] libc: [glibc] - libc: [glibc] lightningcss-linux-x64-musl@1.30.2: resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} @@ -2048,7 +1963,6 @@ packages: cpu: [x64] os: [linux] libc: [musl] - libc: [musl] lightningcss-win32-arm64-msvc@1.30.2: resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} @@ -2137,26 +2051,6 @@ packages: next@16.2.6: resolution: {integrity: sha512-qOVgKJg1+At15NpeUP+eJgCHvTCgXsogweq87Ri/Ix7PkqQHg4sdaXmSFqKlgaIXE4kW0g25LE68W87UANlHtw==} - next@16.2.6: - resolution: {integrity: sha512-qOVgKJg1+At15NpeUP+eJgCHvTCgXsogweq87Ri/Ix7PkqQHg4sdaXmSFqKlgaIXE4kW0g25LE68W87UANlHtw==} - engines: {node: '>=20.9.0'} - hasBin: true - peerDependencies: - '@opentelemetry/api': ^1.1.0 - '@playwright/test': ^1.51.1 - babel-plugin-react-compiler: '*' - react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - sass: ^1.3.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - '@playwright/test': - optional: true - babel-plugin-react-compiler: - optional: true - sass: - optional: true node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} @@ -2946,41 +2840,32 @@ snapshots: optional: true '@next/env@16.2.6': {} - '@next/env@16.2.6': {} '@next/eslint-plugin-next@16.0.6': dependencies: fast-glob: 3.3.1 - '@next/swc-darwin-arm64@16.2.6': '@next/swc-darwin-arm64@16.2.6': optional: true - '@next/swc-darwin-x64@16.2.6': '@next/swc-darwin-x64@16.2.6': optional: true - '@next/swc-linux-arm64-gnu@16.2.6': '@next/swc-linux-arm64-gnu@16.2.6': optional: true - '@next/swc-linux-arm64-musl@16.2.6': '@next/swc-linux-arm64-musl@16.2.6': optional: true - '@next/swc-linux-x64-gnu@16.2.6': '@next/swc-linux-x64-gnu@16.2.6': optional: true - '@next/swc-linux-x64-musl@16.2.6': '@next/swc-linux-x64-musl@16.2.6': optional: true - '@next/swc-win32-arm64-msvc@16.2.6': '@next/swc-win32-arm64-msvc@16.2.6': optional: true - '@next/swc-win32-x64-msvc@16.2.6': '@next/swc-win32-x64-msvc@16.2.6': optional: true @@ -3661,7 +3546,6 @@ snapshots: baseline-browser-mapping@2.10.24: {} - baseline-browser-mapping@2.10.24: {} baseline-browser-mapping@2.8.32: {} @@ -4613,25 +4497,15 @@ snapshots: next@16.2.6(@babel/core@7.28.5)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: - '@next/env': 16.2.6 '@next/env': 16.2.6 '@swc/helpers': 0.5.15 baseline-browser-mapping: 2.10.24 - baseline-browser-mapping: 2.10.24 caniuse-lite: 1.0.30001759 postcss: 8.4.31 react: 19.2.6 react-dom: 19.2.6(react@19.2.6) styled-jsx: 5.1.6(@babel/core@7.28.5)(react@19.2.6) optionalDependencies: - '@next/swc-darwin-arm64': 16.2.6 - '@next/swc-darwin-x64': 16.2.6 - '@next/swc-linux-arm64-gnu': 16.2.6 - '@next/swc-linux-arm64-musl': 16.2.6 - '@next/swc-linux-x64-gnu': 16.2.6 - '@next/swc-linux-x64-musl': 16.2.6 - '@next/swc-win32-arm64-msvc': 16.2.6 - '@next/swc-win32-x64-msvc': 16.2.6 '@next/swc-darwin-arm64': 16.2.6 '@next/swc-darwin-x64': 16.2.6 '@next/swc-linux-arm64-gnu': 16.2.6 diff --git a/frontend/pnpm-workspace.yaml b/frontend/pnpm-workspace.yaml index 56dbf93..b0c9078 100644 --- a/frontend/pnpm-workspace.yaml +++ b/frontend/pnpm-workspace.yaml @@ -1,3 +1,7 @@ +allowBuilds: + sharp: true + unrs-resolver: true + minimumReleaseAge: 10080 minimumReleaseAgeExclude: