check sequence locks.
This commit is contained in:
parent
e2bcbcaba5
commit
5fd44dbed8
@ -434,7 +434,7 @@ Chain.prototype._preload = function _preload(callback) {
|
||||
Chain.prototype._verifyContext = function _verifyContext(block, prev, callback) {
|
||||
var self = this;
|
||||
|
||||
this._verify(block, prev, function(err, flags) {
|
||||
this._verify(block, prev, function(err, state) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
@ -442,7 +442,7 @@ Chain.prototype._verifyContext = function _verifyContext(block, prev, callback)
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
self._checkInputs(block, prev, flags, function(err) {
|
||||
self._checkInputs(block, prev, state, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
@ -577,7 +577,7 @@ Chain.prototype._verify = function _verify(block, prev, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
return done(null, state.flags);
|
||||
return done(null, state);
|
||||
});
|
||||
});
|
||||
};
|
||||
@ -786,11 +786,11 @@ Chain.prototype._findDuplicates = function _findDuplicates(block, prev, callback
|
||||
* @see TX#checkInputs
|
||||
* @param {Block} block
|
||||
* @param {ChainBlock} prev
|
||||
* @param {VerifyFlags} flags
|
||||
* @param {DeploymentState} state
|
||||
* @param {Function} callback - Returns [{@link VerifyError}].
|
||||
*/
|
||||
|
||||
Chain.prototype._checkInputs = function _checkInputs(block, prev, flags, callback) {
|
||||
Chain.prototype._checkInputs = function _checkInputs(block, prev, state, callback) {
|
||||
var self = this;
|
||||
var height = prev.height + 1;
|
||||
var scriptCheck = true;
|
||||
@ -813,103 +813,90 @@ Chain.prototype._checkInputs = function _checkInputs(block, prev, flags, callbac
|
||||
this.db.fillBlock(block, function(err) {
|
||||
var ret = {};
|
||||
var sigops = 0;
|
||||
var i, j, input, tx, hash;
|
||||
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
// Check all transactions
|
||||
for (i = 0; i < block.txs.length; i++) {
|
||||
tx = block.txs[i];
|
||||
hash = tx.hash('hex');
|
||||
utils.forEachSerial(block.txs, function(tx, next) {
|
||||
var hash = tx.hash('hex');
|
||||
|
||||
// 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())
|
||||
continue;
|
||||
|
||||
for (j = 0; j < tx.inputs.length; j++) {
|
||||
input = tx.inputs[j];
|
||||
|
||||
// Ensure tx is not double spending an output.
|
||||
if (!input.coin) {
|
||||
// Ensure tx is not double spending an output.
|
||||
if (!tx.isCoinbase()) {
|
||||
if (!tx.hasCoins()) {
|
||||
assert(!historical, 'BUG: Spent inputs in historical data!');
|
||||
return callback(new VerifyError(block,
|
||||
return next(new VerifyError(block,
|
||||
'invalid',
|
||||
'bad-txns-inputs-missingorspent',
|
||||
100));
|
||||
}
|
||||
}
|
||||
|
||||
if (!self.options.verifySync)
|
||||
continue;
|
||||
self.checkLocks(tx, state.lockFlags, entry, function(err, valid) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
if (!valid) {
|
||||
return next(new VerifyError(block,
|
||||
'invalid',
|
||||
'bad-txns-nonfinal',
|
||||
100));
|
||||
}
|
||||
|
||||
// Count sigops (legacy + scripthash? + witness?)
|
||||
sigops += tx.getSigopsCost(state.flags);
|
||||
|
||||
if (sigops > constants.block.MAX_SIGOPS_COST) {
|
||||
return next(new VerifyError(block,
|
||||
'invalid',
|
||||
'bad-blk-sigops',
|
||||
100));
|
||||
}
|
||||
|
||||
// Contextual sanity checks.
|
||||
if (!tx.isCoinbase()) {
|
||||
if (!tx.checkInputs(height, ret)) {
|
||||
return next(new VerifyError(block,
|
||||
'invalid',
|
||||
ret.reason,
|
||||
ret.score));
|
||||
}
|
||||
}
|
||||
|
||||
return next();
|
||||
});
|
||||
}, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
// Verify all txs in parallel.
|
||||
utils.every(block.txs, function(tx, next) {
|
||||
if (!scriptCheck)
|
||||
continue;
|
||||
return next(null, true);
|
||||
|
||||
// Verify the scripts
|
||||
if (!tx.verify(j, true, flags)) {
|
||||
bcoin.debug(
|
||||
'Transaction failed consensus verification: %s',
|
||||
tx.rhash);
|
||||
bcoin.debug('TX:');
|
||||
bcoin.debug(tx);
|
||||
bcoin.debug('Input (%d):', j);
|
||||
bcoin.debug(input);
|
||||
bcoin.debug('Serialized TX (with coins):');
|
||||
bcoin.debug(tx.toExtended('hex', true));
|
||||
bcoin.debug('Flags: %d', flags);
|
||||
tx.verifyAsync(null, true, state.flags, next);
|
||||
}, function(err, verified) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!verified) {
|
||||
assert(!historical, 'BUG: Invalid inputs in historical data!');
|
||||
return callback(new VerifyError(block,
|
||||
return next(new VerifyError(block,
|
||||
'invalid',
|
||||
'mandatory-script-verify-flag-failed',
|
||||
100));
|
||||
}
|
||||
}
|
||||
|
||||
// Contextual sanity checks.
|
||||
if (!tx.checkInputs(height, ret)) {
|
||||
return callback(new VerifyError(block,
|
||||
'invalid',
|
||||
ret.reason,
|
||||
ret.score));
|
||||
}
|
||||
}
|
||||
// Make sure the miner isn't trying to conjure more coins.
|
||||
if (block.getClaimed().cmp(block.getReward()) > 0) {
|
||||
return callback(new VerifyError(block,
|
||||
'invalid',
|
||||
'bad-cb-amount',
|
||||
100));
|
||||
}
|
||||
|
||||
// Make sure the miner isn't trying to conjure more coins.
|
||||
if (block.getClaimed().cmp(block.getReward()) > 0)
|
||||
return callback(new VerifyError(block, 'invalid', 'bad-cb-amount', 100));
|
||||
|
||||
if (self.options.verifySync)
|
||||
return callback();
|
||||
|
||||
if (!scriptCheck)
|
||||
return callback();
|
||||
|
||||
// Verify all txs in parallel.
|
||||
utils.every(block.txs, function(tx, next) {
|
||||
tx.verifyAsync(null, true, flags, next);
|
||||
}, function(err, verified) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!verified) {
|
||||
assert(!historical, 'BUG: Invalid inputs in historical data!');
|
||||
return callback(new VerifyError(block,
|
||||
'invalid',
|
||||
'mandatory-script-verify-flag-failed',
|
||||
100));
|
||||
}
|
||||
|
||||
return callback();
|
||||
return callback();
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
@ -2470,7 +2457,7 @@ Chain.prototype.getLocks = function getLocks(tx, flags, entry, callback) {
|
||||
var minTime = -1;
|
||||
var coinHeight;
|
||||
|
||||
if (tx.version < 2 || !hasFlag)
|
||||
if (tx.isCoinbase() || tx.version < 2 || !hasFlag)
|
||||
return utils.asyncify(callback)(null, minHeight, minTime);
|
||||
|
||||
utils.forEachSerial(tx.inputs, function(input, next) {
|
||||
@ -2555,7 +2542,6 @@ Chain.prototype.checkLocks = function checkLocks(tx, flags, entry, callback) {
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the difficulty.
|
||||
* @param {ChainBlock} entry
|
||||
|
||||
Loading…
Reference in New Issue
Block a user