wallet/mtx: fix fee checking and refactor some mtx functions.
This commit is contained in:
parent
fa8ec48bc5
commit
8987c0d870
@ -395,6 +395,30 @@ Input.fromRaw = function fromRaw(data, enc) {
|
|||||||
return new Input().fromRaw(data);
|
return new Input().fromRaw(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject properties from outpoint.
|
||||||
|
* @private
|
||||||
|
* @param {Outpoint} outpoint
|
||||||
|
*/
|
||||||
|
|
||||||
|
Input.prototype.fromOutpoint = function fromOutpoint(outpoint) {
|
||||||
|
assert(typeof outpoint.hash === 'string');
|
||||||
|
assert(typeof outpoint.index === 'number');
|
||||||
|
this.prevout.hash = outpoint.hash;
|
||||||
|
this.prevout.index = outpoint.index;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate input from outpoint.
|
||||||
|
* @param {Outpoint}
|
||||||
|
* @returns {Input}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Input.fromOutpoint = function fromOutpoint(outpoint) {
|
||||||
|
return new Input().fromOutpoint(outpoint);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inject properties from coin.
|
* Inject properties from coin.
|
||||||
* @private
|
* @private
|
||||||
|
|||||||
@ -124,6 +124,62 @@ MTX.prototype.clone = function clone() {
|
|||||||
return new MTX(this);
|
return new MTX(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an outpoint as an input.
|
||||||
|
* @param {Outpoint} outpoint
|
||||||
|
*/
|
||||||
|
|
||||||
|
MTX.prototype.addOutpoint = function addOutpoint(outpoint) {
|
||||||
|
var input = Input.fromOutpoint(outpoint);
|
||||||
|
this.inputs.push(input);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a coin as an input.
|
||||||
|
* @param {Coin} coin
|
||||||
|
*/
|
||||||
|
|
||||||
|
MTX.prototype.addCoin = function addCoin(coin) {
|
||||||
|
var input;
|
||||||
|
|
||||||
|
assert(coin instanceof Coin, 'Cannot add non-coin.');
|
||||||
|
|
||||||
|
input = Input.fromCoin(coin);
|
||||||
|
|
||||||
|
this.inputs.push(input);
|
||||||
|
|
||||||
|
this.view.addCoin(coin);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a transaction as an input.
|
||||||
|
* @param {TX} tx
|
||||||
|
* @param {Number} index
|
||||||
|
* @param {Number?} height
|
||||||
|
*/
|
||||||
|
|
||||||
|
MTX.prototype.addTX = function addTX(tx, index, height) {
|
||||||
|
var input, coin;
|
||||||
|
|
||||||
|
assert(tx instanceof TX, 'Cannot add non-transaction.');
|
||||||
|
|
||||||
|
if (height == null)
|
||||||
|
height = -1;
|
||||||
|
|
||||||
|
input = Input.fromTX(tx, index);
|
||||||
|
|
||||||
|
this.inputs.push(input);
|
||||||
|
|
||||||
|
coin = Coin.fromTX(tx, index, height);
|
||||||
|
|
||||||
|
this.view.addCoin(coin);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an input to the transaction.
|
* Add an input to the transaction.
|
||||||
* @example
|
* @example
|
||||||
@ -1367,6 +1423,27 @@ MTX.prototype.toTX = function toTX() {
|
|||||||
return new TX(this);
|
return new TX(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject properties from transaction.
|
||||||
|
* @private
|
||||||
|
* @param {TX} tx
|
||||||
|
* @returns {MTX}
|
||||||
|
*/
|
||||||
|
|
||||||
|
MTX.prototype.fromTX = function fromTX(tx, view) {
|
||||||
|
return this.fromRaw(tx.toRaw());
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate MTX from TX.
|
||||||
|
* @param {TX} tx
|
||||||
|
* @returns {MTX}
|
||||||
|
*/
|
||||||
|
|
||||||
|
MTX.fromTX = function fromTX(tx) {
|
||||||
|
return new MTX().fromTX(tx);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test whether an object is an MTX.
|
* Test whether an object is an MTX.
|
||||||
* @param {Object} obj
|
* @param {Object} obj
|
||||||
@ -1787,25 +1864,30 @@ function sortRandom(a, b) {
|
|||||||
function sortInputs(a, b) {
|
function sortInputs(a, b) {
|
||||||
var ahash = util.revHex(a.prevout.hash);
|
var ahash = util.revHex(a.prevout.hash);
|
||||||
var bhash = util.revHex(b.prevout.hash);
|
var bhash = util.revHex(b.prevout.hash);
|
||||||
var res = util.strcmp(ahash, bhash);
|
var cmp = util.strcmp(ahash, bhash);
|
||||||
|
|
||||||
if (res !== 0)
|
if (cmp !== 0)
|
||||||
return res;
|
return cmp;
|
||||||
|
|
||||||
return a.prevout.index - b.prevout.index;
|
return a.prevout.index - b.prevout.index;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sortOutputs(a, b) {
|
function sortOutputs(a, b) {
|
||||||
var res = a.value - b.value;
|
var cmp = a.value - b.value;
|
||||||
|
|
||||||
if (res !== 0)
|
if (cmp !== 0)
|
||||||
return res;
|
return cmp;
|
||||||
|
|
||||||
return util.cmp(a.script.raw, b.script.raw);
|
return util.cmp(a.script.toRaw(), b.script.toRaw());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expose
|
* Expose
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports = MTX;
|
exports = MTX;
|
||||||
|
exports.MTX = MTX;
|
||||||
|
exports.Selector = CoinSelector;
|
||||||
|
exports.FundingError = FundingError;
|
||||||
|
|
||||||
|
module.exports = exports;
|
||||||
|
|||||||
@ -1363,7 +1363,7 @@ Wallet.prototype._importAddress = co(function* importAddress(acct, address) {
|
|||||||
* transaction size, calculate fee, and add a change output.
|
* transaction size, calculate fee, and add a change output.
|
||||||
* @see MTX#selectCoins
|
* @see MTX#selectCoins
|
||||||
* @see MTX#fill
|
* @see MTX#fill
|
||||||
* @param {MTX} tx - _Must_ be a mutable transaction.
|
* @param {MTX} mtx - _Must_ be a mutable transaction.
|
||||||
* @param {Object?} options
|
* @param {Object?} options
|
||||||
* @param {(String|Number)?} options.account - If no account is
|
* @param {(String|Number)?} options.account - If no account is
|
||||||
* specified, coins from the entire wallet will be filled.
|
* specified, coins from the entire wallet will be filled.
|
||||||
@ -1382,10 +1382,10 @@ Wallet.prototype._importAddress = co(function* importAddress(acct, address) {
|
|||||||
* fee from existing outputs rather than adding more inputs.
|
* fee from existing outputs rather than adding more inputs.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Wallet.prototype.fund = co(function* fund(tx, options, force) {
|
Wallet.prototype.fund = co(function* fund(mtx, options, force) {
|
||||||
var unlock = yield this.fundLock.lock(force);
|
var unlock = yield this.fundLock.lock(force);
|
||||||
try {
|
try {
|
||||||
return yield this._fund(tx, options);
|
return yield this._fund(mtx, options);
|
||||||
} finally {
|
} finally {
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
@ -1398,7 +1398,7 @@ Wallet.prototype.fund = co(function* fund(tx, options, force) {
|
|||||||
* @see MTX#fill
|
* @see MTX#fill
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Wallet.prototype._fund = co(function* fund(tx, options) {
|
Wallet.prototype._fund = co(function* fund(mtx, options) {
|
||||||
var rate, account, coins;
|
var rate, account, coins;
|
||||||
|
|
||||||
if (!options)
|
if (!options)
|
||||||
@ -1431,7 +1431,7 @@ Wallet.prototype._fund = co(function* fund(tx, options) {
|
|||||||
// Don't use any locked coins.
|
// Don't use any locked coins.
|
||||||
coins = this.txdb.filterLocked(coins);
|
coins = this.txdb.filterLocked(coins);
|
||||||
|
|
||||||
yield tx.fund(coins, {
|
yield mtx.fund(coins, {
|
||||||
selection: options.selection,
|
selection: options.selection,
|
||||||
round: options.round,
|
round: options.round,
|
||||||
depth: options.depth,
|
depth: options.depth,
|
||||||
@ -1443,6 +1443,8 @@ Wallet.prototype._fund = co(function* fund(tx, options) {
|
|||||||
maxFee: options.maxFee,
|
maxFee: options.maxFee,
|
||||||
estimate: this.estimateSize.bind(this)
|
estimate: this.estimateSize.bind(this)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
assert(mtx.getFee() <= MTX.Selector.MAX_FEE, 'TX exceeds MAX_FEE.');
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1550,48 +1552,43 @@ Wallet.prototype.estimateSize = co(function* estimateSize(prev) {
|
|||||||
|
|
||||||
Wallet.prototype.createTX = co(function* createTX(options, force) {
|
Wallet.prototype.createTX = co(function* createTX(options, force) {
|
||||||
var outputs = options.outputs;
|
var outputs = options.outputs;
|
||||||
var i, tx, output, total;
|
var mtx = new MTX();
|
||||||
|
var i, output, total;
|
||||||
|
|
||||||
assert(Array.isArray(outputs), 'Outputs must be an array.');
|
assert(Array.isArray(outputs), 'Outputs must be an array.');
|
||||||
|
assert(outputs.length > 0, 'No outputs available.');
|
||||||
if (outputs.length === 0)
|
|
||||||
throw new Error('No outputs available.');
|
|
||||||
|
|
||||||
// Create mutable tx
|
|
||||||
tx = new MTX();
|
|
||||||
|
|
||||||
// Add the outputs
|
// Add the outputs
|
||||||
for (i = 0; i < outputs.length; i++) {
|
for (i = 0; i < outputs.length; i++) {
|
||||||
output = new Output(outputs[i]);
|
output = new Output(outputs[i]);
|
||||||
|
output.mutable = true;
|
||||||
|
|
||||||
if (output.isDust())
|
if (output.isDust())
|
||||||
throw new Error('Output is dust.');
|
throw new Error('Output is dust.');
|
||||||
|
|
||||||
tx.outputs.push(output);
|
mtx.outputs.push(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill the inputs with unspents
|
// Fill the inputs with unspents
|
||||||
yield this.fund(tx, options, force);
|
yield this.fund(mtx, options, force);
|
||||||
|
|
||||||
// Sort members a la BIP69
|
// Sort members a la BIP69
|
||||||
tx.sortMembers();
|
mtx.sortMembers();
|
||||||
|
|
||||||
// Set the locktime to target value.
|
// Set the locktime to target value.
|
||||||
if (options.locktime != null)
|
if (options.locktime != null)
|
||||||
tx.setLocktime(options.locktime);
|
mtx.setLocktime(options.locktime);
|
||||||
|
|
||||||
if (!tx.isSane())
|
// Consensus sanity checks.
|
||||||
throw new Error('CheckTransaction failed.');
|
assert(mtx.isSane(), 'TX failed sanity check.');
|
||||||
|
assert(mtx.checkInputs(this.db.state.height + 1), 'CheckInputs failed.');
|
||||||
|
|
||||||
if (!tx.checkInputs(this.db.state.height + 1))
|
total = yield this.template(mtx);
|
||||||
throw new Error('CheckInputs failed.');
|
|
||||||
|
|
||||||
total = yield this.template(tx);
|
|
||||||
|
|
||||||
if (total === 0)
|
if (total === 0)
|
||||||
throw new Error('Templating failed.');
|
throw new Error('Templating failed.');
|
||||||
|
|
||||||
return tx;
|
return mtx;
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1630,11 +1627,9 @@ Wallet.prototype._send = co(function* send(options, passphrase) {
|
|||||||
if (!mtx.isSigned())
|
if (!mtx.isSigned())
|
||||||
throw new Error('TX could not be fully signed.');
|
throw new Error('TX could not be fully signed.');
|
||||||
|
|
||||||
assert(mtx.getFee() <= MTX.MAX_FEE, 'TX exceeds maxfee.');
|
|
||||||
|
|
||||||
tx = mtx.toTX();
|
tx = mtx.toTX();
|
||||||
|
|
||||||
// Sanity checks.
|
// Policy sanity checks.
|
||||||
if (tx.getSigopsCost(mtx.view) > policy.MAX_TX_SIGOPS_COST)
|
if (tx.getSigopsCost(mtx.view) > policy.MAX_TX_SIGOPS_COST)
|
||||||
throw new Error('TX exceeds policy sigops.');
|
throw new Error('TX exceeds policy sigops.');
|
||||||
|
|
||||||
@ -1661,11 +1656,16 @@ Wallet.prototype._send = co(function* send(options, passphrase) {
|
|||||||
|
|
||||||
Wallet.prototype.increaseFee = co(function* increaseFee(hash, rate, passphrase) {
|
Wallet.prototype.increaseFee = co(function* increaseFee(hash, rate, passphrase) {
|
||||||
var wtx = yield this.getTX(hash);
|
var wtx = yield this.getTX(hash);
|
||||||
var i, tx, view, oldFee, fee, path, input, output, change;
|
var i, tx, mtx, view, oldFee, fee, path, input, output, change;
|
||||||
|
|
||||||
|
assert(util.isUInt32(rate), 'Rate must be a number.');
|
||||||
|
|
||||||
if (!wtx)
|
if (!wtx)
|
||||||
throw new Error('Transaction not found.');
|
throw new Error('Transaction not found.');
|
||||||
|
|
||||||
|
if (wtx.height !== -1)
|
||||||
|
throw new Error('Transaction is confirmed.');
|
||||||
|
|
||||||
tx = wtx.tx;
|
tx = wtx.tx;
|
||||||
|
|
||||||
if (tx.isCoinbase())
|
if (tx.isCoinbase())
|
||||||
@ -1676,31 +1676,28 @@ Wallet.prototype.increaseFee = co(function* increaseFee(hash, rate, passphrase)
|
|||||||
if (!tx.hasCoins(view))
|
if (!tx.hasCoins(view))
|
||||||
throw new Error('Not all coins available.');
|
throw new Error('Not all coins available.');
|
||||||
|
|
||||||
if (!util.isUInt32(rate))
|
|
||||||
throw new Error('Rate must be a number.');
|
|
||||||
|
|
||||||
oldFee = tx.getFee(view);
|
oldFee = tx.getFee(view);
|
||||||
fee = tx.getMinFee(null, rate);
|
fee = tx.getMinFee(null, rate);
|
||||||
|
|
||||||
if (fee > MTX.MAX_FEE)
|
if (fee > MTX.Selector.MAX_FEE)
|
||||||
fee = MTX.MAX_FEE;
|
fee = MTX.Selector.MAX_FEE;
|
||||||
|
|
||||||
if (oldFee >= fee)
|
if (oldFee >= fee)
|
||||||
throw new Error('Fee is not increasing.');
|
throw new Error('Fee is not increasing.');
|
||||||
|
|
||||||
tx = MTX.fromRaw(tx.toRaw());
|
mtx = MTX.fromTX(tx);
|
||||||
tx.view = view;
|
mtx.view = view;
|
||||||
|
|
||||||
for (i = 0; i < tx.inputs.length; i++) {
|
for (i = 0; i < mtx.inputs.length; i++) {
|
||||||
input = tx.inputs[i];
|
input = mtx.inputs[i];
|
||||||
input.script.length = 0;
|
input.script.length = 0;
|
||||||
input.script.compile();
|
input.script.compile();
|
||||||
input.witness.length = 0;
|
input.witness.length = 0;
|
||||||
input.witness.compile();
|
input.witness.compile();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < tx.outputs.length; i++) {
|
for (i = 0; i < mtx.outputs.length; i++) {
|
||||||
output = tx.outputs[i];
|
output = mtx.outputs[i];
|
||||||
path = yield this.getPath(output.getAddress());
|
path = yield this.getPath(output.getAddress());
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
@ -1708,7 +1705,7 @@ Wallet.prototype.increaseFee = co(function* increaseFee(hash, rate, passphrase)
|
|||||||
|
|
||||||
if (path.branch === 1) {
|
if (path.branch === 1) {
|
||||||
change = output;
|
change = output;
|
||||||
tx.changeIndex = i;
|
mtx.changeIndex = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1718,7 +1715,7 @@ Wallet.prototype.increaseFee = co(function* increaseFee(hash, rate, passphrase)
|
|||||||
|
|
||||||
change.value += oldFee;
|
change.value += oldFee;
|
||||||
|
|
||||||
if (tx.getFee() !== 0)
|
if (mtx.getFee() !== 0)
|
||||||
throw new Error('Arithmetic error for change.');
|
throw new Error('Arithmetic error for change.');
|
||||||
|
|
||||||
change.value -= fee;
|
change.value -= fee;
|
||||||
@ -1727,18 +1724,20 @@ Wallet.prototype.increaseFee = co(function* increaseFee(hash, rate, passphrase)
|
|||||||
throw new Error('Fee is too high.');
|
throw new Error('Fee is too high.');
|
||||||
|
|
||||||
if (change.isDust()) {
|
if (change.isDust()) {
|
||||||
tx.outputs.splice(tx.changeIndex, 1);
|
mtx.outputs.splice(mtx.changeIndex, 1);
|
||||||
tx.changeIndex = -1;
|
mtx.changeIndex = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
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.');
|
throw new Error('TX could not be fully signed.');
|
||||||
|
|
||||||
tx = tx.toTX();
|
tx = mtx.toTX();
|
||||||
|
|
||||||
this.logger.debug('Increasing fee for wallet tx (%s): %s', this.id, tx.txid());
|
this.logger.debug(
|
||||||
|
'Increasing fee for wallet tx (%s): %s',
|
||||||
|
this.id, tx.txid());
|
||||||
|
|
||||||
yield this.db.addTX(tx);
|
yield this.db.addTX(tx);
|
||||||
yield this.db.send(tx);
|
yield this.db.send(tx);
|
||||||
@ -1768,18 +1767,18 @@ Wallet.prototype.resend = co(function* resend() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Derive necessary addresses for signing a transaction.
|
* Derive necessary addresses for signing a transaction.
|
||||||
* @param {TX|Input} tx
|
* @param {MTX} mtx
|
||||||
* @param {Number?} index - Input index.
|
* @param {Number?} index - Input index.
|
||||||
* @returns {Promise} - Returns {@link WalletKey}[].
|
* @returns {Promise} - Returns {@link WalletKey}[].
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Wallet.prototype.deriveInputs = co(function* deriveInputs(tx) {
|
Wallet.prototype.deriveInputs = co(function* deriveInputs(mtx) {
|
||||||
var rings = [];
|
var rings = [];
|
||||||
var i, paths, path, account, ring;
|
var i, paths, path, account, ring;
|
||||||
|
|
||||||
assert(tx.mutable);
|
assert(mtx.mutable);
|
||||||
|
|
||||||
paths = yield this.getInputPaths(tx);
|
paths = yield this.getInputPaths(mtx);
|
||||||
|
|
||||||
for (i = 0; i < paths.length; i++) {
|
for (i = 0; i < paths.length; i++) {
|
||||||
path = paths[i];
|
path = paths[i];
|
||||||
@ -1860,20 +1859,20 @@ Wallet.prototype.getPrivateKey = co(function* getPrivateKey(address, passphrase)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Map input addresses to paths.
|
* Map input addresses to paths.
|
||||||
* @param {TX} tx
|
* @param {MTX} mtx
|
||||||
* @returns {Promise} - Returns {@link Path}[].
|
* @returns {Promise} - Returns {@link Path}[].
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Wallet.prototype.getInputPaths = co(function* getInputPaths(tx) {
|
Wallet.prototype.getInputPaths = co(function* getInputPaths(mtx) {
|
||||||
var paths = [];
|
var paths = [];
|
||||||
var i, hashes, hash, path;
|
var i, hashes, hash, path;
|
||||||
|
|
||||||
assert(tx.mutable);
|
assert(mtx.mutable);
|
||||||
|
|
||||||
if (!tx.hasCoins())
|
if (!mtx.hasCoins())
|
||||||
throw new Error('Not all coins available.');
|
throw new Error('Not all coins available.');
|
||||||
|
|
||||||
hashes = tx.getInputHashes('hex');
|
hashes = mtx.getInputHashes('hex');
|
||||||
|
|
||||||
for (i = 0; i < hashes.length; i++) {
|
for (i = 0; i < hashes.length; i++) {
|
||||||
hash = hashes[i];
|
hash = hashes[i];
|
||||||
@ -2058,14 +2057,14 @@ Wallet.prototype.getRedeem = co(function* getRedeem(hash) {
|
|||||||
* Build input scripts templates for a transaction (does not
|
* Build input scripts templates for a transaction (does not
|
||||||
* sign, only creates signature slots). Only builds scripts
|
* sign, only creates signature slots). Only builds scripts
|
||||||
* for inputs that are redeemable by this wallet.
|
* for inputs that are redeemable by this wallet.
|
||||||
* @param {MTX} tx
|
* @param {MTX} mtx
|
||||||
* @returns {Promise} - Returns Number
|
* @returns {Promise} - Returns Number
|
||||||
* (total number of scripts built).
|
* (total number of scripts built).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Wallet.prototype.template = co(function* template(tx) {
|
Wallet.prototype.template = co(function* template(mtx) {
|
||||||
var rings = yield this.deriveInputs(tx);
|
var rings = yield this.deriveInputs(mtx);
|
||||||
return tx.template(rings);
|
return mtx.template(rings);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2077,7 +2076,7 @@ Wallet.prototype.template = co(function* template(tx) {
|
|||||||
* of inputs scripts built and signed).
|
* of inputs scripts built and signed).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Wallet.prototype.sign = co(function* sign(tx, passphrase) {
|
Wallet.prototype.sign = co(function* sign(mtx, passphrase) {
|
||||||
var rings;
|
var rings;
|
||||||
|
|
||||||
if (this.watchOnly)
|
if (this.watchOnly)
|
||||||
@ -2085,9 +2084,9 @@ Wallet.prototype.sign = co(function* sign(tx, passphrase) {
|
|||||||
|
|
||||||
yield this.unlock(passphrase);
|
yield this.unlock(passphrase);
|
||||||
|
|
||||||
rings = yield this.deriveInputs(tx);
|
rings = yield this.deriveInputs(mtx);
|
||||||
|
|
||||||
return yield tx.signAsync(rings);
|
return yield mtx.signAsync(rings);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -613,7 +613,7 @@ describe('Wallet', function() {
|
|||||||
tx.addOutput(to.getAddress(), 5460);
|
tx.addOutput(to.getAddress(), 5460);
|
||||||
|
|
||||||
cost = tx.getOutputValue();
|
cost = tx.getOutputValue();
|
||||||
total = cost * MTX.MIN_FEE;
|
total = cost * 10000;
|
||||||
|
|
||||||
coins1 = yield w1.getCoins();
|
coins1 = yield w1.getCoins();
|
||||||
coins2 = yield w2.getCoins();
|
coins2 = yield w2.getCoins();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user