import sleep from 'sleep-promise' ; import yargs from 'yargs' ; import { switchToClusterFromEnv } from './cluster' ; import { execCmdWithExitOnFailure } from './cmd-utils' ; import { envVar , fetchEnv , isVmBased } from './env-utils' ; import { retrieveIPAddress } from './helm_deploy' ; import { getTestnetOutputs } from './vm-testnet-utils' ; export async function outputIncludes ( cmd , matchString , matchMessage ? ) { const [ stdout ] = await execCmdWithExitOnFailure ( cmd ) ; if ( stdout . includes ( matchString ) ) { if ( matchMessage ) { console . info ( matchMessage ) ; } return true ; } return false ; } export async function retrieveTxNodeIpAddress ( celoEnv , txNodeIndex ) { if ( isVmBased ( ) ) { const outputs = await getTestnetOutputs ( celoEnv ) ; return outputs . tx_node_ip_addresses . value [ txNodeIndex ] ; } else { return retrieveIPAddress ( `${ celoEnv }-tx-nodes-${ txNodeIndex }` ) ; } } export async function getVerificationPoolConfig ( celoEnv ) { await switchToClusterFromEnv ( celoEnv ) ; const ip = await retrieveTxNodeIpAddress ( celoEnv , 0 ) ; return { testnetId : fetchEnv ( 'NETWORK_ID' ) , txIP : ip , txPort : '8545' , } ; } export async function switchToGCPProject ( projectName ) { const [ currentProject ] = await execCmdWithExitOnFailure ( 'gcloud config get-value project' ) ; if ( currentProject !== projectName ) { await execCmdWithExitOnFailure ( `gcloud config set project ${ projectName }` ) ; } } export async function switchToProjectFromEnv ( ) { const expectedProject = fetchEnv ( envVar . TESTNET_PROJECT_NAME ) ; await switchToGCPProject ( expectedProject ) ; } export function addCeloGethMiddleware ( argv ) { return argv . option ( 'geth-dir' , { type : 'string' , description : 'path to geth repository' , demand : 'Please, specify the path to geth directory, where the binary could be found' , } ) . option ( 'data-dir' , { type : 'string' , description : 'path to datadir' , demand : 'Please, specify geth datadir' , } ) ; } export const validateAccountAddress = ( address ) => { return address !== null && address . toLowerCase ( ) . startsWith ( '0x' ) && address . length === 42 ; } ; export const ensure0x = ( hexstr ) => ( hexstr . startsWith ( '0x' ) ? hexstr : '0x' + hexstr ) ; export const strip0x = ( hexstr ) => ( hexstr . startsWith ( '0x' ) ? hexstr . slice ( 2 ) : hexstr ) ; export async function retryCmd ( cmd , numAttempts = 100 , maxTimeoutMs = 15000 ) { for ( let i = 1 ; i <= numAttempts ; i ++ ) { try { const result = await cmd ( ) ; return result ; } catch ( error ) { const sleepTimeBasisInMs = 1000 ; const sleepTimeInMs = Math . min ( sleepTimeBasisInMs * Math . pow ( 2 , i ) , maxTimeoutMs ) ; console . warn ( `${ new Date ( ) . toLocaleTimeString ( ) } Retry attempt: ${ i }/${ numAttempts }, ` + `retry after sleeping for ${ sleepTimeInMs } milli-seconds` , error ) ; await sleep ( sleepTimeInMs ) ; } } throw Error ( `Retried ${ numAttempts } without any successes` ) ; } export const stringToBoolean = ( myString ) => { return myString . toLowerCase ( ) === 'true' ; } ;