miner/template: refactor options handling.
This commit is contained in:
parent
b0c2b89e79
commit
bfd7cc9266
@ -7,6 +7,8 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
|
var consensus = require('../protocol/consensus');
|
||||||
|
var BN = require('bn.js');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @exports mining/common
|
* @exports mining/common
|
||||||
@ -18,7 +20,7 @@ var common = exports;
|
|||||||
* Constants
|
* Constants
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var DIFF_TARGET = 0x00000000ffff0000000000000000000000000000000000000000000000000000;
|
var DIFF = 0x00000000ffff0000000000000000000000000000000000000000000000000000;
|
||||||
var B192 = 0x1000000000000000000000000000000000000000000000000;
|
var B192 = 0x1000000000000000000000000000000000000000000000000;
|
||||||
var B128 = 0x100000000000000000000000000000000;
|
var B128 = 0x100000000000000000000000000000000;
|
||||||
var B64 = 0x10000000000000000;
|
var B64 = 0x10000000000000000;
|
||||||
@ -30,7 +32,7 @@ var B0 = 0x1;
|
|||||||
* @returns {Buffer}
|
* @returns {Buffer}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exports.swap32 = function swap32(data) {
|
common.swap32 = function swap32(data) {
|
||||||
var i, field;
|
var i, field;
|
||||||
|
|
||||||
for (i = 0; i < data.length; i += 4) {
|
for (i = 0; i < data.length; i += 4) {
|
||||||
@ -43,14 +45,13 @@ exports.swap32 = function swap32(data) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Swap 32 bit endianness of uint256 (hex).
|
* Swap 32 bit endianness of uint256 (hex).
|
||||||
* @param {String} data
|
* @param {String} str
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exports.hswap32 = function hswap32(hex) {
|
common.swap32hex = function swap32hex(str) {
|
||||||
var data = new Buffer(hex, 'hex');
|
var data = new Buffer(str, 'hex');
|
||||||
exports.swap32(data)
|
return common.swap32(data).toString('hex');
|
||||||
return data.toString('hex');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,7 +61,7 @@ exports.hswap32 = function hswap32(hex) {
|
|||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exports.rcmp = function rcmp(a, b) {
|
common.rcmp = function rcmp(a, b) {
|
||||||
var i;
|
var i;
|
||||||
|
|
||||||
assert(a.length === b.length);
|
assert(a.length === b.length);
|
||||||
@ -81,7 +82,7 @@ exports.rcmp = function rcmp(a, b) {
|
|||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exports.double256 = function double256(target) {
|
common.double256 = function double256(target) {
|
||||||
var n = 0;
|
var n = 0;
|
||||||
var hi, lo;
|
var hi, lo;
|
||||||
|
|
||||||
@ -113,12 +114,48 @@ exports.double256 = function double256(target) {
|
|||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exports.getDifficulty = function getDifficulty(target) {
|
common.getDifficulty = function getDifficulty(target) {
|
||||||
var d = DIFF_TARGET;
|
var d = DIFF;
|
||||||
var n = exports.double256(target);
|
var n = common.double256(target);
|
||||||
|
|
||||||
if (n === 0)
|
if (n === 0)
|
||||||
return d;
|
return d;
|
||||||
|
|
||||||
if (n > d)
|
if (n > d)
|
||||||
return d;
|
return d;
|
||||||
|
|
||||||
return Math.floor(d / n);
|
return Math.floor(d / n);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get target from bits as a uint256le.
|
||||||
|
* @param {Number} bits
|
||||||
|
* @returns {Buffer}
|
||||||
|
*/
|
||||||
|
|
||||||
|
common.getTarget = function getTarget(bits) {
|
||||||
|
var target = consensus.fromCompact(bits);
|
||||||
|
|
||||||
|
if (target.isNeg())
|
||||||
|
throw new Error('Target is negative.');
|
||||||
|
|
||||||
|
if (target.cmpn(0) === 0)
|
||||||
|
throw new Error('Target is zero.');
|
||||||
|
|
||||||
|
return target.toArrayLike(Buffer, 'le', 32);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get bits from target.
|
||||||
|
* @param {Buffer} data
|
||||||
|
* @returns {Buffer}
|
||||||
|
*/
|
||||||
|
|
||||||
|
common.getBits = function getBits(data) {
|
||||||
|
var target = new BN(data, 'le');
|
||||||
|
|
||||||
|
if (target.cmpn(0) === 0)
|
||||||
|
throw new Error('Target is zero.');
|
||||||
|
|
||||||
|
return consensus.toCompact(target);
|
||||||
|
};
|
||||||
|
|||||||
@ -138,7 +138,7 @@ Miner.prototype._createBlock = co(function* createBlock(tip, address) {
|
|||||||
address: address,
|
address: address,
|
||||||
coinbaseFlags: this.options.coinbaseFlags,
|
coinbaseFlags: this.options.coinbaseFlags,
|
||||||
witness: this.chain.state.hasWitness(),
|
witness: this.chain.state.hasWitness(),
|
||||||
halvingInterval: this.network.halvingInterval,
|
interval: this.network.halvingInterval,
|
||||||
weight: this.options.reservedWeight,
|
weight: this.options.reservedWeight,
|
||||||
sigops: this.options.reservedSigops
|
sigops: this.options.reservedSigops
|
||||||
});
|
});
|
||||||
@ -146,11 +146,12 @@ Miner.prototype._createBlock = co(function* createBlock(tip, address) {
|
|||||||
this.assemble(attempt);
|
this.assemble(attempt);
|
||||||
|
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
'Created miner block (height=%d, weight=%d, fees=%d, txs=%s).',
|
'Created block template (height=%d, weight=%d, fees=%d, txs=%s, diff=%d).',
|
||||||
attempt.height,
|
attempt.height,
|
||||||
attempt.weight,
|
attempt.weight,
|
||||||
Amount.btc(attempt.fees),
|
Amount.btc(attempt.fees),
|
||||||
attempt.items.length + 1);
|
attempt.items.length + 1,
|
||||||
|
attempt.getDifficulty());
|
||||||
|
|
||||||
if (this.options.preverify) {
|
if (this.options.preverify) {
|
||||||
block = attempt.toBlock();
|
block = attempt.toBlock();
|
||||||
|
|||||||
@ -35,27 +35,127 @@ function BlockTemplate(options) {
|
|||||||
if (!(this instanceof BlockTemplate))
|
if (!(this instanceof BlockTemplate))
|
||||||
return new BlockTemplate(options);
|
return new BlockTemplate(options);
|
||||||
|
|
||||||
this.prevBlock = options.prevBlock;
|
this.prevBlock = encoding.NULL_HASH;
|
||||||
this.version = options.version;
|
this.version = 1;
|
||||||
this.height = options.height;
|
this.height = 0;
|
||||||
this.ts = options.ts;
|
this.ts = 0;
|
||||||
this.bits = options.bits;
|
this.bits = 0;
|
||||||
this.target = consensus.fromCompact(this.bits).toArrayLike(Buffer, 'le', 32);
|
this.target = encoding.ZERO_HASH;
|
||||||
this.locktime = options.locktime;
|
this.locktime = 0;
|
||||||
this.flags = options.flags;
|
this.flags = 0;
|
||||||
this.coinbaseFlags = options.coinbaseFlags;
|
this.coinbaseFlags = DUMMY;
|
||||||
this.witness = options.witness;
|
this.witness = false;
|
||||||
this.address = options.address;
|
this.address = new Address();
|
||||||
this.sigops = options.sigops;
|
this.sigops = 400;
|
||||||
this.weight = options.weight;
|
this.weight = 4000;
|
||||||
this.reward = consensus.getReward(this.height, options.halvingInterval);
|
this.interval = 210000;
|
||||||
|
this.fees = 0;
|
||||||
this.tree = new MerkleTree();
|
this.tree = new MerkleTree();
|
||||||
this.left = DUMMY;
|
this.left = DUMMY;
|
||||||
this.right = DUMMY;
|
this.right = DUMMY;
|
||||||
this.fees = 0;
|
|
||||||
this.items = [];
|
this.items = [];
|
||||||
|
|
||||||
|
if (options)
|
||||||
|
this.fromOptions(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject properties from options.
|
||||||
|
* @private
|
||||||
|
* @param {Object} options
|
||||||
|
* @returns {BlockTemplate}
|
||||||
|
*/
|
||||||
|
|
||||||
|
BlockTemplate.prototype.fromOptions = function fromOptions(options) {
|
||||||
|
assert(options);
|
||||||
|
|
||||||
|
if (options.prevBlock != null) {
|
||||||
|
assert(typeof options.prevBlock === 'string');
|
||||||
|
this.prevBlock = options.prevBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.version != null) {
|
||||||
|
assert(typeof options.version === 'number');
|
||||||
|
this.version = options.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.height != null) {
|
||||||
|
assert(typeof options.height === 'number');
|
||||||
|
this.height = options.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.ts != null) {
|
||||||
|
assert(typeof options.ts === 'number');
|
||||||
|
this.ts = options.ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.bits != null)
|
||||||
|
this.setBits(options.bits);
|
||||||
|
|
||||||
|
if (options.target != null)
|
||||||
|
this.setTarget(options.target);
|
||||||
|
|
||||||
|
if (options.locktime != null) {
|
||||||
|
assert(typeof options.locktime === 'number');
|
||||||
|
this.locktime = options.locktime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.flags != null) {
|
||||||
|
assert(typeof options.flags === 'number');
|
||||||
|
this.flags = options.flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.coinbaseFlags != null) {
|
||||||
|
assert(Buffer.isBuffer(options.coinbaseFlags));
|
||||||
|
this.coinbaseFlags = options.coinbaseFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.witness != null) {
|
||||||
|
assert(typeof options.witness === 'boolean');
|
||||||
|
this.witness = options.witness;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.address != null)
|
||||||
|
this.address.fromOptions(options.address);
|
||||||
|
|
||||||
|
if (options.sigops != null) {
|
||||||
|
assert(typeof options.sigops === 'number');
|
||||||
|
this.sigops = options.sigops;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.weight != null) {
|
||||||
|
assert(typeof options.weight === 'number');
|
||||||
|
this.weight = options.weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.interval != null) {
|
||||||
|
assert(typeof options.interval === 'number');
|
||||||
|
this.interval = options.interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.fees != null) {
|
||||||
|
assert(typeof options.fees === 'number');
|
||||||
|
this.fees = options.fees;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.items != null) {
|
||||||
|
assert(Array.isArray(options.items));
|
||||||
|
this.items = options.items;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate block template from options.
|
||||||
|
* @param {Object} options
|
||||||
|
* @returns {BlockTemplate}
|
||||||
|
*/
|
||||||
|
|
||||||
|
BlockTemplate.fromOptions = function fromOptions(options) {
|
||||||
|
return new BlockTemplate().fromOptions(options);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create witness commitment hash.
|
* Create witness commitment hash.
|
||||||
* @returns {Buffer}
|
* @returns {Buffer}
|
||||||
@ -82,13 +182,36 @@ BlockTemplate.prototype.getWitnessHash = function getWitnessHash() {
|
|||||||
return crypto.hash256(data);
|
return crypto.hash256(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the target (bits).
|
||||||
|
* @param {Number} bits
|
||||||
|
*/
|
||||||
|
|
||||||
|
BlockTemplate.prototype.setBits = function setBits(bits) {
|
||||||
|
assert(typeof bits === 'number');
|
||||||
|
this.bits = bits;
|
||||||
|
this.target = common.getTarget(bits);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the target (uint256le).
|
||||||
|
* @param {Buffer} target
|
||||||
|
*/
|
||||||
|
|
||||||
|
BlockTemplate.prototype.setTarget = function setTarget(target) {
|
||||||
|
assert(Buffer.isBuffer(target));
|
||||||
|
this.bits = common.getBits(target);
|
||||||
|
this.target = target;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the block reward.
|
* Calculate the block reward.
|
||||||
* @returns {Amount}
|
* @returns {Amount}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
BlockTemplate.prototype.getReward = function getReward() {
|
BlockTemplate.prototype.getReward = function getReward() {
|
||||||
return this.reward + this.fees;
|
var reward = consensus.getReward(this.height, this.interval);
|
||||||
|
return reward + this.fees;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -707,7 +707,7 @@ describe('Chain', function() {
|
|||||||
it('should fail to connect bad amount', co(function* () {
|
it('should fail to connect bad amount', co(function* () {
|
||||||
var job = yield cpu.createJob();
|
var job = yield cpu.createJob();
|
||||||
|
|
||||||
job.attempt.reward += 1;
|
job.attempt.fees += 1;
|
||||||
job.refresh();
|
job.refresh();
|
||||||
assert.equal(yield mineBlock(job), 'bad-cb-amount');
|
assert.equal(yield mineBlock(job), 'bad-cb-amount');
|
||||||
}));
|
}));
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user