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

improving imported-validator-status #1915

Merged
merged 22 commits into from
Jun 26, 2024
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
REFACTOR: volutary-exit output
gbayasgalan committed Jun 24, 2024
commit 2b1746bf63d1b06bcf9808880e3b110fcc295cc9
245 changes: 119 additions & 126 deletions launcher/src/backend/Monitoring.js
Original file line number Diff line number Diff line change
@@ -3215,146 +3215,139 @@ rm -rf diskoutput

async exitValidatorAccount(pubkey, serviceID) {
const beaconStatus = await this.getBeaconStatus();
if (beaconStatus.code === 0) {
try {
const beaconAPIPort = beaconStatus.data[0].beacon.destinationPort;
const serviceId = beaconStatus.data[0].sid;
if (!Array.isArray(pubkey)) {
pubkey = [pubkey];

if (beaconStatus.code !== 0) {
return [
{
pubkey: undefined,
code: null,
msg: beaconStatus.info,
},
];
}

try {
const beaconAPIPort = beaconStatus.data[0].beacon.destinationPort;
const serviceId = beaconStatus.data[0].sid;
if (!Array.isArray(pubkey)) {
pubkey = [pubkey];
}
let results = [];

const parseRunExitCommandOutput = (output, pubkey) => {
if (!output.includes("{") || !output.includes("}")) {
return {
pubkey: pubkey,
code: null,
msg: output,
};
}
let results = [];
for (let i = 0; i < pubkey.length; i++) {
const ref = StringUtils.createRandomString(); // Create a random string to identify the task
this.nodeConnection.taskManager.otherTasksHandler(ref, `Exit Account ${pubkey[i].substring(0, 6)}..`);
try {
const result = await this.validatorAccountManager.getExitValidatorMessage(pubkey[i], serviceID);
if (result.data === undefined) {
throw result;
}
const curlTag = await this.nodeConnection.ensureCurlImage();
const exitMsg = result.data;
const exitCommand =
`docker run --rm --network=stereum curlimages/curl:${curlTag} curl ` +
`'http://stereum-${serviceId}:${beaconAPIPort}/eth/v1/beacon/pool/voluntary_exits' ` +
`-H 'accept: */*' ` +
`-H 'Content-Type: application/json' ` +
`-d '${JSON.stringify(exitMsg)}' -i -s`;

let runExitCommand = await this.nodeConnection.sshService.exec(exitCommand);
log.info(runExitCommand);

//Error handling
if (SSHService.checkExecError(runExitCommand) && runExitCommand.stderr)
throw SSHService.extractExecError(runExitCommand);

//--------------------------------------------------
runExitCommand = {
rc: 0,
stdout:
"HTTP/1.1 400 OK\r\n" +
"Server: nim-presto/0.0.3 (amd64/linux)\r\n" +
"Content-Length: 63\r\n" +
"Content-Type: application/json\r\n" +
"Date: Mon, 24 Jun 2024 13:40:02 GMT\r\n" +
"Connection: close\r\n" +
"\r\n" +
'{"code":500,"message":"Voluntary exit object(s) was broadcast"}',
stderr: "",
};
//--------------------------------------------------

// Push successful/failed task
if (runExitCommand.stdout.includes('"code":200')) {
this.nodeConnection.taskManager.otherTasksHandler(ref, `Exiting Account`, true, runExitCommand.stdout);
} else {
this.nodeConnection.taskManager.otherTasksHandler(
ref,
`Exiting Account Failed`,
false,
`Exiting Account Failed ${pubkey[i]} Failed:\n` + runExitCommand.stdout
);
}
this.nodeConnection.taskManager.otherTasksHandler(ref);

// If there was a failure, return the appropriate response
if (!runExitCommand.stdout.includes('"code":200')) {
if (!runExitCommand.stdout.includes("{") && !runExitCommand.stdout.includes("}")) {
results.push({
pubkey: pubkey[i],
code: null,
msg: runExitCommand.stdout,
});
} else {
const jsonStartIndex1 = runExitCommand.stdout.indexOf("{");
const jsonEndIndex1 = runExitCommand.stdout.lastIndexOf("}");
const stdoutJson = runExitCommand.stdout.substring(jsonStartIndex1, jsonEndIndex1 + 1);
let parsedJson = {};
parsedJson = JSON.parse(stdoutJson);

const code = parsedJson.code ? parsedJson.code : null;

results.push({
pubkey: runExitCommand.pubkey,
code: code,
msg: parsedJson.message ? parsedJson.message : runExitCommand.stdout,
});
}
} else if (runExitCommand.stdout.includes('"code":200')) {
if (!runExitCommand.stdout.includes("{") && !runExitCommand.stdout.includes("}")) {
results.push({
pubkey: pubkey[i],
code: null,
msg: runExitCommand.stdout,
});
} else {
// Extract the JSON payload from the stdout
const jsonStartIndex = runExitCommand.stdout.indexOf("{");
const jsonEndIndex = runExitCommand.stdout.lastIndexOf("}");
const stdoutJson = runExitCommand.stdout.substring(jsonStartIndex, jsonEndIndex + 1);

let parsedJson = {};

parsedJson = JSON.parse(stdoutJson);

const code = parsedJson.code ? parsedJson.code : null;

results.push({
pubkey: runExitCommand.pubkey,
code: code,
msg: parsedJson.message ? parsedJson.message : runExitCommand.stdout,
});
}
}
} catch (error) {
const jsonStartIndex = output.indexOf("{");
const jsonEndIndex = output.lastIndexOf("}");
const stdoutJson = output.substring(jsonStartIndex, jsonEndIndex + 1);
const parsedJson = JSON.parse(stdoutJson);

return {
pubkey: pubkey,
code: parsedJson.code || null,
msg: parsedJson.message || output,
};
};

const handleExitCommand = async (pubkey, serviceId, beaconAPIPort) => {
const ref = StringUtils.createRandomString();
this.nodeConnection.taskManager.otherTasksHandler(ref, `Exit Account ${pubkey.substring(0, 6)}..`);
try {
const result = await this.validatorAccountManager.getExitValidatorMessage(pubkey, serviceID);
if (result.data === undefined || !("data" in result)) {
throw new Error(result);
}

const curlTag = await this.nodeConnection.ensureCurlImage();
const exitMsg = result.data;
const exitCommand =
`docker run --rm --network=stereum curlimages/curl:${curlTag} curl ` +
`'http://stereum-${serviceId}:${beaconAPIPort}/eth/v1/beacon/pool/voluntary_exits' ` +
`-H 'accept: */*' ` +
`-H 'Content-Type: application/json' ` +
`-d '${JSON.stringify(exitMsg)}' -i -s`;

let runExitCommand = await this.nodeConnection.sshService.exec(exitCommand);
log.info(runExitCommand);

//-------------------------dummy for testing-------------------------
runExitCommand = {
rc: 0,
stdout:
"HTTP/1.1 200 OK\r\n" +
"Server: nim-presto/0.0.3 (amd64/linux)\r\n" +
"Content-Length: 63\r\n" +
"Content-Type: application/json\r\n" +
"Date: Mon, 24 Jun 2024 13:40:02 GMT\r\n" +
"Connection: close\r\n" +
"\r\n" +
'{"code":200,"message":"Voluntary exit object(s) was broadcast"}',
stderr: "",
};
//--------------------------------------------------

if (SSHService.checkExecError(runExitCommand) && runExitCommand.stderr) {
throw new Error(SSHService.extractExecError(runExitCommand));
}

const response = parseRunExitCommandOutput(runExitCommand.stdout, pubkey);

if (response.code === 200) {
this.nodeConnection.taskManager.otherTasksHandler(ref, `Exiting Account`, true, runExitCommand.stdout);
} else {
this.nodeConnection.taskManager.otherTasksHandler(
ref,
`Exiting Account Failed`,
false,
`Exiting Account Failed ${pubkey[i]} Failed:\n` + error
`Exiting Account Failed ${pubkey}:\n${runExitCommand.stdout}`
);
this.nodeConnection.taskManager.otherTasksHandler(ref);
log.error("Exiting signed voluntary account Failed:\n", error);
return error;
}

this.nodeConnection.taskManager.otherTasksHandler(ref);
return response;
} catch (error) {
this.nodeConnection.taskManager.otherTasksHandler(
ref,
`Exiting Account Failed`,
false,
`Exiting Account Failed ${pubkey}:\n${error}`
);
this.nodeConnection.taskManager.otherTasksHandler(ref);
log.error(`Exiting signed voluntary account failed for ${pubkey}:\n`, error);
return {
pubkey: pubkey,
code: null,
msg: error.toString(),
};
}
return results;
} catch (error) {
const ref = StringUtils.createRandomString();
this.nodeConnection.taskManager.otherTasksHandler(
ref,
"Error occurred to get Beacon service ID & port",
false,
`Error occurred to get Beacon service ID & port: ${error}`
);
this.nodeConnection.taskManager.otherTasksHandler(ref);
return error;
};

for (let i = 0; i < pubkey.length; i++) {
const result = await handleExitCommand(pubkey[i], serviceId, beaconAPIPort);
results.push(result);
}
} else if (beaconStatus.code !== 0) {

return results;
} catch (error) {
const ref = StringUtils.createRandomString();
this.nodeConnection.taskManager.otherTasksHandler(
ref,
"Error occurred to get Beacon service ID & port",
false,
`Error occurred to get Beacon service ID & port: ${error}`
);
this.nodeConnection.taskManager.otherTasksHandler(ref);
return [
{
pubkey: undefined,
code: null,
msg: beaconStatus.info,
msg: error.toString(),
},
];
}
2 changes: 1 addition & 1 deletion launcher/src/backend/ValidatorAccountManager.js
Original file line number Diff line number Diff line change
@@ -653,7 +653,7 @@ export class ValidatorAccountManager {
const data = JSON.parse(result.stdout);
if (data.data === undefined) {
if (data.code === undefined || data.message === undefined) {
throw "Undexpected Error: " + result;
throw "Undexpected Error: " + result.stdout;
}
throw data.code + " " + data.message;
}
32 changes: 13 additions & 19 deletions launcher/src/components/UI/staking-page/StakingScreen.vue
Original file line number Diff line number Diff line change
@@ -592,27 +592,20 @@ const withdrawValidatorKey = async () => {
};

if (typeof res !== "string") {
console.log("22222222222222222222-------------");
console.log("hahaha1111111111", res[0].code);
responseObj.code = res[0].code;
console.log("hahahah222222222", responseObj.code);
if (res[0].code === 0 || res[0].code === 200) {
console.log("9999999999999999999999999999999999999-------------", res[0]);
responseObj.pubkey = res[0].pubkey;
responseObj.msg = res[0].msg;
responseObj.flag = "approved";
} else {
console.log("3333333333333333333333-------------");
responseObj.msg = res[0].info;
}
} else {
console.log("444444444444444444-------------");
responseObj.msg = res.split("\n");
}

stakingStore.withdrawAndExitResponse = [responseObj];
} else {
console.log("555555555555555555555555-------------");
//if multiple keys
const multiKeys = stakingStore.keys
.map((item) => {
@@ -621,18 +614,19 @@ const withdrawValidatorKey = async () => {
}
})
.filter((key) => key !== undefined);
// stakingStore.withdrawAndExitResponse = await ControlService.exitValidatorAccount({
// pubkey: multiKeys,
// serviceID: stakingStore.selectedServiceToFilter.config?.serviceID,
// });
res = await Promise.all(
multiKeys.map(async (key) => {
return await ControlService.exitValidatorAccount({
pubkey: key,
serviceID: stakingStore.selectedServiceToFilter.config?.serviceID,
});
})
);
res = stakingStore.withdrawAndExitResponse = await ControlService.exitValidatorAccount({
pubkey: multiKeys,
serviceID: stakingStore.selectedServiceToFilter.config?.serviceID,
});
// res = await Promise.all(
// multiKeys.map(async (key) => {
// return await ControlService.exitValidatorAccount({
// pubkey: key,
// serviceID: stakingStore.selectedServiceToFilter.config?.serviceID,
// });
// })
// );
console.log("222222222222222222222-------------", res);
stakingStore.withdrawAndExitResponse = res.map((item) => {
let responseObj = {
pubkey: "multi keys",