@kyve/core-beta
Version:
🚀 The base KYVE node implementation.
73 lines (72 loc) • 4.03 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.saveBundleDownload = void 0;
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const utils_1 = require("../../utils");
/**
* saveBundleDownload downloads a bundle from the storage provider.
* The download should be aborted if the pool is not
* active anymore or a new bundle proposal has been found
* or the node is the current uploader and the upload interval
* has passed.
*
* If there is an error retrieving the bundle from the storage provider
* the node instantly votes with abstain and continues to try to retrieve
* the bundle.
*
* @method saveBundleDownload
* @param {Node} this
* @param {number} updatedAt
* @return {Promise<Buffer | null>}
*/
async function saveBundleDownload(updatedAt) {
return await (0, utils_1.callWithBackoffStrategy)(async () => {
var _a, _b, _c, _d;
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;
}
// get storage provider the proposed bundle was saved to
this.logger.debug(`storageProviderFactory(${(_b = (_a = this.pool.bundle_proposal) === null || _a === void 0 ? void 0 : _a.storage_provider_id) !== null && _b !== void 0 ? _b : 0}, $STORAGE_PRIV)`);
const storageProvider = await this.storageProviderFactory((_d = (_c = this.pool.bundle_proposal) === null || _c === void 0 ? void 0 : _c.storage_provider_id) !== null && _d !== void 0 ? _d : 0);
// calculate download timeout for storage provider
// the timeout should always be 20 seconds less than the upload interval
// so that the node still has enough time to vote abstain when the
// download timeout is reached
const downloadTimeoutSec = Math.max(0, parseInt(this.pool.data.upload_interval) - 20);
this.logger.debug(`this.storageProvider.retrieveBundle(${this.pool.bundle_proposal.storage_id},${downloadTimeoutSec * 1000})`);
const { storageData } = await storageProvider.retrieveBundle(this.pool.bundle_proposal.storage_id, downloadTimeoutSec * 1000);
this.m.storage_provider_retrieve_successful.inc();
this.logger.info(`Successfully downloaded bundle with id ${this.pool.bundle_proposal.storage_id} from StorageProvider:${storageProvider.name}`);
return storageData;
}, { limitTimeoutMs: 5 * 60 * 1000, increaseByMs: 10 * 1000 }, async (err, ctx) => {
var _a;
this.logger.info(`Retrieving bundle from StorageProvider was unsuccessful. Retrying in ${(ctx.nextTimeoutInMs / 1000).toFixed(2)}s ...`);
this.logger.debug((0, utils_1.standardizeJSON)(err));
this.m.storage_provider_retrieve_failed.inc();
// vote abstain if bundle could not be retrieved from storage
// provider. 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.saveBundleDownload = saveBundleDownload;