All files / src/Program utils.ts

87.5% Statements 42/48
78.94% Branches 15/19
91.66% Functions 11/12
83.33% Lines 30/36

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85  43x 43x 43x 43x 43x 43x 43x   43x 43x   43x                         43x 43x 5x                             43x 5x 5x   43x 5x             43x 15x   43x 7x 4x 1x         43x 10x             43x 10x           43x 10x      
import { Logger } from 'ts-log';
import { Programs, ProviderServerArgs, ServiceNames } from './programs/types';
import { WrongOption } from './errors';
import { getOgmiosCardanoNode } from './services/ogmios';
import { getPool } from './services/postgres';
import { loadGenesisData } from '../util';
import dns, { SrvRecord } from 'dns';
import pRetry, { FailedAttemptError } from 'p-retry';
 
export const SERVICE_DISCOVERY_BACKOFF_FACTOR_DEFAULT = 1.1;
export const SERVICE_DISCOVERY_TIMEOUT_DEFAULT = 60 * 1000;
 
export const cardanoNodeDependantServices = new Set([
  ServiceNames.NetworkInfo,
  ServiceNames.StakePool,
  ServiceNames.Utxo,
  ServiceNames.Rewards,
  ServiceNames.Asset,
  ServiceNames.ChainHistory
]);
 
export type RetryBackoffConfig = {
  factor?: number;
  maxRetryTime?: number;
};
export const onFailedAttemptFor =
  <ServiceNames>(serviceName: ServiceNames, logger: Logger) =>
  async ({ attemptNumber, message, retriesLeft }: FailedAttemptError) => {
    const nextAction = retriesLeft > 0 ? 'retrying...' : 'exiting';
    logger.trace(message);
    logger.debug(
      `Establishing connection to ${serviceName}: Attempt ${attemptNumber} of ${
        attemptNumber + retriesLeft
      }, ${nextAction}`
    );
    Iif (retriesLeft === 0) {
      logger.error(message);
      // will be caught by onDeath() to server.shutdown() and process.exit(1)
      process.kill(process.pid, 'SIGTERM');
    }
  };
// Select the first random record from the DNS server resolved list
export const resolveSrvRecord = async (serviceName: string): Promise<SrvRecord> => {
  const [srvRecord] = await dns.promises.resolveSrv(serviceName);
  return srvRecord;
};
export const createDnsResolver = (config: RetryBackoffConfig, logger: Logger) => async (serviceName: string) =>
  await pRetry(async () => await resolveSrvRecord(serviceName), {
    factor: config.factor,
    maxRetryTime: config.maxRetryTime,
    onFailedAttempt: onFailedAttemptFor(serviceName, logger)
  });
export type DnsResolver = ReturnType<typeof createDnsResolver>;
 
export const serviceSetHas = <ServiceNames>(serviceNames: ServiceNames[], services: Set<ServiceNames>) =>
  serviceNames.some((name) => services.has(name));
 
export const stringOptionToBoolean = (value: string, program: Programs, option: string) => {
  if (['0', 'f', 'false'].includes(value)) return false;
  if (['1', 't', 'true'].includes(value)) return true;
  throw new WrongOption(program, option, ['false', 'true']);
};
 
// If typeorm provider is enabled we establish a DB connection though the TypeORM data source
// Should be refactored when implement many typeorm providers and integrate with IOC dependency injection
export const getDbPools = async (dnsResolver: DnsResolver, logger: Logger, args: ProviderServerArgs) =>
  args.useTypeormStakePoolProvider || args.useTypeormAssetProvider
    ? {}
    : {
        healthCheck: await getPool(dnsResolver, logger, args),
        main: await getPool(dnsResolver, logger, args)
      };
 
export const getCardanoNode = async (dnsResolver: DnsResolver, logger: Logger, args: ProviderServerArgs) =>
  serviceSetHas(args.serviceNames, cardanoNodeDependantServices) &&
  !args.useTypeormStakePoolProvider &&
  !args.useTypeormAssetProvider
    ? await getOgmiosCardanoNode(dnsResolver, logger, args)
    : undefined;
 
export const getGenesisData = async (args: ProviderServerArgs) =>
  args.cardanoNodeConfigPath && !args.useTypeormStakePoolProvider && !args.useTypeormAssetProvider
    ? await loadGenesisData(args.cardanoNodeConfigPath)
    : undefined;