funding error.

This commit is contained in:
Christopher Jeffrey 2016-06-21 16:54:49 -07:00
parent c03f704018
commit 4b1915ca49
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
4 changed files with 52 additions and 13 deletions

View File

@ -16,7 +16,7 @@ var constants = bcoin.protocol.constants;
* a mempool transaction validation error or a blockchain * a mempool transaction validation error or a blockchain
* block verification error. Ultimately used to send * block verification error. Ultimately used to send
* `reject` packets to peers. * `reject` packets to peers.
* @global * @exports VerifyError
* @constructor * @constructor
* @extends Error * @extends Error
* @param {Block|TX} msg * @param {Block|TX} msg
@ -64,7 +64,7 @@ utils.inherits(VerifyError, Error);
/** /**
* An error thrown from the scripting system, * An error thrown from the scripting system,
* potentially pertaining to Script execution. * potentially pertaining to Script execution.
* @global * @exports ScriptError
* @constructor * @constructor
* @extends Error * @extends Error
* @param {String} code - Error code. * @param {String} code - Error code.
@ -111,9 +111,40 @@ function ScriptError(code, op, ip) {
utils.inherits(ScriptError, Error); utils.inherits(ScriptError, Error);
/**
* An error thrown from the coin selector.
* @exports FundingError
* @constructor
* @extends Error
* @param {String} msg
* @param {Amount} available
* @param {Amount} required
* @property {String} message - Error message.
* @property {Amount} availableFunds
* @property {Amount} requiredFunds
*/
function FundingError(msg, available, required) {
Error.call(this);
if (Error.captureStackTrace)
Error.captureStackTrace(this, FundingError);
msg += ' (available=' + utils.btc(available) + ',';
msg += ' required=' + utils.btc(required) + ')';
this.type = 'FundingError';
this.message = msg;
this.availableFunds = available;
this.requiredFunds = required;
}
utils.inherits(FundingError, Error);
/* /*
* Expose * Expose
*/ */
exports.VerifyError = VerifyError; exports.VerifyError = VerifyError;
exports.ScriptError = ScriptError; exports.ScriptError = ScriptError;
exports.FundingError = FundingError;

View File

@ -540,7 +540,9 @@ KeyRing.prototype.toJSON = function toJSON() {
index: this.index, index: this.index,
key: utils.toBase58(this.key), key: utils.toBase58(this.key),
keys: this.keys.map(utils.toBase58), keys: this.keys.map(utils.toBase58),
address: this.getAddress() keyAddress: this.getKeyAddress(),
scriptAddress: this.getScriptAddress(),
programAddress: this.getProgramAddress()
}; };
}; };

View File

@ -14,6 +14,7 @@ var constants = bcoin.protocol.constants;
var Script = bcoin.script; var Script = bcoin.script;
var opcodes = constants.opcodes; var opcodes = constants.opcodes;
var HASH160 = constants.ZERO_HASH.slice(0, 20); var HASH160 = constants.ZERO_HASH.slice(0, 20);
var FundingError = bcoin.errors.FundingError;
/** /**
* A mutable transaction object. * A mutable transaction object.
@ -964,7 +965,7 @@ MTX.prototype.selectCoins = function selectCoins(coins, options) {
var index = 0; var index = 0;
var tx = this.clone(); var tx = this.clone();
var outputValue = tx.getOutputValue(); var outputValue = tx.getOutputValue();
var tryFree, i, size, change, fee, min, output, err; var tryFree, i, size, change, fee, min, output;
if (!options) if (!options)
options = {}; options = {};
@ -1030,6 +1031,9 @@ MTX.prototype.selectCoins = function selectCoins(coins, options) {
if (options.fee != null) { if (options.fee != null) {
fee = options.fee; fee = options.fee;
if (fee > constants.tx.MAX_FEE)
fee = constants.tx.MAX_FEE;
// Transfer `total` funds maximum. // Transfer `total` funds maximum.
addCoins(); addCoins();
} else { } else {
@ -1072,6 +1076,9 @@ MTX.prototype.selectCoins = function selectCoins(coins, options) {
else else
fee = tx.getMinFee(size, options.rate); fee = tx.getMinFee(size, options.rate);
if (fee > constants.tx.MAX_FEE)
fee = constants.tx.MAX_FEE;
// Failed to get enough funds, add more coins. // Failed to get enough funds, add more coins.
if (!isFull()) if (!isFull())
addCoins(); addCoins();
@ -1080,14 +1087,12 @@ MTX.prototype.selectCoins = function selectCoins(coins, options) {
if (!isFull()) { if (!isFull()) {
// Still failing to get enough funds. // Still failing to get enough funds.
err = new Error('Could not select coins.'); throw new FundingError(
err.requiredFunds = total(); 'Not enough funds.',
throw err; tx.getInputValue(),
total());
} }
if (fee > constants.tx.MAX_FEE)
fee = constants.tx.MAX_FEE;
// How much money is left after filling outputs. // How much money is left after filling outputs.
change = tx.getInputValue() - total(); change = tx.getInputValue() - total();

View File

@ -1188,12 +1188,12 @@ Pool.prototype._handleTX = function _handleTX(tx, peer, callback) {
} }
} }
if (!self.mempool) { if (!this.mempool) {
self.emit('tx', tx, peer); this.emit('tx', tx, peer);
return callback(); return callback();
} }
self.mempool.addTX(tx, function(err) { this.mempool.addTX(tx, function(err) {
if (err) { if (err) {
if (err.type === 'VerifyError') { if (err.type === 'VerifyError') {
if (err.score !== -1) if (err.score !== -1)
@ -1201,6 +1201,7 @@ Pool.prototype._handleTX = function _handleTX(tx, peer, callback) {
self.rejects.add(tx.hash()); self.rejects.add(tx.hash());
return callback(err); return callback(err);
} }
return callback(err);
} }
self.emit('tx', tx, peer); self.emit('tx', tx, peer);