priority. checkInputs. chainValue.

This commit is contained in:
Christopher Jeffrey 2016-07-01 23:49:52 -07:00
parent 4bf962638e
commit 27a8a83969
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
4 changed files with 76 additions and 46 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);
};
/**

View File

@ -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,