mtx/wallet: more sanity checks for sending.

This commit is contained in:
Christopher Jeffrey 2016-12-18 03:20:47 -08:00
parent ff28b7c4fb
commit 595ada8c86
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
3 changed files with 34 additions and 16 deletions

View File

@ -138,13 +138,17 @@ function FundingError(msg, available, required) {
if (Error.captureStackTrace)
Error.captureStackTrace(this, FundingError);
msg += ' (available=' + Amount.btc(available) + ',';
msg += ' required=' + Amount.btc(required) + ')';
this.type = 'FundingError';
this.message = msg;
this.availableFunds = available;
this.requiredFunds = required;
this.availableFunds = -1;
this.requiredFunds = -1;
if (available != null) {
this.message += ' (available=' + Amount.btc(available) + ',';
this.message += ' required=' + Amount.btc(required) + ')';
this.availableFunds = available;
this.requiredFunds = required;
}
}
util.inherits(FundingError, Error);

View File

@ -293,6 +293,16 @@ MTX.prototype.getSigops = function getSigops(flags) {
return TX.prototype.getSigops.call(this, this.view, flags);
};
/**
* Calculate sigops weight, taking into account witness programs.
* @param {VerifyFlags?} flags
* @returns {Number} sigop weight
*/
MTX.prototype.getSigopsCost = function getSigopsCost(flags) {
return TX.prototype.getSigopsCost.call(this, this.view, flags);
};
/**
* Perform contextual checks to verify input, output,
* and fee values, as well as coinbase spend maturity
@ -1697,12 +1707,8 @@ CoinSelector.prototype.selectEstimate = co(function* selectEstimate(fee) {
this.fee = this.getFee(size);
if (this.maxFee > 0 && this.fee > this.maxFee) {
throw new FundingError(
'Fee is too high.',
this.tx.getInputValue(),
this.total());
}
if (this.maxFee > 0 && this.fee > this.maxFee)
throw new FundingError('Fee is too high.');
// Failed to get enough funds, add more coins.
if (!this.isFull())

View File

@ -1622,16 +1622,24 @@ Wallet.prototype.send = co(function* send(options, passphrase) {
*/
Wallet.prototype._send = co(function* send(options, passphrase) {
var tx = yield this.createTX(options, true);
var mtx = yield this.createTX(options, true);
var tx;
yield this.sign(tx, passphrase);
yield this.sign(mtx, passphrase);
if (!tx.isSigned())
if (!mtx.isSigned())
throw new Error('TX could not be fully signed.');
assert(tx.getFee() <= constants.tx.MAX_FEE, 'TX exceeds maxfee.');
assert(mtx.getFee() <= constants.tx.MAX_FEE, 'TX exceeds maxfee.');
tx = tx.toTX();
tx = mtx.toTX();
// Sanity checks.
if (tx.getSigopsCost(mtx.view) > constants.tx.MAX_SIGOPS_COST)
throw new Error('TX exceeds policy sigops.');
if (tx.getWeight() > constants.tx.MAX_WEIGHT)
throw new Error('TX exceeds policy weight.');
yield this.db.addTX(tx);