Skip to content

Commit

Permalink
ADD: Lido <> Obol SDVT Integration (#1811)
Browse files Browse the repository at this point in the history
* FIX: backup button

* FIX: Not all logs shown

* FIX: Doppelgänger displayed on failed import

* ADD: Easy Installation for LidoObolExit and Ejector Service

* FIX: failed reading ssh keys bc not connected

* FIX: Custom Installation button

* ADD: Expert Mode and OneClick Preset

* ADD: Icons

* FIX: use user root to keep safe permissions for charon data
  • Loading branch information
NeoPlays authored Apr 12, 2024
1 parent 9f31ba7 commit bf7f817
Show file tree
Hide file tree
Showing 23 changed files with 415 additions and 144 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions launcher/src/backend/OneClickInstall.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,24 @@ export class OneClickInstall {
this.extraServices.push(this.serviceManager.getService("NotificationService", args));
}

if (constellation.includes("ValidatorEjectorService")) {
//ValidatorEjectorService
this.extraServices.push(this.serviceManager.getService("ValidatorEjectorService", {
...args,
consensusClients: [this.beaconService],
executionClients: [this.executionClient],
}));
}

if (constellation.includes("LidoObolExitService")) {
//LidoObolExitService
this.extraServices.push(this.serviceManager.getService("LidoObolExitService", {
...args,
consensusClients: [this.beaconService].concat(this.extraServices.filter((s) => s.service === "CharonService")),
otherServices: this.extraServices.filter((s) => s.service === "ValidatorEjectorService"),
}));
}

this.handleArchiveTags(selectedPreset);


Expand Down Expand Up @@ -452,6 +470,17 @@ export class OneClickInstall {
break;
case "archive":
break;
case "lidoobol":
services = [
"NethermindService",
"LighthouseBeaconService",
"LodestarValidatorService",
"GrafanaService",
"PrometheusNodeExporterService",
"PrometheusService",
"NotificationService",
];
services.push("LidoObolExitService", "CharonService", "ValidatorEjectorService");
}
return services;
}
Expand Down
24 changes: 14 additions & 10 deletions launcher/src/backend/SSHService.js
Original file line number Diff line number Diff line change
Expand Up @@ -324,18 +324,22 @@ export class SSHService {

async readSSHKeyFile(sshDirPath = `~/.ssh`) {
let authorizedKeys = [];
try {
if (sshDirPath.endsWith("/")) sshDirPath = sshDirPath.slice(0, -1, ""); //if path ends with '/' remove it
let result = await this.exec(`cat ${sshDirPath}/authorized_keys`);
if (SSHService.checkExecError(result)) {
throw new Error("Failed reading authorized keys:\n" + SSHService.extractExecError(result));
if (this.connected) {
try {
if (sshDirPath.endsWith("/")) sshDirPath = sshDirPath.slice(0, -1, ""); //if path ends with '/' remove it
let result = await this.exec(`cat ${sshDirPath}/authorized_keys`);
if (SSHService.checkExecError(result)) {
throw new Error("Failed reading authorized keys:\n" + SSHService.extractExecError(result));
}
authorizedKeys = result.stdout.split("\n").filter((e) => e); // split in new lines and remove empty lines
} catch (err) {
log.error("Can't read authorized keys ", err);
return [];
}
authorizedKeys = result.stdout.split("\n").filter((e) => e); // split in new lines and remove empty lines
} catch (err) {
log.error("Can't read authorized keys ", err);
return [];
console.log("authorizedKeys: ", authorizedKeys);
} else {
log.error("SSH not connected, can't read authorized keys");
}
console.log("authorizedKeys: ", authorizedKeys);
return authorizedKeys;
}

Expand Down
178 changes: 118 additions & 60 deletions launcher/src/backend/ServiceManager.js

Large diffs are not rendered by default.

36 changes: 27 additions & 9 deletions launcher/src/backend/ethereum-services/LidoObolExitService.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ import { NodeService } from "./NodeService";
import { ServiceVolume } from "./ServiceVolume";

export class LidoObolExitService extends NodeService {
static buildByUserInput(network, ports, dir) {
static buildByUserInput(network, ports, dir, consensusClients, otherServices) {

let ejector = otherServices.find((service) => service.service === "ValidatorEjectorService");
let charon = consensusClients.find((service) => service.service === "CharonService");
if (charon)
otherServices.push(charon);
consensusClients = consensusClients.filter((service) => !(service.service === "CharonService"));

const service = new LidoObolExitService();
service.setId();
const workingDir = service.buildWorkingDir(dir);
Expand All @@ -12,11 +19,20 @@ export class LidoObolExitService extends NodeService {
const exitmessagesDir = "/exitmessages";
const charonDir = "/charon";


const charonFoler = charon ? `${charon.getDataDir()}/.charon` : workingDir + "/charon";

let messageVolume = ejector ? ejector.volumes.find((volume) => volume.servicePath === '/app/messages') : "";
const messageDir = messageVolume ? messageVolume.destinationPath : workingDir + "/exitmessages";

const volumes = [
new ServiceVolume(workingDir + "/exitmessages", exitmessagesDir),
new ServiceVolume(workingDir + "/charon", charonDir),
new ServiceVolume(messageDir, exitmessagesDir),
new ServiceVolume(charonFoler, charonDir),
];




service.init(
"LidoObolExitService", //service
service.id, // id
Expand All @@ -25,10 +41,10 @@ export class LidoObolExitService extends NodeService {
"latest", // imageVersion
[
"run",
"--beacon-node-url=http://beaconAddress:beaconPort",
`--beacon-node-url=${consensusClients[0] ? consensusClients[0].buildConsensusClientHttpEndpointUrl() : ""}`,
"--charon-runtime-dir=" + charonDir,
"--ejector-exit-path=" + exitmessagesDir,
"--exit-epoch=194048",
`--exit-epoch=${network === "mainnet" ? "194048" : "256"}`,
"--log-color=auto",
"--log-format=console",
"--log-level=info",
Expand All @@ -39,10 +55,12 @@ export class LidoObolExitService extends NodeService {
null, // env
ports, // ports
volumes, // volumes
null, // user
network // network
// executionClients
// consensusClients
"root", // user
network, // network
[], // executionClients
consensusClients[0] ? [consensusClients[0]] : [], // consensusClients
[], // MevBoost
otherServices // otherServices
);
return service;
}
Expand Down
6 changes: 5 additions & 1 deletion launcher/src/backend/ethereum-services/NodeService.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ export class NodeService {
network,
executionClients,
consensusClients,
mevboost
mevboost,
otherServices,
) {
this.service = service;
this.setId(id);
Expand All @@ -81,6 +82,7 @@ export class NodeService {
executionClients: executionClients,
consensusClients: consensusClients,
mevboost: mevboost,
otherServices: otherServices,
};
}

Expand All @@ -104,6 +106,7 @@ export class NodeService {
executionClients: config.dependencies.executionClients ? config.dependencies.executionClients : [],
consensusClients: config.dependencies.consensusClients ? config.dependencies.consensusClients : [],
mevboost: config.dependencies.mevboost ? config.dependencies.mevboost : [],
otherServices: config.dependencies.otherServices ? config.dependencies.otherServices : [],
};
}

Expand Down Expand Up @@ -139,6 +142,7 @@ export class NodeService {
service.buildMinimalConfiguration()
),
mevboost: (this.dependencies.mevboost || []).map((service) => service.buildMinimalConfiguration()),
otherServices: (this.dependencies.otherServices || []).map((service) => service.buildMinimalConfiguration()),
},
};
}
Expand Down
36 changes: 28 additions & 8 deletions launcher/src/backend/ethereum-services/ValidatorEjectorService.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { NodeService } from "./NodeService";
import { ServiceVolume } from "./ServiceVolume";

export class ValidatorEjectorService extends NodeService {
static buildByUserInput(network, dir) {
static buildByUserInput(network, dir, executionClients, consensusClients) {
const service = new ValidatorEjectorService();
service.setId();
const workingDir = service.buildWorkingDir(dir);
Expand All @@ -12,6 +12,24 @@ export class ValidatorEjectorService extends NodeService {

const volumes = [new ServiceVolume(workingDir + "/messages", messageDir)];

let locatorAddress = "0x0000000000000000000000000000000000000000";
let oracleAllowList = '["0x0000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000"]';
switch (network) {
case "mainnet":
locatorAddress = "0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb" //https://docs.lido.fi/deployed-contracts/#core-protocol
oracleAllowList = '["0x140Bd8FbDc884f48dA7cb1c09bE8A2fAdfea776E","0xA7410857ABbf75043d61ea54e07D57A6EB6EF186","0x404335BcE530400a5814375E7Ec1FB55fAff3eA2","0x946D3b081ed19173dC83Cd974fC69e1e760B7d78","0x007DE4a5F7bc37E2F26c0cb2E8A95006EE9B89b5","0xEC4BfbAF681eb505B94E4a7849877DC6c600Ca3A","0x61c91ECd902EB56e314bB2D5c5C07785444Ea1c8","0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d","0xc79F702202E3A6B0B6310B537E786B9ACAA19BAf"]'
break;
case "holesky":
locatorAddress = "0x28FAB2059C713A7F9D8c86Db49f9bb0e96Af1ef8" //https://docs.lido.fi/deployed-contracts/holesky#core-protocol
oracleAllowList = '["0x12A1D74F8697b9f4F1eEBb0a9d0FB6a751366399","0xD892c09b556b547c80B7d8c8cB8d75bf541B2284","0xf7aE520e99ed3C41180B5E12681d31Aa7302E4e5","0x31fa51343297FFce0CC1E67a50B2D3428057D1b1","0x81E411f1BFDa43493D7994F82fb61A415F6b8Fd4","0x4c75FA734a39f3a21C57e583c1c29942F021C6B7","0xD3b1e36A372Ca250eefF61f90E833Ca070559970"]'
break;
case "sepolia":
locatorAddress = "0x8f6254332f69557A72b0DA2D5F0Bc07d4CA991E7" //https://docs.lido.fi/deployed-contracts/sepolia#core-protocol
break;
default:
break;
}

service.init(
"ValidatorEjectorService",
service.id, // id
Expand All @@ -21,13 +39,13 @@ export class ValidatorEjectorService extends NodeService {
[], // command
[], // entrypoint
{
EXECUTION_NODE: "http://foo-bar:8545",
CONSENSUS_NODE: "http://foo-bar:5052",
LOCATOR_ADDRESS: "0x0000000000000000000000000000000000000000",
EXECUTION_NODE: executionClients[0] ? executionClients[0].buildExecutionClientHttpEndpointUrl() : "",
CONSENSUS_NODE: consensusClients[0] ? consensusClients[0].buildConsensusClientHttpEndpointUrl() : "",
LOCATOR_ADDRESS: locatorAddress,
STAKING_MODULE_ID: "123",
OPERATOR_ID: "123",
MESSAGES_LOCATION: "/app/messages",
ORACLE_ADDRESSES_ALLOWLIST: '["0x0000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000"]',
ORACLE_ADDRESSES_ALLOWLIST: oracleAllowList,
HTTP_PORT: "8989",
RUN_METRICS: "true",
RUN_HEALTH_CHECK: "true",
Expand All @@ -36,9 +54,11 @@ export class ValidatorEjectorService extends NodeService {
null, // ports
volumes, // volumes
null, // user
network // network
// executionClients
// consensusClients
network, // network
executionClients[0] ? [executionClients[0]] : [], // executionClients
consensusClients[0] ? [consensusClients[0]] : [], // consensusClients
[], // MevBoost
[] // otherServices
);
return service;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ watch(userSelectedPath, (newValue) => {
});
watchEffect(() => {
if (userSelectedPath.value === "") {
if (userSelectedPath.value === "" || !selectedNetworkName.value) {
nextBtnDisabled.value = true;
} else {
nextBtnDisabled.value = false;
Expand All @@ -144,7 +144,7 @@ const selectNetwork = (network) => {
selectedNetworkName.value = network.name;
manageStore.currentNetwork = network;
displayItem.value = network;
nextBtnDisabled.value = true;
nextBtnDisabled.value = false;
networkListDropdown.value = false;
};
Expand Down
3 changes: 3 additions & 0 deletions launcher/src/components/UI/edit-page/EditScreen.vue
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ const switchClientConfirm = (properties) => {
installDir: "/opt/stereum",
executionClients: [],
consensusClients: [],
otherServices: [],
checkpointURL: properties.checkPointSyncUrl ? properties.checkPointSyncUrl : false,
},
},
Expand All @@ -298,6 +299,7 @@ const confirmModifyingService = (item) => {
data: {
executionClients: item.executionClients,
consensusClients: item.consensusClients,
otherServices: item.otherServices,
},
});
manageStore.isLineHidden = false;
Expand Down Expand Up @@ -450,6 +452,7 @@ const addServiceHandler = (item) => {
installDir: item.installDir || "/opt/stereum",
executionClients: item.executionClients,
consensusClients: item.consensusClients,
otherServices: item.otherServices,
relays: item.relays.map((r) => r[manageStore.configNetwork.network.toLowerCase()]).join(),
checkpointURL: item.checkPointSyncUrl || false,
//CustomService Attributes
Expand Down
Loading

0 comments on commit bf7f817

Please sign in to comment.