priority. checkInputs. chainValue.
This commit is contained in:
parent
4bf962638e
commit
27a8a83969
@ -7,8 +7,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var utils = require('./utils');
|
||||
var assert = utils.assert;
|
||||
var assert = require('assert');
|
||||
|
||||
/**
|
||||
* An LRU cache, used for caching {@link ChainEntry}s.
|
||||
@ -22,15 +21,22 @@ function LRU(maxSize, getSize) {
|
||||
if (!(this instanceof LRU))
|
||||
return new LRU(maxSize, getSize);
|
||||
|
||||
this.data = {};
|
||||
this.size = 0;
|
||||
this.maxSize = maxSize;
|
||||
this.getSize = this._createGetSize(getSize);
|
||||
|
||||
this.data = {};
|
||||
this.size = 0;
|
||||
this.head = null;
|
||||
this.tail = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a getSize callback.
|
||||
* @private
|
||||
* @param {Number} size
|
||||
* @returns {Function}
|
||||
*/
|
||||
|
||||
LRU.prototype._createGetSize = function _createGetSize(size) {
|
||||
if (!size)
|
||||
return;
|
||||
|
||||
@ -1914,7 +1914,8 @@ MempoolEntry.fromOptions = function fromOptions(options) {
|
||||
*/
|
||||
|
||||
MempoolEntry.prototype.fromTX = function fromTX(tx, height) {
|
||||
var data = tx.getPriority(height);
|
||||
var priority = tx.getPriority(height);
|
||||
var value = tx.getChainValue(height);
|
||||
var dependencies = false;
|
||||
var size = tx.getVirtualSize();
|
||||
var fee = tx.getFee();
|
||||
@ -1930,9 +1931,9 @@ MempoolEntry.prototype.fromTX = function fromTX(tx, height) {
|
||||
this.tx = tx;
|
||||
this.height = height;
|
||||
this.size = size;
|
||||
this.priority = data.priority;
|
||||
this.priority = priority;
|
||||
this.fee = fee;
|
||||
this.chainValue = data.value;
|
||||
this.chainValue = value;
|
||||
this.ts = utils.now();
|
||||
this.count = 1;
|
||||
this.sizes = size;
|
||||
|
||||
@ -1266,9 +1266,9 @@ MTX.prototype.avoidFeeSniping = function avoidFeeSniping(height) {
|
||||
height = 0;
|
||||
|
||||
if ((Math.random() * 10 | 0) === 0)
|
||||
this.setLocktime(Math.max(0, height - (Math.random() * 100 | 0)));
|
||||
else
|
||||
this.setLocktime(height);
|
||||
height = Math.max(0, height - (Math.random() * 100 | 0));
|
||||
|
||||
this.setLocktime(height);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -1447,6 +1447,13 @@ TX.prototype.checkInputs = function checkInputs(spendHeight, ret) {
|
||||
input = this.inputs[i];
|
||||
coin = input.coin;
|
||||
|
||||
if (!coin) {
|
||||
// Note: don't trigger dos score here.
|
||||
ret.reason = 'bad-txns-inputs-missingorspent';
|
||||
ret.score = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (coin.coinbase && spendHeight != null) {
|
||||
if (spendHeight - coin.height < constants.tx.COINBASE_MATURITY) {
|
||||
ret.reason = 'bad-txns-premature-spend-of-coinbase';
|
||||
@ -1462,17 +1469,18 @@ TX.prototype.checkInputs = function checkInputs(spendHeight, ret) {
|
||||
}
|
||||
|
||||
total += coin.value;
|
||||
|
||||
if (total < 0 || total > constants.MAX_MONEY) {
|
||||
ret.reason = 'bad-txns-inputvalues-outofrange';
|
||||
ret.score = 100;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (total < 0 || total > constants.MAX_MONEY) {
|
||||
ret.reason = 'bad-txns-inputvalues-outofrange';
|
||||
ret.score = 100;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Overflows already checked in `isSane()`.
|
||||
value = this.getOutputValue();
|
||||
|
||||
if (value > total) {
|
||||
if (total < value) {
|
||||
ret.reason = 'bad-txns-in-belowout';
|
||||
ret.score = 100;
|
||||
return false;
|
||||
@ -1532,32 +1540,28 @@ TX.prototype.getModifiedSize = function getModifiedSize(size) {
|
||||
/**
|
||||
* Calculate the transaction priority.
|
||||
* @param {Number?} height - If not present, tx height
|
||||
* or mempool height will be used.
|
||||
* or network height will be used.
|
||||
* @param {Number?} size - Size to calculate priority
|
||||
* based on. If not present, modified size will be
|
||||
* calculated and used.
|
||||
* @returns {Object} data - Object containing
|
||||
* `priority` and `value`.
|
||||
* based on. If not present, virtual size will be used.
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
TX.prototype.getPriority = function getPriority(height, size) {
|
||||
var sum, i, input, age, value;
|
||||
var sum = 0;
|
||||
var i, input, age;
|
||||
|
||||
if (this.isCoinbase())
|
||||
return { value: 0, priority: 0 };
|
||||
return sum;
|
||||
|
||||
if (height == null) {
|
||||
height = this.height;
|
||||
if (height === -1)
|
||||
height = bcoin.network.get().height + 1;
|
||||
height = bcoin.network.get().height;
|
||||
}
|
||||
|
||||
if (size == null)
|
||||
size = this.maxSize();
|
||||
|
||||
sum = 0;
|
||||
value = 0;
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
input = this.inputs[i];
|
||||
|
||||
@ -1570,14 +1574,42 @@ TX.prototype.getPriority = function getPriority(height, size) {
|
||||
if (input.coin.height <= height) {
|
||||
age = height - input.coin.height;
|
||||
sum += input.coin.value * age;
|
||||
value += input.coin.value;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
value: value,
|
||||
priority: Math.floor(sum / size)
|
||||
};
|
||||
return Math.floor(sum / size);
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate the transaction's on-chain value.
|
||||
* @param {Number?} height
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
TX.prototype.getChainValue = function getChainValue(height) {
|
||||
var value = 0;
|
||||
var i, input;
|
||||
|
||||
if (this.isCoinbase())
|
||||
return value;
|
||||
|
||||
if (height == null)
|
||||
height = Infinity;
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
input = this.inputs[i];
|
||||
|
||||
if (!input.coin)
|
||||
continue;
|
||||
|
||||
if (input.coin.height === -1)
|
||||
continue;
|
||||
|
||||
if (input.coin.height <= height)
|
||||
value += input.coin.value;
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1586,24 +1618,15 @@ TX.prototype.getPriority = function getPriority(height, size) {
|
||||
* passed this test is most likely relayable
|
||||
* without a fee.
|
||||
* @param {Number?} height - If not present, tx
|
||||
* height or mempool height will be used.
|
||||
* height or network height will be used.
|
||||
* @param {Number?} size - If not present, modified
|
||||
* size will be calculated and used.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
TX.prototype.isFree = function isFree(height, size) {
|
||||
var data;
|
||||
|
||||
if (height == null) {
|
||||
height = this.height;
|
||||
if (height === -1)
|
||||
height = bcoin.network.get().height + 1;
|
||||
}
|
||||
|
||||
data = this.getPriority(height, size);
|
||||
|
||||
return data.priority > constants.tx.FREE_THRESHOLD;
|
||||
var priority = this.getPriority(height, size);
|
||||
return priority > constants.tx.FREE_THRESHOLD;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1852,7 +1875,7 @@ TX.prototype.inspect = function inspect() {
|
||||
minFee: utils.btc(this.getMinFee()),
|
||||
rate: utils.btc(this.getRate()),
|
||||
confirmations: this.getConfirmations(),
|
||||
priority: this.getPriority().priority.toString(10),
|
||||
priority: this.getPriority(),
|
||||
date: utils.date(this.ts || this.ps),
|
||||
block: this.block ? utils.revHex(this.block) : null,
|
||||
ts: this.ts,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user