ramda#reduceBy JavaScript Examples

The following examples show how to use ramda#reduceBy. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: staking_payouts.js    From sdk with MIT License 5 votes vote down vote up
buildValidatorRewards = curry(
  ({ pointsByEra, rewardsByEra, prefsByEra }, validatorEras) => {
    const stashErasReducer = (acc, { eras, stashId }) => {
      const eraReducer = (acc, era) => {
        const eraKey = era.toString();
        const eraPoints = pointsByEra[eraKey];
        const eraRewards = rewardsByEra[eraKey];
        const eraPrefs = prefsByEra[eraKey];

        if (
          // Points must be greater than 0
          eraPoints?.eraPoints.gt(new BN(0)) &&
          // We must have a stash as a validator in the given era
          eraPoints?.validators[stashId] &&
          // Era rewards should be defined
          eraRewards &&
          // Validator commission in the given era should be acceptable
          eraPrefs.validators[stashId]?.commission?.toBn().lte(MaxCommission)
        ) {
          const reward = eraPoints.validators[stashId]
            .mul(eraRewards.eraReward)
            .div(eraPoints.eraPoints);

          if (!reward.isZero())
            return acc.concat({
              era,
              reward,
            });
        }

        return acc;
      };

      return eras.reduce(eraReducer, acc);
    };

    return o(
      // Filter out stashes with no rewards
      reject(isEmpty),
      // Reduce given stash eras by the stash id
      reduceBy(stashErasReducer, [], prop("stashId"))
    )(validatorEras);
  }
)
Example #2
Source File: checkArbitratorAnswers.js    From cross-chain-realitio-proxy with MIT License 4 votes vote down vote up
export default async function checkArbitratorAnswers({ homeChainApi }) {
  const chainId = await homeChainApi.getChainId();

  await checkUntrackedArbitratorAnswers();
  await checkCurrentArbitratorAnswers();

  async function checkUntrackedArbitratorAnswers() {
    const [fromBlock, toBlock] = await P.all([getBlockHeight("RULED_REQUESTS"), homeChainApi.getBlockNumber()]);

    const untrackedNotifiedRequests = filter(
      ({ status }) => [Status.AwaitingRuling, Status.Ruled].includes(status),
      await homeChainApi.getNotifiedRequests({ fromBlock, toBlock })
    );

    await saveRequests(untrackedNotifiedRequests);

    const blockHeight = toBlock + 1;
    await updateBlockHeight({ key: "RULED_REQUESTS", blockHeight });
    console.info({ blockHeight }, "Set RULED_REQUESTS block height");

    const stats = {
      data: map(pick(["questionId", "chainId"]), untrackedNotifiedRequests),
      fromBlock,
      toBlock,
    };

    console.info(stats, "Found new requests with arbitrator answers");

    return stats;
  }

  async function checkCurrentArbitratorAnswers() {
    const requestFinishedOrCanceled = ([_, onChainRequest]) =>
      [Status.None, Status.Finished].includes(onChainRequest.status);
    const removeOffChainRequest = asyncPipe([
      mergeOnChainOntoOffChain,
      removeRequest,
      (request) => ({
        action: "OFF_CHAIN_REQUEST_REMOVED",
        payload: request,
      }),
    ]);

    const requestRuled = ([_, onChainArbitration]) => onChainArbitration.status === Status.Ruled;
    const reportArbitrationAnswer = asyncPipe([
      mergeOnChainOntoOffChain,
      homeChainApi.reportArbitrationAnswer,
      (request) => ({
        action: "ARBITRATION_ANSWER_REPORTED",
        payload: request,
      }),
    ]);

    const noop = asyncPipe([
      mergeOnChainOntoOffChain,
      (arbtration) => ({
        action: "NO_OP",
        payload: arbtration,
      }),
    ]);

    const requestsWithRuling = await fetchRequestsByChainId({ status: Status.Ruled, chainId });

    console.info(
      { data: map(pick(["questionId", "requester"]), requestsWithRuling) },
      "Fetched requests which received the arbitration ruling"
    );

    const pipeline = asyncPipe([
      fetchOnChainCounterpart,
      cond([
        [requestFinishedOrCanceled, removeOffChainRequest],
        [requestRuled, reportArbitrationAnswer],
        [() => true, noop],
      ]),
    ]);

    const results = await P.allSettled(map(pipeline, requestsWithRuling));

    const groupQuestionsOrErrorMessage = (acc, r) => {
      if (r.status === "rejected") {
        return [...acc, r.reason?.message];
      }

      const questionId = r.value?.payload?.questionId ?? "<not set>";
      const requester = r.value?.payload?.requester ?? "<not set>";
      return [...acc, { questionId, requester }];
    };
    const toTag = (r) => (r.status === "rejected" ? "FAILURE" : r.value?.action);
    const stats = reduceBy(groupQuestionsOrErrorMessage, [], toTag, results);

    console.info(stats, "Processed requests with ruling");
  }

  async function fetchOnChainCounterpart(offChainRequest) {
    const { questionId, requester } = offChainRequest;

    const onChainRequest = await homeChainApi.getRequest({ questionId, requester });

    return [offChainRequest, onChainRequest];
  }
}
Example #3
Source File: checkNotifiedRequests.js    From cross-chain-realitio-proxy with MIT License 4 votes vote down vote up
export default async function checkNotifiedRequests({ homeChainApi }) {
  const chainId = await homeChainApi.getChainId();

  await checkUntrackedNotifiedRequests();
  await checkCurrentNotifiedRequests();

  async function checkUntrackedNotifiedRequests() {
    const [fromBlock, toBlock] = await P.all([getBlockHeight("NOTIFIED_REQUESTS"), homeChainApi.getBlockNumber()]);

    const untrackedNotifiedRequests = filter(
      ({ status }) => status !== Status.None,
      await homeChainApi.getNotifiedRequests({ fromBlock, toBlock })
    );

    await saveRequests(untrackedNotifiedRequests);

    const blockHeight = toBlock + 1;
    await updateBlockHeight({ key: "NOTIFIED_REQUESTS", blockHeight });
    console.info({ blockHeight }, "Set NOTIFIED_REQUESTS block height");

    const stats = {
      data: map(pick(["questionId", "chainId", "status"]), untrackedNotifiedRequests),
      fromBlock,
      toBlock,
    };

    console.info(stats, "Found new notified arbitration requests");

    return stats;
  }

  async function checkCurrentNotifiedRequests() {
    const requestNotified = ([_, onChainArbitration]) => onChainArbitration.status === Status.Notified;
    const handleNotifiedRequest = asyncPipe([
      mergeOnChainOntoOffChain,
      homeChainApi.handleNotifiedRequest,
      (request) => ({
        action: "NOTIFIED_REQUEST_HANDLED",
        payload: request,
      }),
    ]);

    const requestStatusChanged = ([offChainRequest, onChainRequest]) => offChainRequest.status != onChainRequest.status;
    const updateOffChainRequest = asyncPipe([
      mergeOnChainOntoOffChain,
      updateRequest,
      (request) => ({
        action: "STATUS_CHANGED",
        payload: request,
      }),
    ]);

    const noop = asyncPipe([
      mergeOnChainOntoOffChain,
      (request) => ({
        action: "NO_OP",
        payload: request,
      }),
    ]);

    const pipeline = asyncPipe([
      fetchOnChainCounterpart,
      cond([
        [requestNotified, handleNotifiedRequest],
        [requestStatusChanged, updateOffChainRequest],
        [() => true, noop],
      ]),
    ]);

    const notifiedRequests = await fetchRequestsByChainIdAndStatus({ status: Status.Notified, chainId });

    console.info({ data: map(pick(["questionId", "requester"]), notifiedRequests) }, "Fetched notified requests");

    const results = await P.allSettled(map(pipeline, notifiedRequests));

    const groupQuestionsOrErrorMessage = (acc, r) => {
      if (r.status === "rejected") {
        return [...acc, r.reason?.message];
      }

      const questionId = r.value?.payload?.questionId ?? "<not set>";
      const requester = r.value?.payload?.requester ?? "<not set>";
      return [...acc, { questionId, requester }];
    };
    const toTag = (r) => (r.status === "rejected" ? "FAILURE" : r.value?.action);
    const stats = reduceBy(groupQuestionsOrErrorMessage, [], toTag, results);

    console.info(stats, "Processed notified requests");

    return stats;
  }

  async function fetchOnChainCounterpart(offChainRequest) {
    const { questionId, requester } = offChainRequest;

    const onChainRequest = await homeChainApi.getRequest({ questionId, requester });

    return [offChainRequest, onChainRequest];
  }
}
Example #4
Source File: checkRejectedRequests.js    From cross-chain-realitio-proxy with MIT License 4 votes vote down vote up
export default async function checkRejectedRequests({ homeChainApi }) {
  const chainId = await homeChainApi.getChainId();

  await checkUntrackedRejectedRequests();
  await checkCurrentRejectedRequests();

  async function checkUntrackedRejectedRequests() {
    const [fromBlock, toBlock] = await Promise.all([
      getBlockHeight("REJECTED_REQUESTS"),
      homeChainApi.getBlockNumber(),
    ]);

    const untrackedRejectedRequests = filter(
      ({ status }) => status === Status.Rejected,
      await homeChainApi.getRejectedRequests({ fromBlock, toBlock })
    );

    await saveRequests(untrackedRejectedRequests);

    const blockHeight = toBlock + 1;
    await updateBlockHeight({ key: "REJECTED_REQUESTS", blockHeight });
    console.info({ blockHeight }, "Set REJECTED_REQUESTS block height");

    const stats = {
      data: map(pick(["questionId", "requester"]), untrackedRejectedRequests),
      fromBlock,
      toBlock,
    };

    console.info(stats, "Found new rejected arbitration requests");

    return stats;
  }

  async function checkCurrentRejectedRequests() {
    const requestRemoved = ([_, onChainArbitration]) => onChainArbitration.status === Status.None;
    const removeOffChainRequest = asyncPipe([
      mergeOnChainOntoOffChain,
      removeRequest,
      (arbitration) => ({
        action: "REQUEST_REMOVED",
        payload: arbitration,
      }),
    ]);

    const requestRejected = ([_, onChainArbitration]) => onChainArbitration.status === Status.Rejected;
    const handleRejectedRequest = asyncPipe([
      mergeOnChainOntoOffChain,
      homeChainApi.handleRejectedRequest,
      (request) => ({
        action: "REJECTED_REQUEST_HANDLED",
        payload: request,
      }),
    ]);

    const noop = asyncPipe([
      mergeOnChainOntoOffChain,
      (request) => ({
        action: "NO_OP",
        payload: request,
      }),
    ]);

    const pipeline = asyncPipe([
      fetchOnChainCounterpart,
      cond([
        [requestRemoved, removeOffChainRequest],
        [requestRejected, handleRejectedRequest],
        [() => true, noop],
      ]),
    ]);

    const rejectedRequests = await fetchRequestsByChainIdAndStatus({ chainId, status: Status.Rejected });

    console.info({ data: map(pick(["questionId", "requester"]), rejectedRequests) }, "Fetched rejected requests");

    const results = await P.allSettled(map(pipeline, rejectedRequests));

    const groupQuestionsOrErrorMessage = (acc, r) => {
      if (r.status === "rejected") {
        return [...acc, r.reason?.message];
      }

      const questionId = r.value?.payload?.questionId ?? "<not set>";
      const requester = r.value?.payload?.requester ?? "<not set>";
      return [...acc, { questionId, requester }];
    };
    const toTag = (r) => (r.status === "rejected" ? "FAILURE" : r.value?.action);
    const stats = reduceBy(groupQuestionsOrErrorMessage, [], toTag, results);

    console.info(stats, "Processed rejected requests");

    return stats;
  }

  async function fetchOnChainCounterpart(offChainRequest) {
    const { questionId, requester } = offChainRequest;

    const onChainRequest = await homeChainApi.getRequest({ questionId, requester });

    return [offChainRequest, onChainRequest];
  }
}
Example #5
Source File: checkRequestedArbitrations.js    From cross-chain-realitio-proxy with MIT License 4 votes vote down vote up
export default async function checkRequestedArbitrations({ foreignChainApi }) {
  const chainId = await foreignChainApi.getChainId();

  await checkUntrackedArbitrationRequests();
  await processArbitrationRequests();

  async function checkUntrackedArbitrationRequests() {
    const [fromBlock, toBlock] = await P.all([
      getBlockHeight("ACCEPTED_ARBITRATION_REQUESTS"),
      foreignChainApi.getBlockNumber(),
    ]);

    const untrackedArbitrationRequests = filter(
      ({ status }) => status !== status.None,
      await foreignChainApi.getRequestedArbitrations({ fromBlock, toBlock })
    );

    await saveRequests(untrackedArbitrationRequests);

    const blockHeight = toBlock + 1;
    await updateBlockHeight({ key: "ACCEPTED_ARBITRATION_REQUESTS", blockHeight });
    console.info({ blockHeight }, "Set ACCEPTED_ARBITRATION_REQUESTS block height");

    const stats = {
      data: map(pick(["questionId", "requester", "chainId", "status"]), untrackedArbitrationRequests),
      fromBlock,
      toBlock,
    };

    console.info(stats, "Found new notified arbitration requests");

    return stats;
  }

  async function processArbitrationRequests() {
    const requestRemovedOrRuled = ([_, onChainArbitration]) =>
      [Status.None, Status.Ruled].includes(onChainArbitration.status);
    const removeOffChainRequest = asyncPipe([
      mergeOnChainOntoOffChain,
      removeRequest,
      (arbitration) => ({
        action: "ARBITRATION_REQUEST_REMOVED",
        payload: arbitration,
      }),
    ]);

    const disputeCreationFailed = ([_, onChainArbitration]) => onChainArbitration.status === Status.Failed;
    const handleFailedDisputeCreation = asyncPipe([
      mergeOnChainOntoOffChain,
      foreignChainApi.handleFailedDisputeCreation,
      (arbitration) => ({
        action: "FAILED_DISPUTE_CREATION_HANDLED",
        payload: arbitration,
      }),
    ]);

    const requestStatusChanged = ([offChainArbitration, onChainArbitration]) =>
      offChainArbitration.status != onChainArbitration.status;
    const updateOffChainRequest = asyncPipe([
      mergeOnChainOntoOffChain,
      updateRequest,
      (arbitration) => ({
        action: "STATUS_CHANGED",
        payload: arbitration,
      }),
    ]);

    const noop = asyncPipe([
      mergeOnChainOntoOffChain,
      (arbtration) => ({
        action: "NO_OP",
        payload: arbtration,
      }),
    ]);

    const pipeline = asyncPipe([
      fetchOnChainCounterpart,
      cond([
        [requestRemovedOrRuled, removeOffChainRequest],
        [disputeCreationFailed, handleFailedDisputeCreation],
        [requestStatusChanged, updateOffChainRequest],
        [() => true, noop],
      ]),
    ]);

    const requestedArbitrations = await fetchRequestsByChainId({ chainId });

    console.info(
      { data: map(pick(["questionId", "requester"]), requestedArbitrations) },
      "Fetched requested arbitrations"
    );

    const results = await P.allSettled(map(pipeline, requestedArbitrations));

    const groupQuestionsOrErrorMessage = (acc, r) => {
      if (r.status === "rejected") {
        return [...acc, r.reason?.message];
      }

      const questionId = r.value?.payload?.questionId ?? "<not set>";
      const requester = r.value?.payload?.requester ?? "<not set>";
      return [...acc, { questionId, requester }];
    };
    const toTag = (r) => (r.status === "rejected" ? "FAILURE" : r.value?.action);
    const stats = reduceBy(groupQuestionsOrErrorMessage, [], toTag, results);

    console.info(stats, "Processed requested arbitrations");

    return stats;
  }

  async function fetchOnChainCounterpart(offChainArbitration) {
    const { questionId, requester } = offChainArbitration;

    const onChainArbitration = await foreignChainApi.getArbitrationRequest({ questionId, requester });

    return [offChainArbitration, onChainArbitration];
  }
}