@kyve/core-beta
Version:
🚀 The base KYVE node implementation.
76 lines (75 loc) • 3.84 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.saveLoadValidationBundle = void 0;
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const utils_1 = require("../../utils");
/**
* saveLoadValidationBundle loads the bundle from the local
* cache for validation with the proposed bundle. If there is
* an error loading the bundle from cache the node instantly votes
* with abstain and continues to try to load the bundle
*
* @method saveLoadValidationBundle
* @param {Node} this
* @param {number} updatedAt
* @return {Promise<DataItem[] | null>}
*/
async function saveLoadValidationBundle(updatedAt) {
return await (0, utils_1.callWithBackoffStrategy)(async () => {
await this.syncPoolState();
const unixNow = new bignumber_js_1.default(Date.now());
const unixIntervalEnd = new bignumber_js_1.default(this.pool.bundle_proposal.updated_at)
.plus(this.pool.data.upload_interval)
.multipliedBy(1000);
// check if new proposal is available in the meantime
if (parseInt(this.pool.bundle_proposal.updated_at) > updatedAt) {
return null;
}
// check if pool got inactive in the meantime
if (this.validateIsPoolActive()) {
return null;
}
// check if validator needs to upload
if (this.pool.bundle_proposal.next_uploader === this.staker &&
unixNow.gte(unixIntervalEnd)) {
return null;
}
// load bundle from current pool current index to proposed index
const proposalStartIndex = parseInt(this.pool.data.current_index);
const proposalTargetIndex = proposalStartIndex + parseInt(this.pool.bundle_proposal.bundle_size);
// attempt to load bundle from cache
const bundle = [];
// in order to get the same bundle for validation as the one
// proposed the bundle is loaded with the proposed heights
this.logger.debug(`Loading bundle from index ${proposalStartIndex} to index ${proposalTargetIndex}`);
for (let i = proposalStartIndex; i < proposalTargetIndex; i++) {
try {
// try to get the data item from local cache
this.logger.debug(`this.cacheProvider.get(${i.toString()})`);
const item = await this.cacheProvider.get(i.toString());
bundle.push(item);
}
catch {
// if a request data item can not be found abort and
// try again after a backoff time
throw new Error(`Requested bundle could not be loaded from cache yet.`);
}
}
this.logger.info(`Successfully loaded validation bundle from CacheProvider:${this.cacheProvider.name}`);
return (0, utils_1.standardizeJSON)(bundle);
}, { limitTimeoutMs: 5 * 60 * 1000, increaseByMs: 10 * 1000 }, async (err, ctx) => {
var _a;
this.logger.info(`Loading validation bundle from CacheProvider:${this.cacheProvider.name} was unsuccessful. Retrying in ${(ctx.nextTimeoutInMs / 1000).toFixed(2)}s ...`);
this.logger.debug((0, utils_1.standardizeJSON)(err));
// vote abstain if validation bundle could not be loaded from cache.
// With voting abstain the network knows that the node
// is still online but just could not vote
if (!((_a = this.pool.bundle_proposal) === null || _a === void 0 ? void 0 : _a.voters_abstain.includes(this.staker))) {
await this.voteBundleProposal(this.pool.bundle_proposal.storage_id, utils_1.VOTE.ABSTAIN);
}
});
}
exports.saveLoadValidationBundle = saveLoadValidationBundle;