Skip to content

Commit

Permalink
Merge pull request #266 from dappnode/dappnodedev/add-holesky
Browse files Browse the repository at this point in the history
Add Holesky network
  • Loading branch information
dappnodedev authored Nov 6, 2023
2 parents a12197b + 6cae5f7 commit 82256cf
Show file tree
Hide file tree
Showing 15 changed files with 185 additions and 14 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Staking Brain is a critical logical component for Staking in DAppNode. It provides a user interface and a Launchpad API that allow manual and automatic keystore management. Designed to support not only solo stakers, but also DVT/LSD technologies, Staking Brain streamlines the staking process for all users.

Within the Dappnode environment, Staking Brain is incorporated into the Web3Signer packages (gnosis, mainnet, prater and lukso). It ensures that user configurations for validators are reliably maintained. Please note that Staking Brain does not store keystores itself, but ensures their storage in the web3signer. It also maintains consistency between the validator service and web3signer service, as the validator must recognize all the pubkeys of validators whose keystores have been imported into the signer.
Within the Dappnode environment, Staking Brain is incorporated into the Web3Signer packages (gnosis, mainnet, prater, lukso and holesky). It ensures that user configurations for validators are reliably maintained. Please note that Staking Brain does not store keystores itself, but ensures their storage in the web3signer. It also maintains consistency between the validator service and web3signer service, as the validator must recognize all the pubkeys of validators whose keystores have been imported into the signer.

Each Web3Signer package includes four services:

Expand Down
98 changes: 98 additions & 0 deletions packages/brain/src/modules/envs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,22 @@ import {
executionClientsPrater,
executionClientsGnosis,
executionClientsLukso,
executionClientsHolesky,
ExecutionClientMainnet,
consensusClientsMainnet,
ConsensusClientMainnet,
ExecutionClientGnosis,
ExecutionClientLukso,
ExecutionClientHolesky,
ExecutionClientPrater,
consensusClientsGnosis,
consensusClientsLukso,
consensusClientsHolesky,
consensusClientsPrater,
ConsensusClientPrater,
ConsensusClientGnosis,
ConsensusClientLukso,
ConsensusClientHolesky,
ExecutionClient,
ConsensusClient,
} from "@stakingbrain/common";
Expand Down Expand Up @@ -342,6 +346,78 @@ export function loadStakerConfig(): {
: undefined,
tlsCert,
};
} else if (network === "holesky") {
const { executionClient, consensusClient, defaultFeeRecipient } =
loadEnvs("holesky");
switch (executionClient) {
case "holesky-nethermind.dnp.dappnode.eth":
executionClientUrl = `http://holesky-nethermind.dappnode:8545`;
break;
case "holesky-besu.dnp.dappnode.eth":
executionClientUrl = `http://holesky-besu.dappnode:8545`;
break;
case "holesky-erigon.dnp.dappnode.eth":
executionClientUrl = `http://holesky-erigon.dappnode:8545`;
case "holesky-geth.dnp.dappnode.eth":
executionClientUrl = `http://holesky-geth.dappnode:8545`;
break;
default:
throw Error(
`Unknown execution client for network ${network}: ${executionClient}`
);
}
switch (consensusClient) {
case "prysm-holesky.dnp.dappnode.eth":
token = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.MxwOozSH-TLbW_XKepjyYDHm2IT8Ki0tD3AHuajfNMg`;
beaconchainUrl = `http://beacon-chain.prysm-holesky.dappnode:3500`;
validatorUrl = `http://validator.prysm-holesky.dappnode:3500`;
break;
case "teku-holesky.dnp.dappnode.eth":
token = `cd4892ca35d2f5d3e2301a65fc7aa660`;
beaconchainUrl = `http://beacon-chain.teku-holesky.dappnode:3500`;
validatorUrl = `https://validator.teku-holesky.dappnode:3500`;
tlsCert = fs.readFileSync(
path.join(certDir, "holesky", "teku_client_keystore.p12")
);
break;
case "lighthouse-holesky.dnp.dappnode.eth":
token = `api-token-0x0200e6ce18e26fd38caca7ae1bfb9e2bba7efb20ed2746ad17f2f6dda44603152d`;
beaconchainUrl = `http://beacon-chain.lighthouse-holesky.dappnode:3500`;
validatorUrl = `http://validator.lighthouse-holesky.dappnode:3500`;
break;
case "lodestar-holesky.dnp.dappnode.eth":
token = `api-token-0x7fd16fff6453982a5d8bf14617e7823b68cd18ade59985befe64e0a659300e7d`;
beaconchainUrl = `http://beacon-chain.lodestar-holesky.dappnode:3500`;
validatorUrl = `http://validator.lodestar-holesky.dappnode:3500`;
break;
case "nimbus-holesky.dnp.dappnode.eth":
token = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.MxwOozSH-TLbW_XKepjyYDHm2IT8Ki0tD3AHuajfNMg`;
beaconchainUrl = `http://beacon-validator.nimbus-holesky.dappnode:4500`;
validatorUrl = `http://beacon-validator.nimbus-holesky.dappnode:3500`;
break;
default:
throw Error(
`Unknown consensus client for network ${network}: ${consensusClient}`
);
}

return {
network,
executionClient,
consensusClient,
executionClientUrl,
validatorUrl,
beaconchainUrl,
beaconchaUrl: `https://holesky.beaconcha.in`,
signerUrl: `http://web3signer.web3signer-holesky.dappnode:9000`,
token,
host: `web3signer.web3signer-holesky.dappnode`,
defaultFeeRecipient:
defaultFeeRecipient && isValidEcdsaPubkey(defaultFeeRecipient)
? defaultFeeRecipient
: undefined,
tlsCert,
};
} else {
throw Error(`Unknown network ${network}`);
}
Expand Down Expand Up @@ -453,6 +529,28 @@ function loadEnvs<T extends Network>(
)}`
);
break;
case "holesky":
if (
!executionClientsHolesky.includes(
executionClient as ExecutionClientHolesky
)
)
errors.push(
`Execution client is not valid for network ${network}: ${executionClient}. Valid execution clients for ${network}: ${executionClientsHolesky.join(
", "
)}`
);
if (
!consensusClientsHolesky.includes(
consensusClient as ConsensusClientHolesky
)
)
errors.push(
`Consensus client is not valid for network ${network}: ${consensusClient}. Valid consensus clients for ${network}: ${consensusClientsHolesky.join(
", "
)}`
);
break;
default:
errors.push(
`NETWORK environment variable is not valid: ${network}. Valid NETWORK values: ${networks.join(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { BeaconchaApi } from "../../../../src/modules/apiClients/beaconcha/index

describe.skip("Test for fetching validator indexes in every available network", () => {
it("should return data corresponding to every validator PK", async () => {
const networks = ["mainnet", "prater", "gnosis", "lukso"];
const networks = ["mainnet", "prater", "gnosis", "lukso", "holesky"];

for (const network of networks) {
console.log("NETWORK: ", network);
Expand Down Expand Up @@ -74,6 +74,16 @@ const networkTestMap = new Map<
indexes: [24693, 4272],
},
],
[
"holesky",
{
pubkeys: [
"0x800000b3884235f70b06fec68c19642fc9e81e34fbe7f1c0ae156b8b45860dfe5ac71037ae561c2a759ba83401488e18",
"0x800009f644592de8d2de0da0caca00f26fd6fb3d7f99f57101bbbfb45d4b166f8dbe5fd82b3611e6e90fe323de955bd2"
],
indexes: [886680, 68945],
}
],
]);

// TODO: move below to common
Expand Down Expand Up @@ -111,4 +121,12 @@ const beaconchaApiParamsMap = new Map<string, ApiParams>([
apiPath: "/api/v1/",
},
],
[
"holesky",
{
baseUrl: "https://holesky.beaconcha.in",
host: "brain.web3signer-holesky.dappnode",
apiPath: "/api/v1/",
},
],
]);
Binary file not shown.
1 change: 1 addition & 0 deletions packages/brain/tls/holesky/teku_keystore_password.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dappnode
30 changes: 29 additions & 1 deletion packages/common/src/types/network/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const networks = ["mainnet", "gnosis", "prater", "lukso"] as const;
export const networks = ["mainnet", "gnosis", "prater", "lukso", "holesky"] as const;

export type Network = (typeof networks)[number];

Expand All @@ -21,6 +21,8 @@ export type ExecutionClient<T extends Network> = T extends "mainnet"
? ExecutionClientPrater
: T extends "lukso"
? ExecutionClientLukso
: T extends "holesky"
? ExecutionClientHolesky
: never;

export type ConsensusClient<T extends Network> = T extends "mainnet"
Expand All @@ -31,6 +33,8 @@ export type ConsensusClient<T extends Network> = T extends "mainnet"
? ConsensusClientPrater
: T extends "lukso"
? ConsensusClientLukso
: T extends "holesky"
? ConsensusClientHolesky
: never;

export type Signer<T extends Network> = T extends "mainnet"
Expand All @@ -41,6 +45,8 @@ export type Signer<T extends Network> = T extends "mainnet"
? SignerPrater
: T extends "lukso"
? SignerLukso
: T extends "holesky"
? SignerHolesky
: never;

// Mainnet
Expand Down Expand Up @@ -127,3 +133,25 @@ export const executionClientsLukso = [
"lukso-besu.dnp.dappnode.eth",
] as const;
export type ExecutionClientLukso = (typeof executionClientsLukso)[number];

// Holesky

export const signerHolesky = "web3signer-holesky.dnp.dappnode.eth";
export type SignerHolesky = typeof signerHolesky;

export const consensusClientsHolesky = [
"prysm-holesky.dnp.dappnode.eth",
"lighthouse-holesky.dnp.dappnode.eth",
"teku-holesky.dnp.dappnode.eth",
"nimbus-holesky.dnp.dappnode.eth",
"lodestar-holesky.dnp.dappnode.eth",
] as const;
export type ConsensusClientHolesky = (typeof consensusClientsHolesky)[number];

export const executionClientsHolesky = [
"holesky-geth.dnp.dappnode.eth",
"holesky-erigon.dnp.dappnode.eth",
"holesky-nethermind.dnp.dappnode.eth",
"holesky-besu.dnp.dappnode.eth",
] as const;
export type ExecutionClientHolesky = (typeof executionClientsHolesky)[number];
Binary file added packages/ui/public/assets/lodestar-gnosis.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added packages/ui/public/assets/lodestar-prater.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added packages/ui/public/assets/lodestar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added packages/ui/public/assets/nethermind-goerli.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed packages/ui/public/assets/nimbus-gnosis.png
Binary file not shown.
6 changes: 6 additions & 0 deletions packages/ui/src/ImportScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,12 @@ export default function ImportScreen({
network
)
? [{ value: "solo", label: "Solo" }]
: ["holesky"].includes(network)
? [
{ value: "solo", label: "Solo" },
{ value: "rocketpool", label: "Rocketpool" },
{ value: "stakehouse", label: "StakeHouse" },
]
: [
{ value: "solo", label: "Solo" },
{ value: "rocketpool", label: "Rocketpool" },
Expand Down
38 changes: 28 additions & 10 deletions packages/ui/src/components/StakerConfig/StakerConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,38 @@ export default function StakerConfig({
stakerConfig: StakerConfigType<Network>;
}): JSX.Element {
const images = {
// Mainnet
"erigon.dnp.dappnode.eth": "/assets/erigon.png",
"goerli-erigon.dnp.dappnode.eth": "/assets/erigon-goerli.png",
"geth.dnp.dappnode.eth": "/assets/geth.png",
"besu.public.dappnode.eth": "/assets/besu.png",
"nethermind.public.dappnode.eth": "/assets/nethermind.png",
"nethermind-xdai.dnp.dappnode.eth": "/assets/nethermind-gnosis.png",
"goerli-geth.dnp.dappnode.eth": "/assets/geth-goerli.png",
"goerli-besu.dnp.dappnode.eth": "/assets/besu-goerli.png",
"prysm.dnp.dappnode.eth": "/assets/prysm.png",
"lighthouse.dnp.dappnode.eth": "/assets/lighthouse.png",
"teku.dnp.dappnode.eth": "/assets/teku.png",
"nimbus.dnp.dappnode.eth": "/assets/nimbus.png",
"lodestar.dnp.dappnode.eth": "/assets/lodestar.png",

// Goerli/Prater
"goerli-erigon.dnp.dappnode.eth": "/assets/erigon-goerli.png",
"goerli-geth.dnp.dappnode.eth": "/assets/geth-goerli.png",
"goerli-besu.dnp.dappnode.eth": "/assets/besu-goerli.png",
"goerli-nethermind.dnp.dappnode.eth": "/assets/nethermind-goerli.png",
"prysm-prater.dnp.dappnode.eth": "/assets/prysm-prater.png",
"lighthouse-prater.dnp.dappnode.eth": "/assets/lighthouse-prater.png",
"teku-prater.dnp.dappnode.eth": "/assets/teku-prater.png",
"nimbus-prater.dnp.dappnode.eth": "/assets/nimbus-prater.png",
"lodestar-prater.dnp.dappnode.eth": "/assets/lodestar-prater.png",

// Gnosis
"nethermind-xdai.dnp.dappnode.eth": "/assets/nethermind-gnosis.png",
"gnosis-beacon-chain-prysm.dnp.dappnode.eth": "/assets/prysm-gnosis.png",
"lighthouse-gnosis.dnp.dappnode.eth": "/assets/lighthouse-gnosis.png",
"teku-gnosis.dnp.dappnode.eth": "/assets/teku-gnosis.png",
"nimbus-gnosis.dnp.dappnode.eth": "/assets/nimbus-gnosis.png",
// TODO: Add Lukso logos (now mainnet)
// TODO: Add Nimbus Gnosis logo (now mainnet)
"nimbus-gnosis.dnp.dappnode.eth": "/assets/nimbus.png",
"lodestar-gnosis.dnp.dappnode.eth": "/assets/lodestar-gnosis.png",

// Lukso --> // TODO: Add Lukso logos (now mainnet)
"lukso-geth.dnp.dappnode.eth": "/assets/geth.png",
"lukso-erigon.dnp.dappnode.eth": "/assets/erigon.png",
"lukso-besu.dnp.dappnode.eth": "/assets/besu.png",
Expand All @@ -45,12 +56,19 @@ export default function StakerConfig({
"nimbus-lukso.dnp.dappnode.eth": "/assets/nimbus.png",
"lodestar-lukso.dnp.dappnode.eth": "/assets/lodestar.png",

//Holesky --> // TODO: Add Holesky logos (now mainnet)
"holesky-geth.dnp.dappnode.eth": "/assets/geth.png",
"holesky-erigon.dnp.dappnode.eth": "/assets/erigon.png",
"holesky-besu.dnp.dappnode.eth": "/assets/besu.png",
"holesky-nethermind.dnp.dappnode.eth": "/assets/nethermind.png",
"prysm-holesky.dnp.dappnode.eth": "/assets/prysm.png",
"lighthouse-holesky.dnp.dappnode.eth": "/assets/lighthouse.png",
"teku-holesky.dnp.dappnode.eth": "/assets/teku.png",
"nimbus-holesky.dnp.dappnode.eth": "/assets/nimbus.png",
"lodestar-holesky.dnp.dappnode.eth": "/assets/lodestar.png",

// Default logo until we have a package for them
default: "/assets/dappnode_logo_clean.png",
"goerli-nethermind.dnp.dappnode.eth": "/assets/dappnode_logo.png",
"lodestar.dnp.dappnode.eth": "/assets/dappnode_logo.png",
"lodestar-prater.dnp.dappnode.eth": "/assets/dappnode_logo.png",
"lodestar-gnosis.dnp.dappnode.eth": "/assets/dappnode_logo.png",
};

return (
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const beaconchaApiParamsMap = new Map<string, Omit<ApiParams, "host">>([
apiPath: "/api/v1/",
},
],
["holesky", { baseUrl: "https://holesky.beaconcha.in", apiPath: "/api/v1/" }],
]);

export interface AppParams {
Expand Down
3 changes: 2 additions & 1 deletion packages/ui/src/utils/dataUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ export function prettyClientDnpName(dnpName: string): string {
!name.includes("goerli") &&
!name.includes("prater") &&
!name.includes("gnosis") &&
!name.includes("lukso")
!name.includes("lukso") &&
!name.includes("holesky")
);
if (!clientName) return dnpName;

Expand Down

0 comments on commit 82256cf

Please sign in to comment.