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  38x 38x 38x 38x 38x 38x 38x   38x 38x   38x                         38x 38x 5x                             38x 5x 5x   38x 5x             38x 15x   38x 7x 4x 1x         38x 10x             38x 10x           38x 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;