|
|
@ -196,11 +196,15 @@ Transaction.prototype.getSerializationError = function(opts) { |
|
|
|
return new errors.Transaction.InvalidSatoshis(); |
|
|
|
} |
|
|
|
|
|
|
|
var feeIsDifferent = this._isFeeDifferent(); |
|
|
|
var missingChange = this._missingChange(); |
|
|
|
var feeIsTooLarge = this._isFeeTooLarge(); |
|
|
|
var feeIsTooSmall = this._isFeeTooSmall(); |
|
|
|
var isFullySigned = this.isFullySigned(); |
|
|
|
|
|
|
|
if (!opts.disableDifferentFees && feeIsDifferent) { |
|
|
|
return new errors.Transaction.FeeError(feeIsDifferent); |
|
|
|
} |
|
|
|
if (!opts.disableLargeFees && feeIsTooLarge) { |
|
|
|
if (missingChange) { |
|
|
|
return new errors.Transaction.ChangeAddressMissing('Fee is too large and no change address was provided'); |
|
|
@ -221,8 +225,17 @@ Transaction.prototype.getSerializationError = function(opts) { |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
Transaction.prototype._isFeeDifferent = function() { |
|
|
|
var fee = this.getFee(); |
|
|
|
var unspent = this._getUnspentValue(); |
|
|
|
if (fee !== unspent) { |
|
|
|
return 'Unspent value ' + unspent + ' is different from specified fee ' + |
|
|
|
fee + ' and no change address is specified'; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
Transaction.prototype._isFeeTooLarge = function() { |
|
|
|
var fee = this._getUnspentValue(); |
|
|
|
var fee = this.getFee(); |
|
|
|
var maximumFee = Math.floor(Transaction.FEE_SECURITY_MARGIN * this._estimateFee()); |
|
|
|
if (fee > maximumFee) { |
|
|
|
return 'Fee is too large: expected less than ' + maximumFee + ' but got ' + fee; |
|
|
@ -230,7 +243,7 @@ Transaction.prototype._isFeeTooLarge = function() { |
|
|
|
}; |
|
|
|
|
|
|
|
Transaction.prototype._isFeeTooSmall = function() { |
|
|
|
var fee = this._getUnspentValue(); |
|
|
|
var fee = this.getFee(); |
|
|
|
var minimumFee = Math.ceil(this._estimateFee() / Transaction.FEE_SECURITY_MARGIN); |
|
|
|
if (fee < minimumFee) { |
|
|
|
return 'Fee is too small: expected more than ' + minimumFee + ' but got ' + fee; |
|
|
@ -766,6 +779,8 @@ Transaction.prototype._updateChangeOutput = function() { |
|
|
|
/** |
|
|
|
* Calculates the fee of the transaction. |
|
|
|
* |
|
|
|
* If there's a fixed fee set, return that. |
|
|
|
* |
|
|
|
* If there is no change output set, the fee is the |
|
|
|
* total value of the outputs minus inputs. Note that |
|
|
|
* a serialized transaction only specifies the value |
|
|
@ -774,17 +789,20 @@ Transaction.prototype._updateChangeOutput = function() { |
|
|
|
* This method therefore raises a "MissingPreviousOutput" |
|
|
|
* error when called on a serialized transaction. |
|
|
|
* |
|
|
|
* If there's a fixed fee set, return that. |
|
|
|
* If there's no fee set, estimate it based on size. |
|
|
|
* If there's no fee set and no change address, |
|
|
|
* estimate the fee based on size. |
|
|
|
* |
|
|
|
* @return {Number} fee of this transaction in satoshis |
|
|
|
*/ |
|
|
|
Transaction.prototype.getFee = function() { |
|
|
|
if (!_.isUndefined(this._fee)) { |
|
|
|
return this._fee; |
|
|
|
} |
|
|
|
// if no change output is set, fees should equal all the unspent amount
|
|
|
|
if (!this._changeScript) { |
|
|
|
return this._getUnspentValue(); |
|
|
|
} |
|
|
|
return _.isUndefined(this._fee) ? this._estimateFee() : this._fee; |
|
|
|
return this._estimateFee(); |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|