/*! * mempoolentry.js - mempool entry object for bcoin * Copyright (c) 2014-2016, Christopher Jeffrey (MIT License). * https://github.com/bcoin-org/bcoin */ 'use strict'; var policy = require('../protocol/policy'); var util = require('../utils/util'); var Script = require('../script/script'); /** * Represents a mempool entry. * @exports MempoolEntry * @constructor * @param {Object} options * @param {TX} options.tx - Transaction in mempool. * @param {Number} options.height - Entry height. * @param {Number} options.priority - Entry priority. * @param {Number} options.ts - Entry time. * @param {Amount} options.value - Value of on-chain coins. * @property {TX} tx * @property {Number} height * @property {Number} priority * @property {Number} ts * @property {Amount} value */ function MempoolEntry(options) { if (!(this instanceof MempoolEntry)) return new MempoolEntry(options); this.tx = null; this.height = -1; this.size = 0; this.sigops = 0; this.priority = 0; this.fee = 0; this.ts = 0; this.value = 0; this.dependencies = false; if (options) this.fromOptions(options); } /** * Inject properties from options object. * @private * @param {Object} options */ MempoolEntry.prototype.fromOptions = function fromOptions(options) { this.tx = options.tx; this.height = options.height; this.size = options.size; this.sigops = options.sigops; this.priority = options.priority; this.fee = options.fee; this.ts = options.ts; this.value = options.value; this.dependencies = options.dependencies; return this; }; /** * Instantiate mempool entry from options. * @param {Object} options * @returns {MempoolEntry} */ MempoolEntry.fromOptions = function fromOptions(options) { return new MempoolEntry().fromOptions(options); }; /** * Inject properties from transaction. * @private * @param {TX} tx * @param {Number} height */ MempoolEntry.prototype.fromTX = function fromTX(tx, view, height) { var flags = Script.flags.STANDARD_VERIFY_FLAGS; var priority = tx.getPriority(view, height); var value = tx.getChainValue(view); var sigops = tx.getSigopsCost(view, flags); var dependencies = false; var size = tx.getVirtualSize(); var fee = tx.getFee(view); var i, input; for (i = 0; i < tx.inputs.length; i++) { input = tx.inputs[i]; if (view.getHeight(input) === -1) { dependencies = true; break; } } this.tx = tx; this.height = height; this.size = size; this.sigops = sigops; this.priority = priority; this.fee = fee; this.ts = util.now(); this.value = value; this.dependencies = dependencies; return this; }; /** * Create a mempool entry from a TX. * @param {TX} tx * @param {Number} height - Entry height. * @returns {MempoolEntry} */ MempoolEntry.fromTX = function fromTX(tx, view, height) { return new MempoolEntry().fromTX(tx, view, height); }; /** * Calculate priority, taking into account * the entry height delta, modified size, * and chain value. * @param {Number} height * @returns {Number} Priority. */ MempoolEntry.prototype.getPriority = function getPriority(height) { var heightDelta = height - this.height; var modSize = this.tx.getModifiedSize(this.size); var deltaPriority = (heightDelta * this.value) / modSize; var result = this.priority + Math.floor(deltaPriority); if (result < 0) result = 0; return result; }; /** * Get fee. * @returns {Amount} */ MempoolEntry.prototype.getFee = function getFee() { return this.fee; }; /** * Calculate fee rate. * @returns {Rate} */ MempoolEntry.prototype.getRate = function getRate() { return policy.getRate(this.size, this.fee); }; /** * Test whether the entry is free with * the current priority (calculated by * current height). * @param {Number} height * @returns {Boolean} */ MempoolEntry.prototype.isFree = function isFree(height) { var priority = this.getPriority(height); return priority > policy.FREE_THRESHOLD; }; /* * Expose */ module.exports = MempoolEntry;