UNPKG

bitcore-node

Version:

A blockchain indexing node with extended capabilities using bitcore

213 lines 9.69 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.XrpTransactionStorage = exports.XrpTransactionModel = void 0; const Loggify_1 = require("../../../decorators/Loggify"); const logger_1 = __importDefault(require("../../../logger")); const baseTransaction_1 = require("../../../models/baseTransaction"); const cache_1 = require("../../../models/cache"); const coin_1 = require("../../../models/coin"); const events_1 = require("../../../models/events"); const config_1 = require("../../../services/config"); const storage_1 = require("../../../services/storage"); const utils_1 = require("../../../utils"); let XrpTransactionModel = class XrpTransactionModel extends baseTransaction_1.BaseTransaction { constructor(storage = storage_1.Storage) { super(storage); } onConnect() { super.onConnect(); this.collection.createIndex({ chain: 1, network: 1, from: 1, nonce: 1 }, { background: true, sparse: true }); } async batchImport(params) { const txOps = await this.addTransactions({ ...params }); const coinOps = (await this.addCoins({ ...params })); const batchSize = config_1.Config.get().maxPoolSize; logger_1.default.debug('Writing Transactions: %o', txOps.length); await Promise.all((0, utils_1.partition)(txOps, txOps.length / batchSize).map(txBatch => this.collection.bulkWrite(txBatch.map(op => this.toMempoolSafeUpsert(op, 0 /* SpentHeightIndicators.minimum */)), { ordered: false }))); await Promise.all((0, utils_1.partition)(coinOps, coinOps.length / batchSize).map(coinBatch => coin_1.CoinStorage.collection.bulkWrite(coinBatch.map(op => this.toMempoolSafeUpsert(op, 0 /* SpentHeightIndicators.minimum */)), { ordered: false }))); if (params.initialSyncComplete) { await this.expireBalanceCache(coinOps); } // Create events for mempool txs if (params.height != undefined && params.height < 0 /* SpentHeightIndicators.minimum */) { for (let op of txOps) { const filter = op.updateOne.filter; const tx = { ...op.updateOne.update.$set, ...filter }; await events_1.EventStorage.signalTx(tx); } for (const coinOp of coinOps) { const coin = { ...coinOp.updateOne.filter, ...coinOp.updateOne.update.$set }; await events_1.EventStorage.signalAddressCoin({ address: coin.address, coin: { value: coin.value, address: coin.address, chain: params.chain, network: params.network, mintTxid: coin.mintTxid } }); } } } async expireBalanceCache(coinOps) { let batch = new Array(); for (const coinOp of coinOps) { const coin = { ...coinOp.updateOne.filter, ...coinOp.updateOne.update.$set }; const { address, chain, network } = coin; batch.push({ address, chain, network }); } for (const payload of batch) { const { address, chain, network } = payload; const lowerAddress = address.toLowerCase(); const cacheKey = `getBalanceForAddress-${chain}-${network}-${lowerAddress}`; await cache_1.CacheStorage.expire(cacheKey); } } async addTransactions(params) { let { blockTimeNormalized, chain, height, network, parentChain, forkHeight } = params; if (parentChain && forkHeight && height != undefined && height < forkHeight) { const parentTxs = await exports.XrpTransactionStorage.collection .find({ blockHeight: height, chain: parentChain, network }) .toArray(); return parentTxs.map(parentTx => { return { updateOne: { filter: { txid: parentTx.txid, chain, network }, update: { $set: { ...parentTx, wallets: new Array() } }, upsert: true, forceServerObjectId: true } }; }); } else { return Promise.all(params.txs.map(async (tx) => { const { txid, wallets } = tx; return { updateOne: { filter: { txid, chain, network }, update: { $set: { ...tx, blockTimeNormalized: tx.blockTimeNormalized || blockTimeNormalized, wallets } }, upsert: true, forceServerObjectId: true } }; })); } } async addCoins(params) { let { chain, height, network, parentChain, forkHeight } = params; if (parentChain && forkHeight && height != undefined && height < forkHeight) { const parentChainCoins = await coin_1.CoinStorage.collection .find({ blockHeight: height, chain: parentChain, network }) .toArray(); return parentChainCoins.map((coin) => { const { mintTxid } = coin; return { updateOne: { filter: { mintTxid, mintIndex: coin.mintIndex, chain, network }, update: { $set: { ...coin, wallets: [] } }, upsert: true, forceServerObjectId: true } }; }); } else { return params.coins.map((coin) => { const { mintTxid, wallets, address } = coin; return { updateOne: { filter: { mintTxid, mintIndex: coin.mintIndex, chain, network }, update: { $set: { chain, network, address, mintHeight: coin.mintHeight || height, coinbase: coin.coinbase, value: coin.value }, $setOnInsert: { wallets } }, upsert: true, forceServerObjectId: true } }; }); } } getTransactions(params) { let originalQuery = params.query; const { query, options } = storage_1.Storage.getFindOptions(this, params.options); const finalQuery = Object.assign({}, originalQuery, query); return this.collection.find(finalQuery, options).addCursorFlag('noCursorTimeout', true); } _apiTransform(tx, options) { const transaction = { txid: tx.txid || '', network: tx.network || '', chain: tx.chain || '', blockHeight: (0, utils_1.valueOrDefault)(tx.blockHeight, -1), blockHash: tx.blockHash || '', blockTime: tx.blockTime ? tx.blockTime.toISOString() : '', blockTimeNormalized: tx.blockTimeNormalized ? tx.blockTimeNormalized.toISOString() : '', fee: (0, utils_1.valueOrDefault)(tx.fee, -1), value: (0, utils_1.valueOrDefault)(tx.value, -1), from: tx.from || '', nonce: (0, utils_1.valueOrDefault)(tx.nonce, -1), to: (0, utils_1.valueOrDefault)(tx.to, ''), currency: (0, utils_1.valueOrDefault)(tx.currency, 'XRP'), invoiceID: (0, utils_1.valueOrDefault)(tx.invoiceID, '') }; if (options && options.object) { return transaction; } return JSON.stringify(transaction); } }; exports.XrpTransactionModel = XrpTransactionModel; exports.XrpTransactionModel = XrpTransactionModel = __decorate([ Loggify_1.LoggifyClass ], XrpTransactionModel); exports.XrpTransactionStorage = new XrpTransactionModel(); //# sourceMappingURL=transaction.js.map