All files / src/simple-relayer start-simple-relayer.ts

7.4% Statements 2/27
0% Branches 0/9
0% Functions 0/2
7.4% Lines 2/27

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 793x       3x                                                                                                                                                    
import { sendHealthcheckPing } from "@redstone-finance/utils";
import { IContractConnector } from "../contracts/IContractConnector";
import { IPriceManagerContractAdapter } from "./IPriceManagerContractAdapter";
 
export async function startSimpleRelayer(
  config: {
    relayerIterationInterval: string | number;
    updatePriceInterval: string | number;
    healthcheckPingUrl?: string;
  },
  connector: IContractConnector<IPriceManagerContractAdapter>
) {
  const relayerIterationInterval = Number(config.relayerIterationInterval);
  const updatePriceInterval = Number(config.updatePriceInterval);
 
  const adapter = await connector.getAdapter();
 
  let pendingTransactionHash: string | undefined;
 
  console.log(
    `Starting contract prices updater with interval ${
      relayerIterationInterval / 1000
    } s.`
  );
 
  // eslint-disable-next-line @typescript-eslint/no-misused-promises -- We've decided to allow the exception for setInterval
  setInterval(async () => {
    {
      // eslint-disable-next-line @typescript-eslint/no-floating-promises
      sendHealthcheckPing(config.healthcheckPingUrl);
 
      let txHash: string | undefined;
 
      try {
        Iif (pendingTransactionHash != undefined) {
          return console.log(
            `Skipping, because there exists a pending transaction: ${pendingTransactionHash}`
          );
        }
        const timestampAndRound = await adapter.readTimestampAndRound();
 
        const currentTimestamp = Date.now();
        const timestampDelta =
          currentTimestamp - timestampAndRound.payload_timestamp;
        const isEnoughTimeElapsedSinceLastUpdate =
          timestampDelta >= updatePriceInterval;
        Iif (!isEnoughTimeElapsedSinceLastUpdate) {
          return console.log(
            `Skipping, because not enough time has passed to update prices (${
              timestampDelta / 1000
            } s. of ${updatePriceInterval / 1000} s.)`
          );
        }
 
        const round = timestampAndRound.round ?? -1;
        pendingTransactionHash = "...";
        txHash = await adapter.writePrices(round + 1);
        console.log(
          `Started updating prices (round: ${
            round + 1
          }) with transaction: ${txHash}`
        );
        pendingTransactionHash = txHash;
        console.log(`Waiting for the transaction's status changes...`);
        await connector.waitForTransaction(txHash);
      } catch (error) {
        console.error((error as Error).stack || error);
      } finally {
        Iif (
          pendingTransactionHash === txHash ||
          pendingTransactionHash === "..."
        ) {
          pendingTransactionHash = undefined;
        }
      }
    }
  }, relayerIterationInterval);
}