UNPKG

bitcore-node

Version:

A blockchain indexing node with extended capabilities using bitcore

146 lines 6.28 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.XrpBlockStorage = exports.XrpBlockModel = void 0; const Loggify_1 = require("../../../decorators/Loggify"); const logger_1 = __importDefault(require("../../../logger")); const baseBlock_1 = require("../../../models/baseBlock"); const events_1 = require("../../../models/events"); const transaction_1 = require("./transaction"); let XrpBlockModel = class XrpBlockModel extends baseBlock_1.BaseBlock { constructor(storage) { super(storage); } async onConnect() { super.onConnect(); } async addBlock(params) { const { block, chain, network } = params; const reorg = await this.handleReorg({ block, chain, network }); if (reorg) { return Promise.reject('reorg'); } return this.processBlock(params); } async processBlock(params) { const { chain, network, transactions, parentChain, forkHeight, initialSyncComplete, coins } = params; const blockOp = await this.getBlockOp(params); const convertedBlock = blockOp.updateOne.update.$set; const { height, timeNormalized, time } = convertedBlock; const previousBlock = await this.collection.findOne({ hash: convertedBlock.previousBlockHash, chain, network }); await this.collection.bulkWrite([blockOp]); if (previousBlock) { await this.collection.updateOne({ chain, network, hash: previousBlock.hash }, { $set: { nextBlockHash: convertedBlock.hash } }); logger_1.default.debug('Updating previous block.nextBlockHash %o', convertedBlock.hash); } await transaction_1.XrpTransactionStorage.batchImport({ txs: transactions, coins, blockHash: convertedBlock.hash, blockTime: new Date(time), blockTimeNormalized: new Date(timeNormalized), height, chain, network, parentChain, forkHeight, initialSyncComplete }); if (initialSyncComplete) { events_1.EventStorage.signalBlock(convertedBlock); } await this.collection.updateOne({ hash: convertedBlock.hash, chain, network }, { $set: { processed: true } }); } async getBlockOp(params) { const { block, chain, network } = params; const blockTime = block.time; const prevHash = block.previousBlockHash; const previousBlock = await this.collection.findOne({ hash: prevHash, chain, network }); const timeNormalized = (() => { const prevTime = previousBlock ? previousBlock.timeNormalized : null; if (prevTime && blockTime.getTime() <= prevTime.getTime()) { return new Date(prevTime.getTime() + 1); } else { return blockTime; } })(); const height = block.height; logger_1.default.debug('Setting blockheight: %o', height); return { updateOne: { filter: { hash: block.hash, chain, network }, update: { $set: { ...block, timeNormalized } }, upsert: true } }; } async handleReorg(params) { const { block, chain, network } = params; const prevHash = block.previousBlockHash; let localTip = await this.getLocalTip(params); if (block != null && localTip != null && (localTip.hash === prevHash || localTip.hash === block.hash)) { return false; } if (!localTip || localTip.height === 0) { return false; } if (block) { const prevBlock = await this.collection.findOne({ chain, network, hash: prevHash }); if (prevBlock) { localTip = prevBlock; } else { logger_1.default.error("Previous block isn't in the DB need to roll back until we have a block in common"); } logger_1.default.info(`Resetting tip to ${localTip.height - 1} %o`, { chain, network }); } const reorgOps = [ this.collection.deleteMany({ chain, network, height: { $gte: localTip.height } }), transaction_1.XrpTransactionStorage.collection.deleteMany({ chain, network, blockHeight: { $gte: localTip.height } }) ]; await Promise.all(reorgOps); logger_1.default.debug('Removed data from above blockHeight: %o', localTip.height); return localTip.hash !== prevHash; } _apiTransform(block, options) { const transform = { _id: block._id, chain: block.chain, network: block.network, hash: block.hash, height: block.height, size: block.size, time: block.time, timeNormalized: block.timeNormalized, previousBlockHash: block.previousBlockHash, nextBlockHash: block.nextBlockHash, reward: block.reward, transactionCount: block.transactionCount }; if (options && options.object) { return transform; } return JSON.stringify(transform); } }; exports.XrpBlockModel = XrpBlockModel; exports.XrpBlockModel = XrpBlockModel = __decorate([ Loggify_1.LoggifyClass ], XrpBlockModel); exports.XrpBlockStorage = new XrpBlockModel(); //# sourceMappingURL=block.js.map