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