refactor. cleanup.
This commit is contained in:
parent
e4921af906
commit
9468b00d1c
@ -828,14 +828,24 @@ Chain.prototype._checkInputs = function _checkInputs(block, prev, flags, callbac
|
|||||||
tx = block.txs[i];
|
tx = block.txs[i];
|
||||||
hash = tx.hash('hex');
|
hash = tx.hash('hex');
|
||||||
|
|
||||||
// Coinbases do not have prevouts
|
// Count sigops (legacy + scripthash? + witness?)
|
||||||
|
sigops += tx.getSigopsCost(flags);
|
||||||
|
|
||||||
|
if (sigops > constants.block.MAX_SIGOPS_COST) {
|
||||||
|
return callback(new VerifyError(block,
|
||||||
|
'invalid',
|
||||||
|
'bad-blk-sigops',
|
||||||
|
100));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Coinbases do not have prevouts.
|
||||||
if (tx.isCoinbase())
|
if (tx.isCoinbase())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (j = 0; j < tx.inputs.length; j++) {
|
for (j = 0; j < tx.inputs.length; j++) {
|
||||||
input = tx.inputs[j];
|
input = tx.inputs[j];
|
||||||
|
|
||||||
// Ensure tx is not double spending an output
|
// Ensure tx is not double spending an output.
|
||||||
if (!input.coin) {
|
if (!input.coin) {
|
||||||
assert(!historical, 'BUG: Spent inputs in historical data!');
|
assert(!historical, 'BUG: Spent inputs in historical data!');
|
||||||
return callback(new VerifyError(block,
|
return callback(new VerifyError(block,
|
||||||
@ -858,8 +868,8 @@ Chain.prototype._checkInputs = function _checkInputs(block, prev, flags, callbac
|
|||||||
bcoin.debug('TX:');
|
bcoin.debug('TX:');
|
||||||
bcoin.debug(tx);
|
bcoin.debug(tx);
|
||||||
bcoin.debug('Input (%d):', j);
|
bcoin.debug('Input (%d):', j);
|
||||||
bcoin.debug(tx.inputs[j]);
|
bcoin.debug(input);
|
||||||
bcoin.debug('TX with coins:');
|
bcoin.debug('Serialized TX (with coins):');
|
||||||
bcoin.debug(tx.toExtended('hex', true));
|
bcoin.debug(tx.toExtended('hex', true));
|
||||||
bcoin.debug('Flags: %d', flags);
|
bcoin.debug('Flags: %d', flags);
|
||||||
assert(!historical, 'BUG: Invalid inputs in historical data!');
|
assert(!historical, 'BUG: Invalid inputs in historical data!');
|
||||||
@ -870,16 +880,7 @@ Chain.prototype._checkInputs = function _checkInputs(block, prev, flags, callbac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count sigops (legacy + scripthash? + witness?)
|
// Contextual sanity checks.
|
||||||
sigops += tx.getSigopsCost(flags);
|
|
||||||
|
|
||||||
if (sigops > constants.block.MAX_SIGOPS_COST) {
|
|
||||||
return callback(new VerifyError(block,
|
|
||||||
'invalid',
|
|
||||||
'bad-blk-sigops',
|
|
||||||
100));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tx.checkInputs(height, ret)) {
|
if (!tx.checkInputs(height, ret)) {
|
||||||
return callback(new VerifyError(block,
|
return callback(new VerifyError(block,
|
||||||
'invalid',
|
'invalid',
|
||||||
@ -888,6 +889,7 @@ Chain.prototype._checkInputs = function _checkInputs(block, prev, flags, callbac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure the miner isn't trying to conjure more coins.
|
||||||
if (block.getClaimed().cmp(block.getReward()) > 0)
|
if (block.getClaimed().cmp(block.getReward()) > 0)
|
||||||
return callback(new VerifyError(block, 'invalid', 'bad-cb-amount', 100));
|
return callback(new VerifyError(block, 'invalid', 'bad-cb-amount', 100));
|
||||||
|
|
||||||
@ -1705,17 +1707,12 @@ Chain.prototype.has = function has(hash, callback) {
|
|||||||
* @param {Function} callback - Returns [Error, {@link ChainBlock}].
|
* @param {Function} callback - Returns [Error, {@link ChainBlock}].
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Chain.prototype.byTime = function byTime(ts, callback, force) {
|
Chain.prototype.byTime = function byTime(ts, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var start = 0;
|
var start = 0;
|
||||||
var end = this.height;
|
var end = this.height;
|
||||||
var pos, delta;
|
var pos, delta;
|
||||||
|
|
||||||
// var unlock = this._lock(byTime, [ts, callback], force);
|
|
||||||
// if (!unlock)
|
|
||||||
// return;
|
|
||||||
// callback = utils.wrap(callback, unlock);
|
|
||||||
|
|
||||||
function done(err, result) {
|
function done(err, result) {
|
||||||
if (err)
|
if (err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
@ -1863,14 +1860,9 @@ Chain.prototype.getProgress = function getProgress() {
|
|||||||
* @param {Function} callback - Returns [Error, Hash[]].
|
* @param {Function} callback - Returns [Error, Hash[]].
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Chain.prototype.getHashRange = function getHashRange(start, end, callback, force) {
|
Chain.prototype.getHashRange = function getHashRange(start, end, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
// var unlock = this._lock(getHashRange, [start, end, callback], force);
|
|
||||||
// if (!unlock)
|
|
||||||
// return;
|
|
||||||
// callback = utils.wrap(callback, unlock);
|
|
||||||
|
|
||||||
this.byTime(start, function(err, start) {
|
this.byTime(start, function(err, start) {
|
||||||
if (err)
|
if (err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
|
|||||||
@ -279,8 +279,6 @@ Pool.prototype._init = function _init() {
|
|||||||
|
|
||||||
this.chain.on('orphan', function(block, data, peer) {
|
this.chain.on('orphan', function(block, data, peer) {
|
||||||
self.emit('orphan', data, peer);
|
self.emit('orphan', data, peer);
|
||||||
// Resolve orphan chain
|
|
||||||
// self.resolveOrphan(self.peers.load, null, data.hash);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.chain.on('full', function() {
|
this.chain.on('full', function() {
|
||||||
@ -343,18 +341,6 @@ Pool.prototype.resolveOrphan = function resolveOrphan(peer, top, orphan, callbac
|
|||||||
return callback();
|
return callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're already processing the block
|
|
||||||
// that would resolve this, ignore.
|
|
||||||
// if (self.request.map[orphan.soil]) {
|
|
||||||
// bcoin.debug('Already requested orphan "soil".');
|
|
||||||
// return callback();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (self.chain.hasPending(orphan.soil)) {
|
|
||||||
// bcoin.debug('Already processing orphan "soil".');
|
|
||||||
// return callback();
|
|
||||||
// }
|
|
||||||
|
|
||||||
peer.getBlocks(locator, orphan.root);
|
peer.getBlocks(locator, orphan.root);
|
||||||
|
|
||||||
callback();
|
callback();
|
||||||
@ -794,14 +780,6 @@ Pool.prototype._handleInv = function _handleInv(hashes, peer, callback) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Pool.prototype._prehandleTX = function _prehandleTX(tx, peer, callback) {
|
|
||||||
return callback(null, tx);
|
|
||||||
};
|
|
||||||
|
|
||||||
Pool.prototype._prehandleBlock = function _prehandleBlock(block, peer, callback) {
|
|
||||||
return callback(null, block);
|
|
||||||
};
|
|
||||||
|
|
||||||
Pool.prototype._handleBlock = function _handleBlock(block, peer, callback) {
|
Pool.prototype._handleBlock = function _handleBlock(block, peer, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var requested;
|
var requested;
|
||||||
@ -820,52 +798,47 @@ Pool.prototype._handleBlock = function _handleBlock(block, peer, callback) {
|
|||||||
return callback();
|
return callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
this._prehandleBlock(block, peer, function(err) {
|
this.chain.add(block, function(err) {
|
||||||
if (err)
|
if (err) {
|
||||||
return callback(err);
|
if (err.type === 'VerifyError') {
|
||||||
|
if (err.score >= 0)
|
||||||
|
peer.sendReject(block, err.code, err.reason, err.score);
|
||||||
|
|
||||||
self.chain.add(block, function(err) {
|
if (err.reason === 'bad-prevblk') {
|
||||||
if (err) {
|
if (peer === self.peers.load)
|
||||||
if (err.type === 'VerifyError') {
|
self.resolveOrphan(peer, null, block.hash('hex'));
|
||||||
if (err.score >= 0)
|
|
||||||
peer.sendReject(block, err.code, err.reason, err.score);
|
|
||||||
|
|
||||||
if (err.reason === 'bad-prevblk') {
|
|
||||||
if (peer === self.peers.load)
|
|
||||||
self.resolveOrphan(peer, null, block.hash('hex'));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.scheduleRequests(peer);
|
|
||||||
|
|
||||||
return callback(err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.scheduleRequests(peer);
|
||||||
|
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
self.scheduleRequests(peer);
|
self.scheduleRequests(peer);
|
||||||
|
|
||||||
self.emit('chain-progress', self.chain.getProgress(), peer);
|
self.emit('chain-progress', self.chain.getProgress(), peer);
|
||||||
|
|
||||||
if (self.chain.total % 20 === 0) {
|
if (self.chain.total % 20 === 0) {
|
||||||
bcoin.debug(
|
bcoin.debug(
|
||||||
'Status: tip=%s ts=%s height=%d blocks=%d orphans=%d active=%d'
|
'Status: tip=%s ts=%s height=%d blocks=%d orphans=%d active=%d'
|
||||||
+ ' queue=%d target=%s peers=%d pending=%d highest=%d jobs=%d',
|
+ ' queue=%d target=%s peers=%d pending=%d highest=%d jobs=%d',
|
||||||
block.rhash,
|
block.rhash,
|
||||||
utils.date(block.ts),
|
utils.date(block.ts),
|
||||||
self.chain.height,
|
self.chain.height,
|
||||||
self.chain.total,
|
self.chain.total,
|
||||||
self.chain.orphan.count,
|
self.chain.orphan.count,
|
||||||
self.request.activeBlocks,
|
self.request.activeBlocks,
|
||||||
peer.queue.block.length,
|
peer.queue.block.length,
|
||||||
block.bits,
|
block.bits,
|
||||||
self.peers.all.length,
|
self.peers.all.length,
|
||||||
self.chain.locker.pending.length,
|
self.chain.locker.pending.length,
|
||||||
self.chain.bestHeight,
|
self.chain.bestHeight,
|
||||||
self.chain.locker.jobs.length);
|
self.chain.locker.jobs.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
return callback();
|
return callback();
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -990,7 +963,7 @@ Pool.prototype._createPeer = function _createPeer(options) {
|
|||||||
|
|
||||||
for (i = 0; i < txs.length; i++) {
|
for (i = 0; i < txs.length; i++) {
|
||||||
hash = txs[i];
|
hash = txs[i];
|
||||||
if (self.markTX(hash, 0))
|
if (self._markTX(hash, 0))
|
||||||
self.getData(peer, self.tx.type, hash);
|
self.getData(peer, self.tx.type, hash);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1018,7 +991,7 @@ Pool.prototype._handleTX = function _handleTX(tx, peer, callback) {
|
|||||||
callback = utils.asyncify(callback);
|
callback = utils.asyncify(callback);
|
||||||
|
|
||||||
requested = this.fulfill(tx);
|
requested = this.fulfill(tx);
|
||||||
updated = this.markTX(tx, 1);
|
updated = this._markTX(tx, 1);
|
||||||
|
|
||||||
function addMempool(tx, callback) {
|
function addMempool(tx, callback) {
|
||||||
if (!self.mempool)
|
if (!self.mempool)
|
||||||
@ -1030,27 +1003,22 @@ Pool.prototype._handleTX = function _handleTX(tx, peer, callback) {
|
|||||||
self.mempool.addTX(tx, callback);
|
self.mempool.addTX(tx, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._prehandleTX(tx, peer, function(err) {
|
addMempool(tx, function(err) {
|
||||||
if (err)
|
if (err) {
|
||||||
return callback(err);
|
if (err.type === 'VerifyError') {
|
||||||
|
if (err.score >= 0)
|
||||||
addMempool(tx, function(err) {
|
peer.sendReject(tx, err.code, err.reason, err.score);
|
||||||
if (err) {
|
return callback();
|
||||||
if (err.type === 'VerifyError') {
|
|
||||||
if (err.score >= 0)
|
|
||||||
peer.sendReject(tx, err.code, err.reason, err.score);
|
|
||||||
return callback();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (updated || tx.block)
|
if (updated || tx.block)
|
||||||
self.emit('tx', tx, peer);
|
self.emit('tx', tx, peer);
|
||||||
|
|
||||||
if (self.options.spv && tx.block)
|
if (self.options.spv && tx.block)
|
||||||
self.emit('watched', tx, peer);
|
self.emit('watched', tx, peer);
|
||||||
|
|
||||||
return callback();
|
return callback();
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1212,7 +1180,7 @@ Pool.prototype._addPeer = function _addPeer() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Pool.prototype.markTX = function(hash, state) {
|
Pool.prototype._markTX = function(hash, state) {
|
||||||
if (hash.hash)
|
if (hash.hash)
|
||||||
hash = hash.hash('hex');
|
hash = hash.hash('hex');
|
||||||
|
|
||||||
|
|||||||
@ -946,7 +946,7 @@ TX.prototype.getScripthashSigops = function getScripthashSigops() {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (input.coin.script.isScripthash())
|
if (input.coin.script.isScripthash())
|
||||||
total += input.coin.script.getSigops(input.script);
|
total += input.coin.script.getScripthashSigops(input.script);
|
||||||
}
|
}
|
||||||
|
|
||||||
return total;
|
return total;
|
||||||
@ -994,10 +994,12 @@ TX.prototype.getSigopsCost = function getSigopsCost(flags) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
TX.prototype.getSigops = function getSigops(flags) {
|
TX.prototype.getSigops = function getSigops(flags) {
|
||||||
|
var scale = constants.WITNESS_SCALE_FACTOR;
|
||||||
|
|
||||||
if (flags == null)
|
if (flags == null)
|
||||||
flags = constants.flags.STANDARD_VERIFY_FLAGS;
|
flags = constants.flags.STANDARD_VERIFY_FLAGS;
|
||||||
|
|
||||||
return (this.getSigopsCost(flags) + 3) / 4 | 0;
|
return (this.getSigopsCost(flags) + scale - 1) / scale | 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1202,8 +1204,6 @@ TX.prototype.hasStandardInputs = function hasStandardInputs(flags) {
|
|||||||
|
|
||||||
if ((flags & constants.flags.VERIFY_P2SH)
|
if ((flags & constants.flags.VERIFY_P2SH)
|
||||||
&& input.coin.script.isScripthash()) {
|
&& input.coin.script.isScripthash()) {
|
||||||
assert(input.script.isPushOnly());
|
|
||||||
|
|
||||||
stack = new Stack();
|
stack = new Stack();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user