rpc/mempool: implement prioritisetransaction.
This commit is contained in:
parent
6f27b3fa3d
commit
68bba8621e
@ -708,6 +708,9 @@ RPC.prototype.getRawMempool = co(function* getRawMempool(args, help) {
|
||||
if (help || args.length > 1)
|
||||
throw new RPCError('getrawmempool ( verbose )');
|
||||
|
||||
if (!this.mempool)
|
||||
throw new RPCError('No mempool available.');
|
||||
|
||||
if (verbose) {
|
||||
hashes = this.mempool.getSnapshot();
|
||||
|
||||
@ -748,8 +751,11 @@ RPC.prototype.getTXOut = co(function* getTXOut(args, help) {
|
||||
if (!hash || index == null)
|
||||
throw new RPCError('Invalid outpoint.');
|
||||
|
||||
if (mempool)
|
||||
if (mempool) {
|
||||
if (!this.mempool)
|
||||
throw new RPCError('No mempool available.');
|
||||
coin = this.mempool.getCoin(hash, index);
|
||||
}
|
||||
|
||||
if (!coin)
|
||||
coin = yield this.chain.db.getCoin(hash, index);
|
||||
@ -1352,7 +1358,7 @@ RPC.prototype.prioritiseTransaction = co(function* prioritiseTransaction(args, h
|
||||
var valid = new Validator([args]);
|
||||
var hash = valid.hash(0);
|
||||
var pri = valid.num(1);
|
||||
var fee = valid.num(2);
|
||||
var fee = valid.i64(2);
|
||||
var entry;
|
||||
|
||||
if (help || args.length !== 3) {
|
||||
@ -1374,6 +1380,8 @@ RPC.prototype.prioritiseTransaction = co(function* prioritiseTransaction(args, h
|
||||
if (!entry)
|
||||
throw new RPCError('Transaction not in mempool.');
|
||||
|
||||
this.mempool.prioritise(entry, pri, fee);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
@ -1673,6 +1681,9 @@ RPC.prototype.signRawTransaction = co(function* signRawTransaction(args, help) {
|
||||
if (!data)
|
||||
throw new RPCError('Invalid hex string.');
|
||||
|
||||
if (!this.mempool)
|
||||
throw new RPCError('No mempool available.');
|
||||
|
||||
tx = MTX.fromRaw(data);
|
||||
tx.view = yield this.mempool.getSpentView(tx);
|
||||
|
||||
|
||||
@ -1953,6 +1953,29 @@ Mempool.prototype.getSize = function getSize() {
|
||||
return this.size;
|
||||
};
|
||||
|
||||
/**
|
||||
* Prioritise transaction.
|
||||
* @param {MempoolEntry} entry
|
||||
* @param {Number} pri
|
||||
* @param {Amount} fee
|
||||
*/
|
||||
|
||||
Mempool.prototype.prioritise = function _prioritise(entry, pri, fee) {
|
||||
if (-fee > entry.deltaFee)
|
||||
fee = -entry.deltaFee;
|
||||
|
||||
if (-pri < entry.priority)
|
||||
pri = -entry.priority;
|
||||
|
||||
this.updateAncestors(entry, preprioritise);
|
||||
|
||||
entry.priority += pri;
|
||||
entry.deltaFee += fee;
|
||||
entry.descFee += fee;
|
||||
|
||||
this.updateAncestors(entry, prioritise);
|
||||
};
|
||||
|
||||
/**
|
||||
* MempoolOptions
|
||||
* @alias module:mempool.MempoolOptions
|
||||
@ -2571,7 +2594,7 @@ function nop(parent, child) {
|
||||
}
|
||||
|
||||
function addFee(parent, child) {
|
||||
parent.descFee += child.fee;
|
||||
parent.descFee += child.deltaFee;
|
||||
parent.descSize += child.size;
|
||||
}
|
||||
|
||||
@ -2580,10 +2603,18 @@ function removeFee(parent, child) {
|
||||
parent.descSize -= child.descSize;
|
||||
}
|
||||
|
||||
function preprioritise(parent, child) {
|
||||
parent.descFee -= child.deltaFee;
|
||||
}
|
||||
|
||||
function prioritise(parent, child) {
|
||||
parent.descFee += child.deltaFee;
|
||||
}
|
||||
|
||||
function cmpRate(a, b) {
|
||||
var xf = a.fee;
|
||||
var xf = a.deltaFee;
|
||||
var xs = a.size;
|
||||
var yf = b.fee;
|
||||
var yf = b.deltaFee;
|
||||
var ys = b.size;
|
||||
var x, y;
|
||||
|
||||
@ -2609,7 +2640,7 @@ function cmpRate(a, b) {
|
||||
}
|
||||
|
||||
function useDesc(a) {
|
||||
var x = a.fee * a.descSize;
|
||||
var x = a.deltaFee * a.descSize;
|
||||
var y = a.descFee * a.size;
|
||||
return y > x;
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@ function MempoolEntry(options) {
|
||||
this.sigops = 0;
|
||||
this.priority = 0;
|
||||
this.fee = 0;
|
||||
this.deltaFee = 0;
|
||||
this.ts = 0;
|
||||
this.value = 0;
|
||||
this.dependencies = false;
|
||||
@ -63,6 +64,7 @@ MempoolEntry.prototype.fromOptions = function fromOptions(options) {
|
||||
this.sigops = options.sigops;
|
||||
this.priority = options.priority;
|
||||
this.fee = options.fee;
|
||||
this.deltaFee = options.deltaFee;
|
||||
this.ts = options.ts;
|
||||
this.value = options.value;
|
||||
this.dependencies = options.dependencies;
|
||||
@ -112,6 +114,7 @@ MempoolEntry.prototype.fromTX = function fromTX(tx, view, height) {
|
||||
this.sigops = sigops;
|
||||
this.priority = priority;
|
||||
this.fee = fee;
|
||||
this.deltaFee = fee;
|
||||
this.ts = util.now();
|
||||
this.value = value;
|
||||
this.dependencies = dependencies;
|
||||
@ -160,9 +163,9 @@ MempoolEntry.prototype.txid = function txid() {
|
||||
*/
|
||||
|
||||
MempoolEntry.prototype.getPriority = function getPriority(height) {
|
||||
var heightDelta = height - this.height;
|
||||
var deltaPriority = (heightDelta * this.value) / this.size;
|
||||
var result = this.priority + Math.floor(deltaPriority);
|
||||
var height = height - this.height;
|
||||
var priority = (height * this.value) / this.size;
|
||||
var result = this.priority + Math.floor(priority);
|
||||
if (result < 0)
|
||||
result = 0;
|
||||
return result;
|
||||
@ -177,6 +180,15 @@ MempoolEntry.prototype.getFee = function getFee() {
|
||||
return this.fee;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get delta fee.
|
||||
* @returns {Amount}
|
||||
*/
|
||||
|
||||
MempoolEntry.prototype.getDeltaFee = function getDeltaFee() {
|
||||
return this.deltaFee;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate fee rate.
|
||||
* @returns {Rate}
|
||||
@ -186,6 +198,15 @@ MempoolEntry.prototype.getRate = function getRate() {
|
||||
return policy.getRate(this.size, this.fee);
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate delta fee rate.
|
||||
* @returns {Rate}
|
||||
*/
|
||||
|
||||
MempoolEntry.prototype.getDeltaRate = function getDeltaRate() {
|
||||
return policy.getRate(this.size, this.deltaFee);
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate fee cumulative descendant rate.
|
||||
* @returns {Rate}
|
||||
@ -322,6 +343,7 @@ MempoolEntry.prototype.fromRaw = function fromRaw(data) {
|
||||
this.sigops = br.readU32();
|
||||
this.priority = br.readDouble();
|
||||
this.fee = br.readU64();
|
||||
this.deltaFee = this.fee;
|
||||
this.ts = br.readU32();
|
||||
this.value = br.readU64();
|
||||
this.dependencies = br.readU8() === 1;
|
||||
|
||||
@ -649,9 +649,9 @@ BlockEntry.fromTX = function fromTX(tx, view, attempt) {
|
||||
BlockEntry.fromEntry = function fromEntry(entry, attempt) {
|
||||
var item = new BlockEntry(entry.tx);
|
||||
item.fee = entry.getFee();
|
||||
item.rate = entry.getRate();
|
||||
item.rate = entry.getDeltaRate();
|
||||
item.priority = entry.getPriority(attempt.height);
|
||||
item.free = item.fee < policy.getMinFee(entry.size);
|
||||
item.free = entry.getDeltaFee() < policy.getMinFee(entry.size);
|
||||
item.sigops = entry.sigops;
|
||||
item.descRate = entry.getDescRate();
|
||||
return item;
|
||||
|
||||
@ -197,6 +197,50 @@ Validator.prototype.u64 = function u64(key, fallback) {
|
||||
return value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a value (as an int32).
|
||||
* @param {String} key
|
||||
* @param {Object?} fallback
|
||||
* @returns {Number|null}
|
||||
*/
|
||||
|
||||
Validator.prototype.i32 = function i32(key, fallback) {
|
||||
var value = this.num(key);
|
||||
|
||||
if (fallback === undefined)
|
||||
fallback = null;
|
||||
|
||||
if (value === null)
|
||||
return fallback;
|
||||
|
||||
if (value % 1 !== 0 || Math.abs(value) > 0x7fffffff)
|
||||
throw new Error(fmt(key) + ' must be an int32.');
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a value (as an int64).
|
||||
* @param {String} key
|
||||
* @param {Object?} fallback
|
||||
* @returns {Number|null}
|
||||
*/
|
||||
|
||||
Validator.prototype.i64 = function i64(key, fallback) {
|
||||
var value = this.num(key);
|
||||
|
||||
if (fallback === undefined)
|
||||
fallback = null;
|
||||
|
||||
if (value === null)
|
||||
return fallback;
|
||||
|
||||
if (value % 1 !== 0 || Math.abs(value) > 0x1fffffffffffff)
|
||||
throw new Error(fmt(key) + ' must be an int64.');
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a value (as a satoshi number or btc string).
|
||||
* @param {String} key
|
||||
|
||||
Loading…
Reference in New Issue
Block a user