net/miner/hd: classify.
This commit is contained in:
parent
daa55a05bc
commit
280d5d38e5
1042
lib/hd/mnemonic.js
1042
lib/hd/mnemonic.js
File diff suppressed because it is too large
Load Diff
1294
lib/hd/private.js
1294
lib/hd/private.js
File diff suppressed because it is too large
Load Diff
963
lib/hd/public.js
963
lib/hd/public.js
File diff suppressed because it is too large
Load Diff
@ -14,15 +14,9 @@ const StaticWriter = require('bufio/lib/staticwriter');
|
||||
const TX = require('../primitives/tx');
|
||||
|
||||
/**
|
||||
* Mempool Entry
|
||||
* Represents a mempool entry.
|
||||
* @alias module:mempool.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.time - Entry time.
|
||||
* @param {Amount} options.value - Value of on-chain coins.
|
||||
* @property {TX} tx
|
||||
* @property {Number} height
|
||||
* @property {Number} priority
|
||||
@ -30,338 +24,351 @@ const TX = require('../primitives/tx');
|
||||
* @property {Amount} value
|
||||
*/
|
||||
|
||||
function MempoolEntry(options) {
|
||||
if (!(this instanceof MempoolEntry))
|
||||
return new MempoolEntry(options);
|
||||
class MempoolEntry {
|
||||
/**
|
||||
* Create a mempool entry.
|
||||
* @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.time - Entry time.
|
||||
* @param {Amount} options.value - Value of on-chain coins.
|
||||
*/
|
||||
|
||||
this.tx = null;
|
||||
this.height = -1;
|
||||
this.size = 0;
|
||||
this.sigops = 0;
|
||||
this.priority = 0;
|
||||
this.fee = 0;
|
||||
this.deltaFee = 0;
|
||||
this.time = 0;
|
||||
this.value = 0;
|
||||
this.coinbase = false;
|
||||
this.dependencies = false;
|
||||
this.descFee = 0;
|
||||
this.descSize = 0;
|
||||
constructor(options) {
|
||||
this.tx = null;
|
||||
this.height = -1;
|
||||
this.size = 0;
|
||||
this.sigops = 0;
|
||||
this.priority = 0;
|
||||
this.fee = 0;
|
||||
this.deltaFee = 0;
|
||||
this.time = 0;
|
||||
this.value = 0;
|
||||
this.coinbase = false;
|
||||
this.dependencies = false;
|
||||
this.descFee = 0;
|
||||
this.descSize = 0;
|
||||
|
||||
if (options)
|
||||
this.fromOptions(options);
|
||||
if (options)
|
||||
this.fromOptions(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject properties from options object.
|
||||
* @private
|
||||
* @param {Object} options
|
||||
*/
|
||||
|
||||
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.deltaFee = options.deltaFee;
|
||||
this.time = options.time;
|
||||
this.value = options.value;
|
||||
this.coinbase = options.coinbase;
|
||||
this.dependencies = options.dependencies;
|
||||
this.descFee = options.descFee;
|
||||
this.descSize = options.descSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate mempool entry from options.
|
||||
* @param {Object} options
|
||||
* @returns {MempoolEntry}
|
||||
*/
|
||||
|
||||
static fromOptions(options) {
|
||||
return new this().fromOptions(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject properties from transaction.
|
||||
* @private
|
||||
* @param {TX} tx
|
||||
* @param {Number} height
|
||||
*/
|
||||
|
||||
fromTX(tx, view, height) {
|
||||
const flags = Script.flags.STANDARD_VERIFY_FLAGS;
|
||||
const value = tx.getChainValue(view);
|
||||
const sigops = tx.getSigopsCost(view, flags);
|
||||
const size = tx.getSigopsSize(sigops);
|
||||
const priority = tx.getPriority(view, height, size);
|
||||
const fee = tx.getFee(view);
|
||||
|
||||
let dependencies = false;
|
||||
let coinbase = false;
|
||||
|
||||
for (const {prevout} of tx.inputs) {
|
||||
if (view.isCoinbase(prevout))
|
||||
coinbase = true;
|
||||
|
||||
if (view.getHeight(prevout) === -1)
|
||||
dependencies = true;
|
||||
}
|
||||
|
||||
this.tx = tx;
|
||||
this.height = height;
|
||||
this.size = size;
|
||||
this.sigops = sigops;
|
||||
this.priority = priority;
|
||||
this.fee = fee;
|
||||
this.deltaFee = fee;
|
||||
this.time = util.now();
|
||||
this.value = value;
|
||||
this.coinbase = coinbase;
|
||||
this.dependencies = dependencies;
|
||||
this.descFee = fee;
|
||||
this.descSize = size;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mempool entry from a TX.
|
||||
* @param {TX} tx
|
||||
* @param {Number} height - Entry height.
|
||||
* @returns {MempoolEntry}
|
||||
*/
|
||||
|
||||
static fromTX(tx, view, height) {
|
||||
return new this().fromTX(tx, view, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate transaction hash.
|
||||
* @param {String?} enc
|
||||
* @returns {Hash}
|
||||
*/
|
||||
|
||||
hash(enc) {
|
||||
return this.tx.hash(enc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate reverse transaction hash.
|
||||
* @returns {Hash}
|
||||
*/
|
||||
|
||||
txid() {
|
||||
return this.tx.txid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate priority, taking into account
|
||||
* the entry height delta, modified size,
|
||||
* and chain value.
|
||||
* @param {Number} height
|
||||
* @returns {Number} Priority.
|
||||
*/
|
||||
|
||||
getPriority(height) {
|
||||
const delta = height - this.height;
|
||||
const priority = (delta * this.value) / this.size;
|
||||
|
||||
let result = this.priority + Math.floor(priority);
|
||||
|
||||
if (result < 0)
|
||||
result = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get fee.
|
||||
* @returns {Amount}
|
||||
*/
|
||||
|
||||
getFee() {
|
||||
return this.fee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get delta fee.
|
||||
* @returns {Amount}
|
||||
*/
|
||||
|
||||
getDeltaFee() {
|
||||
return this.deltaFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate fee rate.
|
||||
* @returns {Rate}
|
||||
*/
|
||||
|
||||
getRate() {
|
||||
return policy.getRate(this.size, this.fee);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate delta fee rate.
|
||||
* @returns {Rate}
|
||||
*/
|
||||
|
||||
getDeltaRate() {
|
||||
return policy.getRate(this.size, this.deltaFee);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate fee cumulative descendant rate.
|
||||
* @returns {Rate}
|
||||
*/
|
||||
|
||||
getDescRate() {
|
||||
return policy.getRate(this.descSize, this.descFee);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the memory usage of a transaction.
|
||||
* Note that this only calculates the JS heap
|
||||
* size. Sizes of buffers are ignored (the v8
|
||||
* heap is what we care most about). All numbers
|
||||
* are based on the output of v8 heap snapshots
|
||||
* of TX objects.
|
||||
* @returns {Number} Usage in bytes.
|
||||
*/
|
||||
|
||||
memUsage() {
|
||||
const tx = this.tx;
|
||||
let total = 0;
|
||||
|
||||
total += 176; // mempool entry
|
||||
total += 48; // coinbase
|
||||
total += 48; // dependencies
|
||||
|
||||
total += 208; // tx
|
||||
total += 80; // _hash
|
||||
total += 88; // _hhash
|
||||
total += 80; // _raw
|
||||
total += 80; // _whash
|
||||
total += 48; // mutable
|
||||
|
||||
total += 32; // input array
|
||||
|
||||
for (const input of tx.inputs) {
|
||||
total += 120; // input
|
||||
total += 104; // prevout
|
||||
total += 88; // prevout hash
|
||||
|
||||
total += 40; // script
|
||||
total += 80; // script raw buffer
|
||||
total += 32; // script code array
|
||||
total += input.script.code.length * 40; // opcodes
|
||||
|
||||
for (const op of input.script.code) {
|
||||
if (op.data)
|
||||
total += 80; // op buffers
|
||||
}
|
||||
|
||||
total += 96; // witness
|
||||
total += 32; // witness items
|
||||
total += input.witness.items.length * 80; // witness buffers
|
||||
}
|
||||
|
||||
total += 32; // output array
|
||||
|
||||
for (const output of tx.outputs) {
|
||||
total += 104; // output
|
||||
total += 40; // script
|
||||
total += 80; // script raw buffer
|
||||
total += 32; // script code array
|
||||
total += output.script.code.length * 40; // opcodes
|
||||
|
||||
for (const op of output.script.code) {
|
||||
if (op.data)
|
||||
total += 80; // op buffers
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the entry is free with
|
||||
* the current priority (calculated by
|
||||
* current height).
|
||||
* @param {Number} height
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
isFree(height) {
|
||||
const priority = this.getPriority(height);
|
||||
return priority > policy.FREE_THRESHOLD;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get entry serialization size.
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
getSize() {
|
||||
return this.tx.getSize() + 42;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize entry to a buffer.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
toRaw() {
|
||||
const bw = new StaticWriter(this.getSize());
|
||||
bw.writeBytes(this.tx.toRaw());
|
||||
bw.writeU32(this.height);
|
||||
bw.writeU32(this.size);
|
||||
bw.writeU32(this.sigops);
|
||||
bw.writeDouble(this.priority);
|
||||
bw.writeU64(this.fee);
|
||||
bw.writeU32(this.time);
|
||||
bw.writeU64(this.value);
|
||||
bw.writeU8(this.coinbase ? 1 : 0);
|
||||
bw.writeU8(this.dependencies ? 1 : 0);
|
||||
return bw.render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
* @returns {MempoolEntry}
|
||||
*/
|
||||
|
||||
fromRaw(data) {
|
||||
const br = new BufferReader(data);
|
||||
this.tx = TX.fromReader(br);
|
||||
this.height = br.readU32();
|
||||
this.size = br.readU32();
|
||||
this.sigops = br.readU32();
|
||||
this.priority = br.readDouble();
|
||||
this.fee = br.readU64();
|
||||
this.deltaFee = this.fee;
|
||||
this.time = br.readU32();
|
||||
this.value = br.readU64();
|
||||
this.coinbase = br.readU8() === 1;
|
||||
this.dependencies = br.readU8() === 1;
|
||||
this.descFee = this.fee;
|
||||
this.descSize = this.size;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate entry from serialized data.
|
||||
* @param {Buffer} data
|
||||
* @returns {MempoolEntry}
|
||||
*/
|
||||
|
||||
static fromRaw(data) {
|
||||
return new this().fromRaw(data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.deltaFee = options.deltaFee;
|
||||
this.time = options.time;
|
||||
this.value = options.value;
|
||||
this.coinbase = options.coinbase;
|
||||
this.dependencies = options.dependencies;
|
||||
this.descFee = options.descFee;
|
||||
this.descSize = options.descSize;
|
||||
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) {
|
||||
const flags = Script.flags.STANDARD_VERIFY_FLAGS;
|
||||
const value = tx.getChainValue(view);
|
||||
const sigops = tx.getSigopsCost(view, flags);
|
||||
const size = tx.getSigopsSize(sigops);
|
||||
const priority = tx.getPriority(view, height, size);
|
||||
const fee = tx.getFee(view);
|
||||
|
||||
let dependencies = false;
|
||||
let coinbase = false;
|
||||
|
||||
for (const {prevout} of tx.inputs) {
|
||||
if (view.isCoinbase(prevout))
|
||||
coinbase = true;
|
||||
|
||||
if (view.getHeight(prevout) === -1)
|
||||
dependencies = true;
|
||||
}
|
||||
|
||||
this.tx = tx;
|
||||
this.height = height;
|
||||
this.size = size;
|
||||
this.sigops = sigops;
|
||||
this.priority = priority;
|
||||
this.fee = fee;
|
||||
this.deltaFee = fee;
|
||||
this.time = util.now();
|
||||
this.value = value;
|
||||
this.coinbase = coinbase;
|
||||
this.dependencies = dependencies;
|
||||
this.descFee = fee;
|
||||
this.descSize = size;
|
||||
|
||||
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 transaction hash.
|
||||
* @param {String?} enc
|
||||
* @returns {Hash}
|
||||
*/
|
||||
|
||||
MempoolEntry.prototype.hash = function hash(enc) {
|
||||
return this.tx.hash(enc);
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate reverse transaction hash.
|
||||
* @returns {Hash}
|
||||
*/
|
||||
|
||||
MempoolEntry.prototype.txid = function txid() {
|
||||
return this.tx.txid();
|
||||
};
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
const delta = height - this.height;
|
||||
const priority = (delta * this.value) / this.size;
|
||||
let result = this.priority + Math.floor(priority);
|
||||
if (result < 0)
|
||||
result = 0;
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get fee.
|
||||
* @returns {Amount}
|
||||
*/
|
||||
|
||||
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}
|
||||
*/
|
||||
|
||||
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}
|
||||
*/
|
||||
|
||||
MempoolEntry.prototype.getDescRate = function getDescRate() {
|
||||
return policy.getRate(this.descSize, this.descFee);
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate the memory usage of a transaction.
|
||||
* Note that this only calculates the JS heap
|
||||
* size. Sizes of buffers are ignored (the v8
|
||||
* heap is what we care most about). All numbers
|
||||
* are based on the output of v8 heap snapshots
|
||||
* of TX objects.
|
||||
* @returns {Number} Usage in bytes.
|
||||
*/
|
||||
|
||||
MempoolEntry.prototype.memUsage = function memUsage() {
|
||||
const tx = this.tx;
|
||||
let total = 0;
|
||||
|
||||
total += 176; // mempool entry
|
||||
total += 48; // coinbase
|
||||
total += 48; // dependencies
|
||||
|
||||
total += 208; // tx
|
||||
total += 80; // _hash
|
||||
total += 88; // _hhash
|
||||
total += 80; // _raw
|
||||
total += 80; // _whash
|
||||
total += 48; // mutable
|
||||
|
||||
total += 32; // input array
|
||||
|
||||
for (const input of tx.inputs) {
|
||||
total += 120; // input
|
||||
total += 104; // prevout
|
||||
total += 88; // prevout hash
|
||||
|
||||
total += 40; // script
|
||||
total += 80; // script raw buffer
|
||||
total += 32; // script code array
|
||||
total += input.script.code.length * 40; // opcodes
|
||||
|
||||
for (const op of input.script.code) {
|
||||
if (op.data)
|
||||
total += 80; // op buffers
|
||||
}
|
||||
|
||||
total += 96; // witness
|
||||
total += 32; // witness items
|
||||
total += input.witness.items.length * 80; // witness buffers
|
||||
}
|
||||
|
||||
total += 32; // output array
|
||||
|
||||
for (const output of tx.outputs) {
|
||||
total += 104; // output
|
||||
total += 40; // script
|
||||
total += 80; // script raw buffer
|
||||
total += 32; // script code array
|
||||
total += output.script.code.length * 40; // opcodes
|
||||
|
||||
for (const op of output.script.code) {
|
||||
if (op.data)
|
||||
total += 80; // op buffers
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
const priority = this.getPriority(height);
|
||||
return priority > policy.FREE_THRESHOLD;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get entry serialization size.
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
MempoolEntry.prototype.getSize = function getSize() {
|
||||
return this.tx.getSize() + 42;
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize entry to a buffer.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
MempoolEntry.prototype.toRaw = function toRaw() {
|
||||
const bw = new StaticWriter(this.getSize());
|
||||
bw.writeBytes(this.tx.toRaw());
|
||||
bw.writeU32(this.height);
|
||||
bw.writeU32(this.size);
|
||||
bw.writeU32(this.sigops);
|
||||
bw.writeDouble(this.priority);
|
||||
bw.writeU64(this.fee);
|
||||
bw.writeU32(this.time);
|
||||
bw.writeU64(this.value);
|
||||
bw.writeU8(this.coinbase ? 1 : 0);
|
||||
bw.writeU8(this.dependencies ? 1 : 0);
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
* @returns {MempoolEntry}
|
||||
*/
|
||||
|
||||
MempoolEntry.prototype.fromRaw = function fromRaw(data) {
|
||||
const br = new BufferReader(data);
|
||||
this.tx = TX.fromReader(br);
|
||||
this.height = br.readU32();
|
||||
this.size = br.readU32();
|
||||
this.sigops = br.readU32();
|
||||
this.priority = br.readDouble();
|
||||
this.fee = br.readU64();
|
||||
this.deltaFee = this.fee;
|
||||
this.time = br.readU32();
|
||||
this.value = br.readU64();
|
||||
this.coinbase = br.readU8() === 1;
|
||||
this.dependencies = br.readU8() === 1;
|
||||
this.descFee = this.fee;
|
||||
this.descSize = this.size;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate entry from serialized data.
|
||||
* @param {Buffer} data
|
||||
* @returns {MempoolEntry}
|
||||
*/
|
||||
|
||||
MempoolEntry.fromRaw = function fromRaw(data) {
|
||||
return new MempoolEntry().fromRaw(data);
|
||||
};
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
5402
lib/net/packets.js
5402
lib/net/packets.js
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user