UNPKG

@kyve/core-beta

Version:

🚀 The base KYVE node implementation.

83 lines (82 loc) • 3.96 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.canPropose = void 0; const utils_1 = require("../../utils"); const INFINITY_LOOP = true; /** * canPropose checks if the node is able to propose the next * bundle proposal by calling a special chain query called "canPropose". * It runs indefinitely until the query returns a valid response * * @method canPropose * @param {Node} this * @param {number} updatedAt the last update time of the current bundle proposal * @return {Promise<boolean>} */ async function canPropose(updatedAt) { var _a; try { const canPropose = await (0, utils_1.callWithBackoffStrategy)(async () => { await this.syncPoolState(); // get the index from where the bundle should get created const fromIndex = parseInt(this.pool.data.current_index) + parseInt(this.pool.bundle_proposal.bundle_size); // abort if staker is the current uploader if (this.pool.bundle_proposal.next_uploader !== this.staker) { return { possible: false, reason: "Node is not next uploader of this bundle proposal", }; } // abort if a new bundle proposal was found if (parseInt(this.pool.bundle_proposal.updated_at) > updatedAt) { return { possible: false, reason: "New bundle proposal was found", }; } // loop until a valid response has been returned. The invalid // response here is the "upload interval not surpassed". If the query // returns an "upload interval not surpassed" that usually // means we have to wait for the next block in the blockchain // because the chain time only updates on every new block while (INFINITY_LOOP) { this.logger.debug(`this.lcd.kyve.query.v1beta1.canPropose({pool_id: ${this.poolId.toString()},staker: ${this.staker},proposer: ${this.client.account.address},from_index: ${fromIndex.toString()}})`); const canPropose = await this.lcd.kyve.query.v1beta1.canPropose({ pool_id: this.poolId.toString(), staker: this.staker, proposer: this.client.account.address, from_index: fromIndex.toString(), }); // wait until a new block with an updated block time has been // produced by the blockchain if (!canPropose.possible && canPropose.reason.endsWith("upload interval not surpassed")) { await (0, utils_1.sleep)(1000); continue; } return canPropose; } }, { limitTimeoutMs: 5 * 60 * 1000, increaseByMs: 10 * 1000 }, async (err, ctx) => { this.logger.info(`Requesting query canPropose was unsuccessful. Retrying in ${(ctx.nextTimeoutInMs / 1000).toFixed(2)}s ...`); this.logger.debug((0, utils_1.standardizeJSON)(err)); this.m.query_can_propose_failed.inc(); }); this.logger.debug(JSON.stringify(canPropose)); this.m.query_can_propose_successful.inc(); if (canPropose === null || canPropose === void 0 ? void 0 : canPropose.possible) { this.logger.info(`Can propose next bundle proposal`); return true; } else { this.logger.info(`Skipping proposal. Reason: ${(_a = canPropose === null || canPropose === void 0 ? void 0 : canPropose.reason) !== null && _a !== void 0 ? _a : "unknown"}`); return false; } } catch (err) { this.logger.error(`Failed to call canPropose`); this.logger.error((0, utils_1.standardizeJSON)(err)); return false; } } exports.canPropose = canPropose;