UNPKG

@celo/contractkit

Version:

Celo's ContractKit to interact with Celo network

150 lines 9.81 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.EpochManagerWrapper = exports.EpochProcessStatus = void 0; const base_1 = require("@celo/base"); const bignumber_js_1 = __importDefault(require("bignumber.js")); const BaseWrapper_1 = require("./BaseWrapper"); const BaseWrapperForGoverning_1 = require("./BaseWrapperForGoverning"); var EpochProcessStatus; (function (EpochProcessStatus) { EpochProcessStatus[EpochProcessStatus["NotStarted"] = 0] = "NotStarted"; EpochProcessStatus[EpochProcessStatus["Started"] = 1] = "Started"; })(EpochProcessStatus || (exports.EpochProcessStatus = EpochProcessStatus = {})); /** * Contract handling epoch management. */ class EpochManagerWrapper extends BaseWrapperForGoverning_1.BaseWrapperForGoverning { constructor() { super(...arguments); this.epochDuration = (0, BaseWrapper_1.proxyCall)(this.contract.methods.epochDuration, undefined, BaseWrapper_1.valueToInt); this.firstKnownEpoch = (0, BaseWrapper_1.proxyCall)(this.contract.methods.firstKnownEpoch, undefined, BaseWrapper_1.valueToInt); this.getCurrentEpochNumber = (0, BaseWrapper_1.proxyCall)(this.contract.methods.getCurrentEpochNumber, undefined, BaseWrapper_1.valueToInt); this.getFirstBlockAtEpoch = (0, BaseWrapper_1.proxyCall)(this.contract.methods.getFirstBlockAtEpoch, undefined, BaseWrapper_1.valueToInt); this.getLastBlockAtEpoch = (0, BaseWrapper_1.proxyCall)(this.contract.methods.getLastBlockAtEpoch, undefined, BaseWrapper_1.valueToInt); this.getEpochNumberOfBlock = (0, BaseWrapper_1.proxyCall)(this.contract.methods.getEpochNumberOfBlock, undefined, BaseWrapper_1.valueToInt); this.processedGroups = (0, BaseWrapper_1.proxyCall)(this.contract.methods.processedGroups, undefined, BaseWrapper_1.valueToString); this.isOnEpochProcess = (0, BaseWrapper_1.proxyCall)(this.contract.methods.isOnEpochProcess); this.isEpochProcessingStarted = (0, BaseWrapper_1.proxyCall)(this.contract.methods.isEpochProcessingStarted); this.isIndividualProcessing = (0, BaseWrapper_1.proxyCall)(this.contract.methods.isIndividualProcessing); this.isTimeForNextEpoch = (0, BaseWrapper_1.proxyCall)(this.contract.methods.isTimeForNextEpoch); this.getElectedAccounts = (0, BaseWrapper_1.proxyCall)(this.contract.methods.getElectedAccounts); this.getElectedSigners = (0, BaseWrapper_1.proxyCall)(this.contract.methods.getElectedSigners); this.getEpochProcessingStatus = (0, BaseWrapper_1.proxyCall)(this.contract.methods.epochProcessing, undefined, (result) => { return { status: parseInt(result.status), perValidatorReward: new bignumber_js_1.default(result.perValidatorReward), totalRewardsVoter: new bignumber_js_1.default(result.totalRewardsVoter), totalRewardsCommunity: new bignumber_js_1.default(result.totalRewardsCommunity), totalRewardsCarbonFund: new bignumber_js_1.default(result.totalRewardsCarbonFund), }; }); this.startNextEpochProcess = (0, BaseWrapper_1.proxySend)(this.connection, this.contract.methods.startNextEpochProcess); this.finishNextEpochProcess = (0, BaseWrapper_1.proxySend)(this.connection, this.contract.methods.finishNextEpochProcess); this.sendValidatorPayment = (0, BaseWrapper_1.proxySend)(this.connection, this.contract.methods.sendValidatorPayment); this.setToProcessGroups = (0, BaseWrapper_1.proxySend)(this.connection, this.contract.methods.setToProcessGroups); this.processGroups = (0, BaseWrapper_1.proxySend)(this.connection, this.contract.methods.processGroups); this.startNextEpochProcessTx = () => __awaiter(this, void 0, void 0, function* () { // check that the epoch process is not already started const isEpochProcessStarted = yield this.isOnEpochProcess(); if (isEpochProcessStarted) { console.warn('Epoch process has already started.'); return; } return this.startNextEpochProcess(); }); this.finishNextEpochProcessTx = () => __awaiter(this, void 0, void 0, function* () { const { groups, lessers, greaters } = yield this.getEpochGroupsAndSorting(); return this.finishNextEpochProcess(groups, lessers, greaters); }); this.processGroupsTx = () => __awaiter(this, void 0, void 0, function* () { const { groups, lessers, greaters } = yield this.getEpochGroupsAndSorting(); return this.processGroups(groups, lessers, greaters); }); this.getLessersAndGreaters = (groups) => __awaiter(this, void 0, void 0, function* () { const scoreManager = yield this.contracts.getScoreManager(); const election = yield this.contracts.getElection(); const processingStatusPromise = this.getEpochProcessingStatus(); const groupWithVotesPromise = election.getEligibleValidatorGroupsVotes(); const lessers = new Array(groups.length); const greaters = new Array(groups.length); const rewards = yield Promise.all(groups.map((group) => __awaiter(this, void 0, void 0, function* () { const groupScore = yield scoreManager.getGroupScore(group); return yield election.getGroupEpochRewards(group, (yield processingStatusPromise).totalRewardsVoter, groupScore); }))); const groupWithVotes = yield groupWithVotesPromise; const groupWithVotesMap = new Map(groupWithVotes.map((group) => [group.address, group])); const missingGroups = groups.filter((group) => !groupWithVotesMap.has(group)); const missingGroupsLoaded = yield Promise.all(missingGroups.map((group) => __awaiter(this, void 0, void 0, function* () { const votes = yield election.getTotalVotesForGroup(group); return { group, votes }; }))); for (const group of missingGroupsLoaded) { groupWithVotes.push({ address: group.group, votes: group.votes }); } for (let i = 0; i < groups.length; i++) { const reward = rewards[i]; // biome-ignore lint/style/useForOf: unsure why we need it do it this way for (let j = 0; j < groupWithVotes.length; j++) { if (groupWithVotes[j].address === groups[i]) { groupWithVotes[j].votes.plus(reward); break; } } groupWithVotes.sort((a, b) => (b.votes.gt(a.votes) ? 1 : b.votes.lt(a.votes) ? -1 : 0)); for (let j = 0; j < groupWithVotes.length; j++) { if (groupWithVotes[j].address === groups[i]) { greaters[i] = j === 0 ? base_1.NULL_ADDRESS : groupWithVotes[j - 1].address; lessers[i] = j === groupWithVotes.length - 1 ? base_1.NULL_ADDRESS : groupWithVotes[j + 1].address; break; } } } return [lessers, greaters]; }); this.getEpochGroupsAndSorting = () => __awaiter(this, void 0, void 0, function* () { const elected = yield this.getElectedAccounts(); const validators = yield this.contracts.getValidators(); const electedGroups = Array.from(new Set(yield Promise.all(elected.map((validator) => __awaiter(this, void 0, void 0, function* () { return validators.getMembershipInLastEpoch(validator); }))))); const groupProcessedEvents = yield this.contract.getPastEvents('GroupProcessed', { // We need +1 because events are emitted on the first block of the new epoch fromBlock: (yield this.getFirstBlockAtEpoch(yield this.getCurrentEpochNumber())) + 1, }); // Filter out groups that have been processed const groups = electedGroups.filter((group) => { return !groupProcessedEvents.some((event) => event.returnValues.group === group); }); const [lessers, greaters] = yield this.getLessersAndGreaters(groups); return { groups, lessers, greaters }; }); } get _contract() { return this.contract; } getConfig() { return __awaiter(this, void 0, void 0, function* () { const currentEpochNumber = yield this.getCurrentEpochNumber(); const epochDuration = yield this.epochDuration(); const isTimeForNextEpoch = yield this.isTimeForNextEpoch(); return { currentEpochNumber, epochDuration, isTimeForNextEpoch, }; }); } } exports.EpochManagerWrapper = EpochManagerWrapper; //# sourceMappingURL=EpochManager.js.map