wallet: increaseFee call.

This commit is contained in:
Christopher Jeffrey 2016-10-27 14:44:35 -07:00
parent a4a408a18d
commit cc58b507eb
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 95 additions and 3 deletions

View File

@ -482,7 +482,7 @@ Wallet.prototype.retoken = co(function* retoken(passphrase) {
*/
Wallet.prototype._retoken = co(function* retoken(passphrase) {
var master = yield this.unlock(passphrase);
yield this.unlock(passphrase);
this.tokenDepth++;
this.token = this.getToken(this.tokenDepth);
@ -1483,6 +1483,99 @@ Wallet.prototype._send = co(function* send(options, passphrase) {
return tx;
});
/**
* Intentionally double-spend outputs by
* increasing fee for an existing transaction.
* @param {Hash} hash
* @param {Rate} rate
* @param {(String|Buffer)?} passphrase
* @returns {Promise} - Returns {@link TX}.
*/
Wallet.prototype.increaseFee = co(function* increaseFee(hash, rate, passphrase) {
var tx = yield this.getTX(hash);
var i, oldFee, fee, path, input, output, change;
if (!tx)
throw new Error('Transaction not found.');
if (tx.isCoinbase())
throw new Error('Transaction is a coinbase.');
yield this.fillHistory(tx);
if (!tx.hasCoins())
throw new Error('Not all coins available.');
if (!utils.isUInt32(rate))
throw new Error('Rate must be a number.');
oldFee = tx.getFee();
fee = tx.getMinFee(null, rate);
if (fee > constants.tx.MAX_FEE)
fee = constants.tx.MAX_FEE;
if (oldFee >= fee)
throw new Error('Fee is not increasing.');
tx = MTX.fromRaw(tx.toRaw());
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
input.script.length = 0;
input.script.compile();
input.witness.length = 0;
input.witness.compile();
}
for (i = 0; i < tx.outputs.length; i++) {
output = tx.outputs[i];
path = yield this.getPath(output.getAddress());
if (!path)
continue;
if (path.branch === 1) {
change = output;
tx.changeIndex = i;
break;
}
}
if (!change)
throw new Error('No change output.');
change.value += oldFee;
if (tx.getFee() !== 0)
throw new Error('Arithmetic error for change.');
change.value -= fee;
if (change.value < 0)
throw new Error('Fee is too high.');
if (change.isDust(constants.tx.MIN_RELAY)) {
tx.outputs.splice(tx.changeIndex, 1);
tx.changeIndex = -1;
}
yield this.sign(tx, passphrase);
if (!tx.isSigned())
throw new Error('TX could not be fully signed.');
tx = tx.toTX();
this.logger.debug('Increasing fee for wallet tx (%s): %s', this.id, tx.rhash);
yield this.db.addTX(tx);
yield this.db.send(tx);
return tx;
});
/**
* Resend pending wallet transactions.
* @returns {Promise}

View File

@ -1724,7 +1724,7 @@ WalletDB.prototype.rollback = co(function* rollback(height) {
*/
WalletDB.prototype.revert = co(function* revert(height) {
var i, iter, item, height, block, tx;
var i, iter, item, block, tx;
iter = this.db.iterator({
gte: layout.b(height + 1),
@ -1739,7 +1739,6 @@ WalletDB.prototype.revert = co(function* revert(height) {
break;
try {
height = layout.bb(item.key);
block = BlockMapRecord.fromRaw(item.value);
for (i = block.txs.length - 1; i >= 0; i--) {