rpc: more mining nonsense.
This commit is contained in:
parent
6598245486
commit
061548f2ac
513
lib/http/rpc.js
513
lib/http/rpc.js
@ -12,6 +12,7 @@ var crypto = require('../crypto/crypto');
|
||||
var assert = utils.assert;
|
||||
var constants = bcoin.constants;
|
||||
var NetworkAddress = require('../primitives/netaddress');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var fs;
|
||||
|
||||
try {
|
||||
@ -24,6 +25,8 @@ function RPC(node) {
|
||||
if (!(this instanceof RPC))
|
||||
return new RPC(node);
|
||||
|
||||
EventEmitter.call(this);
|
||||
|
||||
this.node = node;
|
||||
this.network = node.network;
|
||||
this.chain = node.chain;
|
||||
@ -39,12 +42,13 @@ function RPC(node) {
|
||||
this.mining = false;
|
||||
this.proclimit = 0;
|
||||
|
||||
this.prevBlock = null;
|
||||
this.currentBlock = null;
|
||||
this.lastTX = 0;
|
||||
this.start = 0;
|
||||
this.blockStart = 0;
|
||||
this._boundChain = false;
|
||||
}
|
||||
|
||||
utils.inherits(RPC, EventEmitter);
|
||||
|
||||
RPC.prototype.execute = function execute(json, callback) {
|
||||
switch (json.method) {
|
||||
case 'stop':
|
||||
@ -1385,51 +1389,46 @@ RPC.prototype.verifychain = function verifychain(args, callback) {
|
||||
* Mining
|
||||
*/
|
||||
|
||||
RPC.prototype.getwork = function getwork(args, callback, force) {
|
||||
var self = this;
|
||||
var i, data, abbr, field, block, header;
|
||||
RPC.prototype._submitwork = function getwork(data, callback) {
|
||||
var data, block, header;
|
||||
|
||||
callback = this.locker.lock(getwork, [args, callback], force);
|
||||
if (data.length !== 128)
|
||||
return callback(new RPCError('Invalid parameter.'));
|
||||
|
||||
if (!callback)
|
||||
return;
|
||||
if (!this.currentBlock)
|
||||
return this._getwork(callback);
|
||||
|
||||
if (args.length > 1)
|
||||
return callback(new RPCError('getwork ( "data" )'));
|
||||
data = data.slice(0, 80);
|
||||
|
||||
if (args.length === 1 && this.currentBlock) {
|
||||
if (!utils.isHex(args[0]))
|
||||
return callback(new RPCError('Invalid parameter.'));
|
||||
reverseEndian(data);
|
||||
|
||||
if (args[0].length !== 256)
|
||||
return callback(new RPCError('Invalid parameter.'));
|
||||
header = bcoin.headers.fromAbbr(data);
|
||||
block = this.currentBlock.block;
|
||||
|
||||
data = new Buffer(args[0], 'hex').slice(0, 80);
|
||||
reverseEndian(data);
|
||||
|
||||
header = bcoin.headers.fromAbbr(data);
|
||||
block = this.currentBlock.block;
|
||||
|
||||
this._clearBlock();
|
||||
|
||||
if (header.prevBlock !== block.prevBlock)
|
||||
return self.getwork([], callback, true);
|
||||
|
||||
block.nonce = header.nonce;
|
||||
block.ts = header.ts;
|
||||
block.mutable = false;
|
||||
block.txs[0].mutable = false;
|
||||
|
||||
return this.chain.add(block, function(err) {
|
||||
if (err) {
|
||||
if (err.reason)
|
||||
return callback(new RPCError(err.reason));
|
||||
return callback(err);
|
||||
}
|
||||
return self.getwork([], callback, true);
|
||||
});
|
||||
if (header.prevBlock !== block.prevBlock
|
||||
|| header.merkleRoot !== block.merkleRoot
|
||||
|| header.bits !== block.bits) {
|
||||
return callback(null, false);
|
||||
}
|
||||
|
||||
block.nonce = header.nonce;
|
||||
block.ts = header.ts;
|
||||
block.mutable = false;
|
||||
block.txs[0].mutable = false;
|
||||
|
||||
return this.chain.add(block, function(err) {
|
||||
if (err) {
|
||||
if (err.type === 'VerifyError')
|
||||
return callback(null, false);
|
||||
return callback(err);
|
||||
}
|
||||
return callback(null, true);
|
||||
});
|
||||
};
|
||||
|
||||
RPC.prototype._getwork = function getwork(callback) {
|
||||
var i, data, abbr;
|
||||
|
||||
this._createBlock(function(err, attempt) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
@ -1453,20 +1452,70 @@ RPC.prototype.getwork = function getwork(args, callback, force) {
|
||||
});
|
||||
};
|
||||
|
||||
RPC.prototype.getblocktemplate = function getblocktemplate(args, callback) {
|
||||
RPC.prototype.getwork = function getwork(args, callback) {
|
||||
var self = this;
|
||||
var txs = [];
|
||||
var txIndex = {};
|
||||
var mode = 'template';
|
||||
var maxVersion = -1;
|
||||
var i, j, tx, deps, input, dep, block;
|
||||
var opt, lpid, keys, vbavailable, vbrules, mutable, clientRules;
|
||||
var data;
|
||||
|
||||
callback = this.locker.lock(getblocktemplate, [args, callback]);
|
||||
callback = this.locker.lock(getwork, [args, callback]);
|
||||
|
||||
if (!callback)
|
||||
return;
|
||||
|
||||
if (args.length > 1)
|
||||
return callback(new RPCError('getwork ( "data" )'));
|
||||
|
||||
if (args.length === 1) {
|
||||
if (!utils.isHex(args[0]))
|
||||
return callback(new RPCError('Invalid parameter.'));
|
||||
|
||||
data = new Buffer(args[0], 'hex');
|
||||
|
||||
return this._submitwork(data, callback);
|
||||
}
|
||||
|
||||
return this._getwork(callback);
|
||||
};
|
||||
|
||||
RPC.prototype.submitblock = function submitblock(args, callback) {
|
||||
var block;
|
||||
|
||||
callback = this.locker.lock(submitblock, [args, callback]);
|
||||
|
||||
if (!callback)
|
||||
return;
|
||||
|
||||
if (args.help || args.length < 1 || args.length > 2) {
|
||||
return callback(new RPCError('submitblock "hexdata"'
|
||||
+ ' ( "jsonparametersobject" )'));
|
||||
}
|
||||
|
||||
block = bcoin.block.fromRaw(toString(args[0]), 'hex');
|
||||
|
||||
this._submitblock(block, callback);
|
||||
};
|
||||
|
||||
RPC.prototype._submitblock = function submitblock(block, callback) {
|
||||
if (block.prevBlock !== this.chain.tip.hash)
|
||||
return callback(null, 'rejected: inconclusive-not-best-prevblk');
|
||||
|
||||
this.chain.add(block, function(err, total) {
|
||||
if (err) {
|
||||
if (err.type === 'VerifyError')
|
||||
return callback(null, 'rejected: ' + err.reason);
|
||||
return callback(err);
|
||||
}
|
||||
callback(null, null);
|
||||
});
|
||||
};
|
||||
|
||||
RPC.prototype.getblocktemplate = function getblocktemplate(args, callback) {
|
||||
var self = this;
|
||||
var mode = 'template';
|
||||
var version = -1;
|
||||
var coinbase = true;
|
||||
var i, opt, lpid, keys, rules;
|
||||
var cap, coinbasevalue, coinbasetxn;
|
||||
|
||||
if (args.help || args.length > 1)
|
||||
return callback(new RPCError('getblocktemplate ( "jsonrequestobject" )'));
|
||||
|
||||
@ -1487,25 +1536,32 @@ RPC.prototype.getblocktemplate = function getblocktemplate(args, callback) {
|
||||
|
||||
block = bcoin.block.fromRaw(opt.data, 'hex');
|
||||
|
||||
if (block.prevBlock !== self.chain.tip.hash)
|
||||
return callback(new RPCError('inconclusive-not-best-prevblk'));
|
||||
|
||||
return this.chain.add(block, function(err) {
|
||||
if (err) {
|
||||
if (err.reason)
|
||||
return callback(null, err.reason);
|
||||
return callback(null, 'rejected');
|
||||
}
|
||||
callback(null, null);
|
||||
});
|
||||
return this._submitblock(block, callback);
|
||||
}
|
||||
|
||||
if (Array.isArray(opt.rules)) {
|
||||
clientRules = [];
|
||||
rules = [];
|
||||
for (i = 0; i < opt.rules.length; i++)
|
||||
clientRules.push(String(opt.rules[i]));
|
||||
rules.push(toString(opt.rules[i]));
|
||||
} else if (utils.isNumber(opt.maxversion)) {
|
||||
maxVersion = opt.maxversion;
|
||||
version = opt.maxversion;
|
||||
}
|
||||
|
||||
if (Array.isArray(opt.capabilities)) {
|
||||
for (i = 0; i < opt.capabilities.length; i++) {
|
||||
cap = toString(opt.capabilities[i]);
|
||||
switch (cap) {
|
||||
case 'coinbasetxn':
|
||||
coinbasetxn = true;
|
||||
break;
|
||||
case 'coinbasevalue':
|
||||
coinbasevalue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (coinbasetxn && !coinbasevalue)
|
||||
coinbase = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1520,110 +1576,143 @@ RPC.prototype.getblocktemplate = function getblocktemplate(args, callback) {
|
||||
this._poll(lpid, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
self._tmpl(version, coinbase, rules, callback);
|
||||
});
|
||||
};
|
||||
|
||||
self._createBlock(function(err, attempt) {
|
||||
RPC.prototype._tmpl = function _tmpl(version, coinbase, rules, callback) {
|
||||
var self = this;
|
||||
var txs = [];
|
||||
var txIndex = {};
|
||||
var i, j, tx, deps, input, dep, block;
|
||||
var keys, vbavailable, vbrules, mutable, template;
|
||||
|
||||
callback = this.locker.lock(_tmpl, [version, coinbase, rules, callback]);
|
||||
|
||||
if (!callback)
|
||||
return;
|
||||
|
||||
this._createBlock(function(err, attempt) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
block = attempt.block;
|
||||
|
||||
for (i = 1; i < block.txs.length; i++) {
|
||||
tx = block.txs[i];
|
||||
txIndex[tx.hash('hex')] = i;
|
||||
deps = [];
|
||||
|
||||
for (j = 0; j < tx.inputs.length; j++) {
|
||||
input = tx.inputs[j];
|
||||
dep = txIndex[input.prevout.hash];
|
||||
if (dep != null)
|
||||
deps.push(dep);
|
||||
}
|
||||
|
||||
txs.push({
|
||||
data: tx.toRaw().toString('hex'),
|
||||
txid: tx.rhash,
|
||||
hash: tx.rwhash,
|
||||
depends: deps,
|
||||
fee: tx.getFee(),
|
||||
sigops: tx.getSigops(),
|
||||
weight: tx.getWeight()
|
||||
});
|
||||
}
|
||||
|
||||
keys = Object.keys(self.network.deployments);
|
||||
vbavailable = {};
|
||||
vbrules = [];
|
||||
mutable = ['time', 'transactions', 'prevblock'];
|
||||
|
||||
if (version >= 2)
|
||||
mutable.push('version/force');
|
||||
|
||||
utils.forEachSerial(keys, function(id, next) {
|
||||
var deployment = self.network.deployments[id];
|
||||
self.chain.getState(self.chain.tip, id, function(err, state) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
switch (state) {
|
||||
case constants.thresholdStates.DEFINED:
|
||||
case constants.thresholdStates.FAILED:
|
||||
break;
|
||||
case constants.thresholdStates.LOCKED_IN:
|
||||
block.version |= 1 << deployment.bit;
|
||||
case constants.thresholdStates.STARTED:
|
||||
vbavailable[id] = deployment.bit;
|
||||
if (rules) {
|
||||
if (rules.indexOf(id) === -1 && !deployment.force)
|
||||
block.version &= ~(1 << deployment.bit);
|
||||
}
|
||||
break;
|
||||
case constants.thresholdStates.ACTIVE:
|
||||
vbrules.push(id);
|
||||
if (rules) {
|
||||
if (rules.indexOf(id) === -1 && !deployment.force)
|
||||
return next(new RPCError('Client must support ' + id + '.'));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
}, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
block = attempt.block;
|
||||
block.version >>>= 0;
|
||||
|
||||
for (i = 1; i < block.txs.length; i++) {
|
||||
tx = block.txs[i];
|
||||
txIndex[tx.hash('hex')] = i;
|
||||
deps = [];
|
||||
template = {
|
||||
capabilities: ['proposal'],
|
||||
version: block.version,
|
||||
rules: vbrules,
|
||||
vbavailable: vbavailable,
|
||||
vbrequired: 0,
|
||||
previousblockhash: utils.revHex(block.prevBlock),
|
||||
transactions: txs,
|
||||
coinbaseaux: {
|
||||
flags: attempt.coinbaseFlags.toString('hex')
|
||||
},
|
||||
coinbasevalue: attempt.coinbase.outputs[0].value,
|
||||
longpollid: self.chain.tip.rhash + utils.pad32(self.mempool.totalTX),
|
||||
target: utils.revHex(attempt.target.toString('hex')),
|
||||
submitold: false,
|
||||
mintime: block.ts,
|
||||
maxtime: bcoin.now(),
|
||||
mutable: mutable,
|
||||
noncerange: '00000000ffffffff',
|
||||
sigoplimit: attempt.witness
|
||||
? constants.block.MAX_SIGOPS_WEIGHT
|
||||
: constants.block.MAX_SIGOPS,
|
||||
sizelimit: constants.block.MAX_SIZE,
|
||||
weightlimit: constants.block.MAX_WEIGHT,
|
||||
curtime: bcoin.now(),
|
||||
bits: utils.hex32(block.bits),
|
||||
height: attempt.height,
|
||||
default_witness_commitment: attempt.witness
|
||||
? attempt.coinbase.outputs[1].script.toJSON()
|
||||
: undefined
|
||||
};
|
||||
|
||||
for (j = 0; j < tx.inputs.length; j++) {
|
||||
input = tx.inputs[j];
|
||||
dep = txIndex[input.prevout.hash];
|
||||
if (dep != null)
|
||||
deps.push(dep);
|
||||
}
|
||||
|
||||
txs.push({
|
||||
if (!coinbase) {
|
||||
template.coinbaseaux = undefined;
|
||||
template.coinbasevalue = undefined;
|
||||
tx = block.txs[0];
|
||||
template.coinbasetxn = {
|
||||
data: tx.toRaw().toString('hex'),
|
||||
txid: tx.rhash,
|
||||
hash: tx.rwhash,
|
||||
depends: deps,
|
||||
fee: tx.getFee(),
|
||||
depends: [],
|
||||
fee: 0,
|
||||
sigops: tx.getSigops(),
|
||||
weight: tx.getWeight()
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
keys = Object.keys(self.network.deployments);
|
||||
vbavailable = {};
|
||||
vbrules = [];
|
||||
mutable = ['time', 'transactions', 'prevblock'];
|
||||
|
||||
if (maxVersion >= 2)
|
||||
mutable.push('version/force');
|
||||
|
||||
utils.forEachSerial(keys, function(id, next) {
|
||||
var deployment = self.network.deployments[id];
|
||||
self.chain.getState(self.chain.tip, id, function(err, state) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
switch (state) {
|
||||
case constants.thresholdStates.DEFINED:
|
||||
case constants.thresholdStates.FAILED:
|
||||
break;
|
||||
case constants.thresholdStates.LOCKED_IN:
|
||||
block.version |= 1 << deployment.bit;
|
||||
case constants.thresholdStates.STARTED:
|
||||
vbavailable[id] = deployment.bit;
|
||||
if (clientRules) {
|
||||
if (clientRules.indexOf(id) === -1 && !deployment.force)
|
||||
block.version &= ~(1 << deployment.bit);
|
||||
}
|
||||
break;
|
||||
case constants.thresholdStates.ACTIVE:
|
||||
vbrules.push(id);
|
||||
if (clientRules) {
|
||||
if (clientRules.indexOf(id) === -1 && !deployment.force)
|
||||
return next(new RPCError('Client must support ' + id + '.'));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
}, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
block.version >>>= 0;
|
||||
|
||||
callback(null, {
|
||||
capabilities: ['proposal'],
|
||||
version: block.version,
|
||||
rules: vbrules,
|
||||
vbavailable: vbavailable,
|
||||
vbrequired: 0,
|
||||
previousblockhash: utils.revHex(block.prevBlock),
|
||||
transactions: txs,
|
||||
coinbaseaux: {
|
||||
flags: new Buffer(attempt.coinbaseFlags, 'utf8').toString('hex')
|
||||
},
|
||||
coinbasevalue: attempt.coinbase.outputs[0].value,
|
||||
longpollid: self.chain.tip.rhash + utils.pad32(self.mempool.totalTX),
|
||||
target: utils.revHex(attempt.target.toString('hex')),
|
||||
mintime: attempt.block.ts,
|
||||
mutable: mutable,
|
||||
noncerange: '00000000ffffffff',
|
||||
sigoplimit: attempt.witness
|
||||
? constants.block.MAX_SIGOPS_WEIGHT
|
||||
: constants.block.MAX_SIGOPS,
|
||||
sizelimit: constants.block.MAX_SIZE,
|
||||
weightlimit: constants.block.MAX_WEIGHT,
|
||||
curtime: block.ts,
|
||||
bits: utils.hex32(block.bits),
|
||||
height: attempt.height,
|
||||
default_witness_commitment: attempt.witness
|
||||
? attempt.coinbase.outputs[1].script.toJSON()
|
||||
: undefined
|
||||
});
|
||||
});
|
||||
callback(null, template);
|
||||
});
|
||||
});
|
||||
};
|
||||
@ -1632,60 +1721,77 @@ RPC.prototype._poll = function _poll(lpid, callback) {
|
||||
var self = this;
|
||||
var watched, lastTX;
|
||||
|
||||
if (lpid == null)
|
||||
if (typeof lpid !== 'string')
|
||||
return callback();
|
||||
|
||||
if (typeof lpid === 'string') {
|
||||
if (lpid.length < 65)
|
||||
return callback(new RPCError('Invalid parameter.'));
|
||||
watched = lpid.slice(0, 64);
|
||||
lastTX = +lpid.slice(64);
|
||||
if (!utils.isHex(watched) || !utils.isNumber(lastTX))
|
||||
return callback(new RPCError('Invalid parameter.'));
|
||||
watched = utils.revHex(watched);
|
||||
} else {
|
||||
watched = this.chain.tip.hash;
|
||||
lastTX = this.lastTX;
|
||||
}
|
||||
if (lpid.length !== 74)
|
||||
return callback(new RPCError('Invalid parameter.'));
|
||||
|
||||
function listener() {
|
||||
if (self.chain.tip.hash !== watched || self.mempool.totalTX !== lastTX) {
|
||||
self.chain.removeListener('block', listener);
|
||||
self.mempool.removeListener('tx', listener);
|
||||
return callback();
|
||||
}
|
||||
}
|
||||
watched = lpid.slice(0, 64);
|
||||
lastTX = +lpid.slice(64, 74);
|
||||
|
||||
this.chain.on('block', listener);
|
||||
this.mempool.on('tx', listener);
|
||||
if (!utils.isHex(watched) || !utils.isNumber(lastTX))
|
||||
return callback(new RPCError('Invalid parameter.'));
|
||||
|
||||
watched = utils.revHex(watched);
|
||||
|
||||
if (self.chain.tip.hash !== watched)
|
||||
return callback();
|
||||
|
||||
this.once('clear block', callback);
|
||||
};
|
||||
|
||||
RPC.prototype._clearBlock = function _clearBlock() {
|
||||
this.prevBlock = null;
|
||||
this.currentBlock = null;
|
||||
this.lastTX = 0;
|
||||
this.start = 0;
|
||||
this.blockStart = 0;
|
||||
};
|
||||
|
||||
RPC.prototype._bindChain = function _bindChain() {
|
||||
var self = this;
|
||||
|
||||
if (this._boundChain)
|
||||
return;
|
||||
|
||||
this._boundChain = true;
|
||||
|
||||
this.chain.on('connect', function() {
|
||||
if (!self.currentBlock)
|
||||
return;
|
||||
|
||||
self._clearBlock();
|
||||
self.emit('clear block');
|
||||
});
|
||||
|
||||
this.mempool.on('tx', function() {
|
||||
var diff;
|
||||
|
||||
if (!self.currentBlock)
|
||||
return;
|
||||
|
||||
diff = utils.now() - self.blockStart;
|
||||
|
||||
if (diff > 5) {
|
||||
self._clearBlock();
|
||||
self.emit('clear block');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
RPC.prototype._createBlock = function _createBlock(callback) {
|
||||
var self = this;
|
||||
var diff = utils.now() - this.start;
|
||||
var total = this.mempool.totalTX;
|
||||
|
||||
if (this.prevBlock !== this.chain.tip.hash
|
||||
|| (total !== this.lastTX && diff > 5)) {
|
||||
return this.miner.createBlock(function(err, attempt) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
self.prevBlock = attempt.block.prevBlock;
|
||||
self.currentBlock = attempt;
|
||||
self.lastTX = self.mempool.totalTX;
|
||||
self.start = utils.now();
|
||||
callback(null, attempt);
|
||||
});
|
||||
}
|
||||
this._bindChain();
|
||||
|
||||
callback(null, this.currentBlock);
|
||||
if (this.currentBlock)
|
||||
return callback(null, this.currentBlock);
|
||||
|
||||
this.miner.createBlock(function(err, attempt) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
self.currentBlock = attempt;
|
||||
self.blockStart = utils.now();
|
||||
callback(null, attempt);
|
||||
});
|
||||
};
|
||||
|
||||
RPC.prototype.getmininginfo = function getmininginfo(args, callback) {
|
||||
@ -1714,8 +1820,8 @@ RPC.prototype.getmininginfo = function getmininginfo(args, callback) {
|
||||
genproclimit: self.proclimit,
|
||||
networkhashps: hashps,
|
||||
pooledtx: self.mempool.totalTX,
|
||||
testnet: self.network.type !== bcoin.network.main,
|
||||
chain: self.network.type,
|
||||
testnet: self.network !== bcoin.network.main,
|
||||
chain: 'main',
|
||||
generate: self.mining
|
||||
});
|
||||
});
|
||||
@ -1773,23 +1879,6 @@ RPC.prototype.prioritisetransaction = function prioritisetransaction(args, callb
|
||||
callback(null, true);
|
||||
};
|
||||
|
||||
RPC.prototype.submitblock = function submitblock(args, callback) {
|
||||
var block;
|
||||
|
||||
if (args.help || args.length < 1 || args.length > 2) {
|
||||
return callback(new RPCError('submitblock "hexdata"'
|
||||
+ ' ( "jsonparametersobject" )'));
|
||||
}
|
||||
|
||||
block = bcoin.block.fromRaw(toString(args[0]), 'hex');
|
||||
|
||||
this.chain.add(block, function(err, total) {
|
||||
if (err)
|
||||
return callback(null, 'rejected');
|
||||
callback(null, 'valid');
|
||||
});
|
||||
};
|
||||
|
||||
RPC.prototype._hashps = function _hashps(lookup, height, callback) {
|
||||
var self = this;
|
||||
var minTime, maxTime, pb0, time, workDiff, timeDiff, ps;
|
||||
|
||||
@ -40,6 +40,9 @@ function Miner(options) {
|
||||
this.coinbaseFlags = this.options.coinbaseFlags || 'mined by bcoin';
|
||||
this.version = null;
|
||||
|
||||
if (typeof this.coinbaseFlags === 'string')
|
||||
this.coinbaseFlags = new Buffer(this.coinbaseFlags, 'utf8');
|
||||
|
||||
this.pool = options.pool;
|
||||
this.chain = options.chain;
|
||||
this.logger = options.logger || this.chain.logger;
|
||||
@ -144,7 +147,8 @@ Miner.prototype._open = function open(callback) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
self.logger.info('Miner loaded (flags=%s).', self.coinbaseFlags);
|
||||
self.logger.info('Miner loaded (flags=%s).',
|
||||
self.coinbaseFlags.toString('utf8'));
|
||||
|
||||
callback();
|
||||
});
|
||||
|
||||
@ -57,6 +57,9 @@ function MinerBlock(options) {
|
||||
this.timeout = null;
|
||||
this.callback = null;
|
||||
|
||||
if (typeof this.coinbaseFlags === 'string')
|
||||
this.coinbaseFlags = new Buffer(this.coinbaseFlags, 'utf8');
|
||||
|
||||
this.coinbase = new bcoin.tx();
|
||||
this.coinbase.mutable = true;
|
||||
|
||||
@ -417,7 +420,7 @@ MinerBlock.prototype.toRaw = function toRaw(writer) {
|
||||
p.writeU32(this.block.version);
|
||||
p.writeU32(this.block.bits);
|
||||
p.writeVarBytes(this.address.toRaw());
|
||||
p.writeVarString(this.coinbaseFlags, 'utf8');
|
||||
p.writeVarBytes(this.coinbaseFlags);
|
||||
p.writeU8(this.witness ? 1 : 0);
|
||||
p.writeVarint(this.block.txs.length - 1);
|
||||
|
||||
@ -443,7 +446,7 @@ MinerBlock.fromRaw = function fromRaw(data) {
|
||||
var version = p.readU32();
|
||||
var bits = p.readU32();
|
||||
var address = bcoin.address.fromRaw(p.readVarBytes());
|
||||
var coinbaseFlags = p.readVarString('utf8');
|
||||
var coinbaseFlags = p.readVarBytes();
|
||||
var witness = p.readU8() === 1;
|
||||
var count = p.readVarint();
|
||||
var txs = [];
|
||||
|
||||
Loading…
Reference in New Issue
Block a user