UNPKG

@rsksmart/rif-storage-pinning

Version:

Application for providing your storage space to other to use in exchange of RIF Tokens

110 lines (109 loc) 5.14 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.collectDirectAddresses = exports.collectPinsClosure = void 0; const config_1 = __importDefault(require("config")); const parse_duration_1 = __importDefault(require("parse-duration")); const agreement_model_1 = __importDefault(require("./models/agreement.model")); const sequelize_1 = require("sequelize"); const logger_1 = require("./logger"); const communication_1 = require("./communication"); const definitions_1 = require("./definitions"); const errors_1 = require("./errors"); const direct_address_model_1 = __importDefault(require("./models/direct-address.model")); const utils_1 = require("./utils"); const logger = logger_1.loggingFactory('gc'); /** * This is a closure that garbage-collects pins of expired Agreements. * * When first detects an Agreement to have no funds it saves the block number at what it was detected. * Then after number of blocks specified for confirmations it actualy unpins the data. * * This is in order to handle case when reorg happens and the DepositFunds event is emitted in the * confirmation range. * * @param options */ function collectPinsClosure(options) { return (block) => __awaiter(this, void 0, void 0, function* () { var _a; logger.verbose('Running pinning GC'); const nonExpiredAgreements = yield agreement_model_1.default.findAll({ where: { expiredAtBlockNumber: null, isActive: true } }); for (const agreement of nonExpiredAgreements) { if (!agreement.hasSufficientFunds) { logger.info(`Marking agreement ${agreement.agreementReference} to be collected at block ${block.number}.`); agreement.expiredAtBlockNumber = block.number; yield agreement.save(); } } const agreementsToUnpins = yield agreement_model_1.default.findAll({ where: { expiredAtBlockNumber: { [sequelize_1.Op.lte]: block.number - config_1.default.get('blockchain.eventsEmitter.confirmations') }, isActive: true } }); for (const agreement of agreementsToUnpins) { if (agreement.hasSufficientFunds) { // Agreement received funds in meanwhile, lets continue! agreement.expiredAtBlockNumber = null; } else { // Agreement is still without funds! logger.info(`Unpinning agreement ${agreement.agreementReference}.`); try { yield ((_a = options === null || options === void 0 ? void 0 : options.manager) === null || _a === void 0 ? void 0 : _a.unpin(agreement.dataReference)); } catch (e) { if (e.code === errors_1.NotPinnedError.code) { logger.info(`Data reference ${agreement.dataReference} was already removed prior our GC run!`); } else { throw e; } } yield communication_1.broadcast(definitions_1.MessageCodesEnum.I_AGREEMENT_EXPIRED, { agreementReference: agreement.agreementReference }); agreement.isActive = false; } yield agreement.save(); } }); } exports.collectPinsClosure = collectPinsClosure; function collectDirectAddresses() { return () => __awaiter(this, void 0, void 0, function* () { logger.info('In collect Direct Addresses'); if (!config_1.default.has('directAddress.ttl')) { logger.error('ttl for "directAddress" not provided'); } const ttl = parse_duration_1.default(config_1.default.get('directAddress.ttl')); if (!ttl) { throw new Error('Invalid Direct Address ttl value'); } yield direct_address_model_1.default.destroy({ where: { createdAt: { [sequelize_1.Op.lte]: new Date(Date.now() - ttl) } } }); }); } exports.collectDirectAddresses = collectDirectAddresses; function default_1(options) { return utils_1.composeGc([ collectPinsClosure(options), collectDirectAddresses() ]); } exports.default = default_1;