Skip to content

Client diversity piechart update #15251

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

Open
wants to merge 38 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
4bb1a87
Created React PieChart component
LifeofDan-EL Apr 7, 2025
11827ed
Merge branch 'ethereum:dev' into client-diversity
LifeofDan-EL Apr 7, 2025
1553d14
Testing to see if the chart works, before removing and updating the d…
LifeofDan-EL Apr 7, 2025
fb4c103
Merge branch 'client-diversity' of https://github.com/LifeofDan-EL/et…
LifeofDan-EL Apr 7, 2025
84292b1
Fix lint errors
LifeofDan-EL Apr 7, 2025
480a1e1
Fix lint errors
LifeofDan-EL Apr 7, 2025
45761c8
Changed import way for the PieChart
LifeofDan-EL Apr 8, 2025
0c8ac7c
Revert yarn.lock and .env.example to match upstream/dev
LifeofDan-EL Apr 8, 2025
99615fa
Merge branch 'ethereum:dev' into client-diversity
LifeofDan-EL Apr 8, 2025
202418c
Improved PieChart
LifeofDan-EL Apr 8, 2025
f8d0a70
Fixing import issue
LifeofDan-EL Apr 8, 2025
171eefa
Slight improvement on the PieChart
LifeofDan-EL Apr 8, 2025
f689074
Merge branch 'ethereum:dev' into client-diversity
LifeofDan-EL Apr 11, 2025
1ce8c30
Delete .yarnrc.yml
LifeofDan-EL Apr 11, 2025
73091d9
Delete .yarn directory
LifeofDan-EL Apr 11, 2025
1f0116e
Updated styling to use color palette
LifeofDan-EL Apr 11, 2025
cbe8b2e
Changed to accent colors
LifeofDan-EL Apr 12, 2025
7cfd42c
Remove sticking out label, then attaching the percentage value to the…
LifeofDan-EL Apr 12, 2025
352ed27
Trying to fix payload issue
LifeofDan-EL Apr 12, 2025
c57d2c2
Added ResponsiveContainer to PieChart
LifeofDan-EL Apr 16, 2025
8c7ad14
Working on responsiveness
LifeofDan-EL Apr 16, 2025
c112033
Working on responsiveness
LifeofDan-EL Apr 16, 2025
a6b359b
Working on responsiveness
LifeofDan-EL Apr 16, 2025
57ec8f0
Working on responsiveness
LifeofDan-EL Apr 16, 2025
8ffc3da
Working on responsiveness
LifeofDan-EL Apr 16, 2025
7e6926d
Working on responsiveness
LifeofDan-EL Apr 16, 2025
ce7e234
Working on responsiveness
LifeofDan-EL Apr 16, 2025
d8b85c6
Still working on it
LifeofDan-EL Apr 16, 2025
64c2c57
Working on responsiveness
LifeofDan-EL Apr 16, 2025
d2b2910
Working on responsiveness
LifeofDan-EL Apr 16, 2025
003b4d0
Testing for responsiveness
LifeofDan-EL Apr 16, 2025
b697fe3
Updated content
LifeofDan-EL Apr 18, 2025
e0d3b85
Merge branch 'ethereum:dev' into client-diversity
LifeofDan-EL Apr 18, 2025
9724d25
Formatted footnote better
LifeofDan-EL Apr 18, 2025
dfdfc39
Merge branch 'client-diversity' of https://github.com/LifeofDan-EL/et…
LifeofDan-EL Apr 18, 2025
8273f9f
Working on footnote issue
LifeofDan-EL Apr 18, 2025
4975d85
Working on footnote
LifeofDan-EL Apr 19, 2025
a7545d6
Fixed typo
LifeofDan-EL Apr 19, 2025
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
45 changes: 0 additions & 45 deletions .env.example

This file was deleted.

Binary file added .yarn/install-state.gz
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is not needed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved.

Binary file not shown.
1 change: 1 addition & 0 deletions .yarnrc.yml
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is not needed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodeLinker: node-modules
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,27 @@ lang: en
sidebarDepth: 2
---

import { PieChart } from "@/components/PieChart"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import is redundant now that we are injecting the component in the MdComponents file.

Also, next-mdx-remote (the mdx compiler that we use) doesn't support imports or exports, so we need to do something different to pass the below data to the component.

I think the easiest would be to pass the data array inline like this:

<PieChart data={[ { name: "Geth", value: 43 }, ... ]} title="Execution Clients" />

To clarify more, you can't use variables like executionData without exporting them in mdx. But since imports/exports are not supported, we can't use them either.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @pettinarip for the clarification, it was an oversight pushing the yarn file. Thanks again.


const executionData = [
{ name: "Geth", value: 43 },
{ name: "Nethermind", value: 36 },
{ name: "Besu", value: 16 },
{ name: "Erigon", value: 3 },
{ name: "Reth", value: 2 },
{ name: "Other", value: 0 },
]

const consensusData = [
{ name: "Lighthouse", value: 32.59 },
{ name: "Prysm", value: 31.31 },
{ name: "Teku", value: 27.06 },
{ name: "Nimbus", value: 5.63 },
{ name: "Grandine", value: 2.0 },
{ name: "Lodestar", value: 1.42 },
{ name: "Others", value: 0.15 },
]

The behavior of an Ethereum node is controlled by the client software it runs. There are several production-level Ethereum clients, each one developed and maintained in different languages by separate teams. The clients are built to a common spec that ensures the clients seamlessly communicate with each other and have the same functionality and provide an equivalent user experience. However, at the moment the distribution of clients across nodes is not equal enough to realize this network fortification to its full potential. Ideally, users divide roughly equally across the various clients to bring as much client diversity as possible to the network.

## Prerequisites {#prerequisites}
Expand Down Expand Up @@ -41,7 +62,19 @@ There is also a human cost to having majority clients. It puts excess strain and

## Current client diversity {#current-client-diversity}



<div style={{ display: 'flex', gap: '1rem' }}>
<div style={{ flex: 1 }}>
<PieChart data={executionData} title="Execution Clients" />
</div>
<div style={{ flex: 1 }}>
<PieChart data={consensusData} title="Consensus Clients" />
</div>
</div>

![Pie chart showing client diversity](./client-diversity.png)

_Diagram data from [ethernodes.org](https://ethernodes.org) and [clientdiversity.org](https://clientdiversity.org/)_

The two pie charts above show snapshots of the current client diversity for the execution and consensus layers (at time of writing in January 2022). The execution layer is overwhelmingly dominated by [Geth](https://geth.ethereum.org/), with [Open Ethereum](https://openethereum.github.io/) a distant second, [Erigon](https://github.com/ledgerwatch/erigon) third and [Nethermind](https://nethermind.io/) fourth, with other clients comprising less than 1 % of the network. The most commonly used client on the consensus layer - [Prysm](https://prysmaticlabs.com/#projects) - is not as dominant as Geth but still represents over 60% of the network. [Lighthouse](https://lighthouse.sigmaprime.io/) and [Teku](https://consensys.net/knowledge-base/ethereum-2/teku/) make up ~20% and ~14% respectively, and other clients are rarely used.
Expand Down
2 changes: 2 additions & 0 deletions src/components/MdComponents/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { ChildOnlyProp } from "@/lib/types"

import Contributors from "@/components/Contributors"
import MarkdownImage from "@/components/MarkdownImage"
import { PieChart } from "@/components/PieChart"
import TooltipLink from "@/components/TooltipLink"
import YouTube from "@/components/YouTube"

Expand Down Expand Up @@ -166,6 +167,7 @@ export const reactComponents = {
GlossaryTooltip,
InfoBanner,
Page,
PieChart,
QuizWidget: StandaloneQuizWidget,
IssuesList,
Tag,
Expand Down
114 changes: 114 additions & 0 deletions src/components/PieChart/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
"use client"

import { FaArrowTrendUp } from "react-icons/fa6"
import { Pie, PieChart as RechartsPieChart } from "recharts"

import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card"
import {
ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart"

type PieChartDataPoint = { name: string; value: number }

/**
* PieChartProps defines the properties for the PieChart component.
*
* @property {PieChartDataPoint[]} data - The data to be displayed in the chart. Each object should have a `name` and `value` property.
* @property {string} [title] - The title of the chart.
* @property {string} [description] - The description of the chart.
* @property {string} [footerText] - The footer text of the chart.
* @property {string} [footerSubText] - The footer subtext of the chart.
*/

type PieChartProps = {
data: PieChartDataPoint[]
title?: string
description?: string
footerText?: string
footerSubText?: string
}

const defaultChartConfig = {
value: {
label: "Value",
color: "hsl(var(--accent-a))",
},
} satisfies ChartConfig

/**
* PieChart component renders a pie chart with the provided data and optional title, description, footer text, and footer subtext.
*
* @param {PieChartProps} props - The properties for the PieChart component.
* @returns {JSX.Element} The rendered PieChart component.
*/

export function PieChart({
data,
title,
description,
footerText,
footerSubText,
}: PieChartProps) {
return (
<Card>
<CardHeader>
{title && <CardTitle>{title}</CardTitle>}
{description && <CardDescription>{description}</CardDescription>}
</CardHeader>
<CardContent>
<ChartContainer config={defaultChartConfig}>
<RechartsPieChart
accessibilityLayer
data={data}
margin={{
left: 12,
right: 12,
top: 12,
bottom: 12,
}}
>
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
<Pie
data={data}
dataKey="value"
nameKey="name"
cx="50%"
cy="50%"
outerRadius={80}
fill="hsl(var(--accent-a))"
label
/>
</RechartsPieChart>
</ChartContainer>
</CardContent>
{(footerText || footerSubText) && (
<CardFooter>
<div className="flex w-full items-start gap-2 text-sm">
<div className="grid gap-2">
{footerText && (
<div className="flex items-center gap-2 font-medium leading-none">
{footerText} <FaArrowTrendUp className="h-4 w-4" />
</div>
)}
{footerSubText && (
<div className="text-muted-foreground flex items-center gap-2 leading-none">
{footerSubText}
</div>
)}
</div>
</div>
</CardFooter>
)}
</Card>
)
}
Loading
Loading