Merge pull request #1226 from dskloet/refactor/get-serialization-error

Simplify transaction.getSerializationError()
This commit is contained in:
Braydon Fuller 2015-05-18 15:08:50 -04:00
commit c251c2bfd1
1 changed files with 52 additions and 37 deletions

View File

@ -182,7 +182,8 @@ Transaction.prototype.invalidSatoshis = function() {
};
/**
* Retrieve a possible error that could appear when trying to serialize and broadcast this transaction
* Retrieve a possible error that could appear when trying to serialize and
* broadcast this transaction.
*
* @param {Object} opts allows to skip certain tests. {@see Transaction#serialize}
* @return {bitcore.Error}
@ -190,38 +191,23 @@ Transaction.prototype.invalidSatoshis = function() {
Transaction.prototype.getSerializationError = function(opts) {
opts = opts || {};
return this._isInvalidSatoshis() ||
this._hasFeeError(opts) ||
this._hasDustOutputs(opts) ||
this._isMissingSignatures(opts) ||
this._hasMoreOutputThanInput(opts);
};
Transaction.prototype._isInvalidSatoshis = function() {
if (this.invalidSatoshis()) {
return new errors.Transaction.InvalidSatoshis();
}
};
var feeIsDifferent = this._isFeeDifferent();
if (feeIsDifferent) {
return new errors.Transaction.FeeError.Different(feeIsDifferent);
}
var missingChange = this._missingChange();
var feeIsTooLarge = this._isFeeTooLarge();
var feeIsTooSmall = this._isFeeTooSmall();
var isFullySigned = this.isFullySigned();
if (!opts.disableLargeFees && feeIsTooLarge) {
if (missingChange) {
return new errors.Transaction.ChangeAddressMissing('Fee is too large and no change address was provided');
}
return new errors.Transaction.FeeError.TooLarge(feeIsTooLarge);
}
if (!opts.disableSmallFees && feeIsTooSmall) {
return new errors.Transaction.FeeError.TooSmall(feeIsTooSmall);
}
if (!opts.disableDustOutputs && this._hasDustOutputs()) {
return new errors.Transaction.DustOutputs();
}
if (!opts.disableIsFullySigned && !isFullySigned) {
return new errors.Transaction.MissingSignatures();
}
if (!opts.disableMoreOutputThanInput && this._getUnspentValue() < 0) {
return new errors.Transaction.InvalidOutputAmountSum();
}
Transaction.prototype._hasFeeError = function(opts) {
return this._isFeeDifferent() ||
this._isFeeTooLarge(opts) ||
this._isFeeTooSmall(opts);
};
Transaction.prototype._isFeeDifferent = function() {
@ -229,24 +215,33 @@ Transaction.prototype._isFeeDifferent = function() {
var fee = this._fee;
var unspent = this._getUnspentValue();
if (fee !== unspent) {
return 'Unspent value is ' + unspent + ' but specified fee is ' + fee;
return new errors.Transaction.FeeError.Different('Unspent value is ' + unspent + ' but specified fee is ' + fee);
}
}
};
Transaction.prototype._isFeeTooLarge = function() {
Transaction.prototype._isFeeTooLarge = function(opts) {
if (opts.disableLargeFees) {
return;
}
var fee = this._getUnspentValue();
var maximumFee = Math.floor(Transaction.FEE_SECURITY_MARGIN * this._estimateFee());
if (fee > maximumFee) {
return 'expected less than ' + maximumFee + ' but got ' + fee;
if (this._missingChange()) {
return new errors.Transaction.ChangeAddressMissing('Fee is too large and no change address was provided');
}
return new errors.Transaction.FeeError.TooLarge('expected less than ' + maximumFee + ' but got ' + fee);
}
};
Transaction.prototype._isFeeTooSmall = function() {
Transaction.prototype._isFeeTooSmall = function(opts) {
if (opts.disableSmallFees) {
return;
}
var fee = this._getUnspentValue();
var minimumFee = Math.ceil(this._estimateFee() / Transaction.FEE_SECURITY_MARGIN);
if (fee < minimumFee) {
return 'expected more than ' + minimumFee + ' but got ' + fee;
return new errors.Transaction.FeeError.TooSmall('expected more than ' + minimumFee + ' but got ' + fee);
}
};
@ -254,15 +249,35 @@ Transaction.prototype._missingChange = function() {
return !this._changeScript;
};
Transaction.prototype._hasDustOutputs = function() {
Transaction.prototype._hasDustOutputs = function(opts) {
if (opts.disableDustOutputs) {
return;
}
var index, output;
for (index in this.outputs) {
output = this.outputs[index];
if (output.satoshis < Transaction.DUST_AMOUNT && !output.script.isDataOut()) {
return true;
return new errors.Transaction.DustOutputs();
}
}
return false;
};
Transaction.prototype._isMissingSignatures = function(opts) {
if (opts.disableIsFullySigned) {
return;
}
if (!this.isFullySigned()) {
return new errors.Transaction.MissingSignatures();
}
};
Transaction.prototype._hasMoreOutputThanInput = function(opts) {
if (opts.disableMoreOutputThanInput) {
return;
}
if (this._getUnspentValue() < 0) {
return new errors.Transaction.InvalidOutputAmountSum();
}
};
Transaction.prototype.inspect = function() {