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