check sequence locks.

This commit is contained in:
Christopher Jeffrey 2016-05-05 19:41:14 -07:00
parent e2bcbcaba5
commit 5fd44dbed8
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -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