From 6bda7c06bd7c0cf4e12506a8ef20312a61b0da02 Mon Sep 17 00:00:00 2001 From: Sam Sweet Date: Mon, 11 Nov 2024 07:33:35 -0500 Subject: [PATCH] SHARD-899: fetch canUnstake data from validator endpoint (#35) * fetch canUnstake data from validator endpoint * rename unstakeable to stakeState --------- Co-authored-by: Sam Sweet --- src/node-commands.ts | 63 +++++++++++++++++++++++---------- src/utils/fetch-network-data.ts | 19 ++++++++++ 2 files changed, 63 insertions(+), 19 deletions(-) diff --git a/src/node-commands.ts b/src/node-commands.ts index 2121de8..6d46f0c 100644 --- a/src/node-commands.ts +++ b/src/node-commands.ts @@ -45,6 +45,7 @@ import { getCommitHashForCLI, getCommitHashForGUI, getCommitHashForValidator, + fetchUnstakeableDetails, } from './utils'; import {isValidPrivate} from 'ethereumjs-util'; import logger from './utils/logger'; @@ -315,6 +316,31 @@ export function registerNodeCommands(program: Command) { ]); // TODO: Use Promise.allSettled. Need to update nodeJs to 12.9 + let nodeInfo; + try { + nodeInfo = await fetchNodeInfo(config); + } catch (e) { + logger.error('Unable to fetch node info: ' + e); + nodeInfo = null; + } + + let unstakable = { + unlocked: false, + reason: 'Could not fetch data', + remainingTime: -1, + }; + if (accountInfo.nominator) { + const eoaData = await fetchEOADetails(config, accountInfo.nominator); + + if (eoaData) { + const unstakableData = await fetchUnstakeableDetails( + config, + publicKey, + accountInfo.nominator + ); + unstakable = unstakableData ?? unstakable; + } + } if (descriptions.length === 0) { // Node process not started console.log( @@ -333,6 +359,7 @@ export function registerNodeCommands(program: Command) { ? ethers.utils.formatEther(accountInfo.totalPenalty) : '', autorestart: nodeConfig.autoRestart, + stakeState: unstakable, }) ); cache.writeMaps(); @@ -344,14 +371,6 @@ export function registerNodeCommands(program: Command) { if (status.status !== 'stopped') { // Node is started and active - let nodeInfo; - try { - nodeInfo = await fetchNodeInfo(config); - } catch (e) { - logger.error('Unable to fetch node info: ' + e); - nodeInfo = null; - } - const lockedStakeStr = accountInfo.lockedStake ? ethers.utils.formatEther(accountInfo.lockedStake) : ''; @@ -384,6 +403,7 @@ export function registerNodeCommands(program: Command) { : '', autorestart: nodeConfig.autoRestart, nodeInfo: nodeInfo, + stakeState: unstakable, // TODO: Add fetching node info when in standby }) ); @@ -414,6 +434,7 @@ export function registerNodeCommands(program: Command) { ? ethers.utils.formatEther(accountInfo.totalPenalty) : '', autorestart: nodeConfig.autoRestart, + stakeState: unstakable, }) ); cache.writeMaps(); @@ -432,24 +453,28 @@ export function registerNodeCommands(program: Command) { } try { - const eoaData = await fetchEOADetails(config, address) - const stakeValue = eoaData?.operatorAccountInfo?.stake?.value - const nominee = eoaData?.operatorAccountInfo?.nominee ?? '' + const eoaData = await fetchEOADetails(config, address); + const stakeValue = eoaData?.operatorAccountInfo?.stake?.value; + const nominee = eoaData?.operatorAccountInfo?.nominee ?? ''; // Convert stake value to ether, handling potential hexadecimal input const stakeOutput = stakeValue ? ethers.utils.formatEther( - ethers.BigNumber.from(stakeValue.startsWith('0x') ? stakeValue : '0x' + stakeValue).toString() + ethers.BigNumber.from( + stakeValue.startsWith('0x') ? stakeValue : '0x' + stakeValue + ).toString() ) - : '' + : ''; - console.log(yaml.dump({ - stake: stakeOutput, - nominee: nominee - })); + console.log( + yaml.dump({ + stake: stakeOutput, + nominee: nominee, + }) + ); } catch (error) { - console.log(error) - console.error(`Error fetching stake details for ${address}: ${error}`) + console.log(error); + console.error(`Error fetching stake details for ${address}: ${error}`); } }); diff --git a/src/utils/fetch-network-data.ts b/src/utils/fetch-network-data.ts index 87c0ee6..0f4af51 100644 --- a/src/utils/fetch-network-data.ts +++ b/src/utils/fetch-network-data.ts @@ -325,6 +325,25 @@ export async function fetchEOADetails( return eoaParams?.account; } +export async function fetchUnstakeableDetails( + config: networkConfigType, + nominee: string, + nominator: string +) { + const unstakable = await fetchDataFromNetwork<{ + stakeUnlocked: { + unlocked: boolean; + reason: string; + remainingTime: number; + }; + }>( + config, + `/canUnstake/${nominee}/${nominator}`, + data => data?.stakeUnlocked == null + ); + + return unstakable?.stakeUnlocked; +} export async function fetchValidatorVersions(config: networkConfigType) { const validatorVersions = await fetchDataFromNetwork<{