async signing.

This commit is contained in:
Christopher Jeffrey 2016-07-15 08:36:37 -07:00
parent 33d2803d4c
commit b81a6b3ea1
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
3 changed files with 68 additions and 15 deletions

View File

@ -1324,10 +1324,16 @@ MTX.fromRaw = function fromRaw(data, enc) {
* @see TX.fromExtended
*/
MTX.fromExtended = function fromExtended(data, enc) {
MTX.fromExtended = function fromExtended(data, saveCoins, enc) {
if (typeof saveCoins === 'string') {
enc = saveCoins;
saveCoins = false;
}
if (typeof data === 'string')
data = new Buffer(data, enc);
return new MTX().fromExtended(data)._mutable();
return new MTX().fromExtended(data, saveCoins)._mutable();
};
/**

View File

@ -50,6 +50,7 @@ function Wallet(db, options) {
this.db = db;
this.network = db.network;
this.workerPool = db.workerPool;
this.writeLock = new bcoin.locker(this);
this.fillLock = new bcoin.locker(this);
@ -1142,17 +1143,16 @@ Wallet.prototype.scriptInputs = function scriptInputs(tx, callback) {
* Build input scripts and sign inputs for a transaction. Only attempts
* to build/sign inputs that are redeemable by this wallet.
* @param {MTX} tx
* @param {Number?} index - Index of input. If not present,
* @param {Object|String|Buffer} options - Options or passphrase.
* @param {Number?} options.index - Index of input. If not present,
* it will attempt to build and sign all redeemable inputs.
* @param {SighashType?} type
* @param {SighashType?} options.type
* @param {Function} callback - Returns [Error, Number] (total number
* of inputs scripts built and signed).
*/
Wallet.prototype.sign = function sign(tx, options, callback) {
var self = this;
var total = 0;
var i, address, key;
if (typeof options === 'function') {
callback = options;
@ -1170,19 +1170,62 @@ Wallet.prototype.sign = function sign(tx, options, callback) {
if (err)
return callback(err);
for (i = 0; i < addresses.length; i++) {
address = addresses[i];
key = master.deriveAccount44(address.account);
key = key.derive(address.change).derive(address.index);
assert(utils.equal(key.getPublicKey(), address.key));
total += address.sign(tx, key, options.index, options.type);
}
return callback(null, total);
self._sign(addresses, master, tx, options.index, options.type, callback);
});
});
};
/**
* Sign a transaction.
* @param {KeyRing[]} addresses
* @param {HDPrivateKey} master
* @param {MTX} tx
* @param {Number?} index
* @param {SighashType?} type
*/
Wallet.sign = function sign(addresses, master, tx, index, type) {
var total = 0;
var i, address, key;
for (i = 0; i < addresses.length; i++) {
address = addresses[i];
key = master.deriveAccount44(address.account);
key = key.derive(address.change).derive(address.index);
assert(utils.equal(key.getPublicKey(), address.key));
total += address.sign(tx, key, index, type);
}
return total;
};
/**
* Sign a transaction asynchronously.
* @param {KeyRing[]} addresses
* @param {HDPrivateKey} master
* @param {MTX} tx
* @param {Number?} index
* @param {SighashType?} type
* @param {Function} callback - Returns [Error, Number] (total number
* of inputs scripts built and signed).
*/
Wallet.prototype._sign = function _sign(addresses, master, tx, index, type, callback) {
var result;
if (!this.workerPool) {
callback = utils.asyncify(callback);
try {
result = Wallet.sign(addresses, master, tx, index, type);
} catch (e) {
return callback(e);
}
return callback(null, result);
}
this.workerPool.sign(addresses, master, tx, index, type, callback);
};
/**
* Fill transaction with coins (accesses db).
* @param {TX} tx

View File

@ -51,6 +51,7 @@ function WalletDB(options) {
this.fees = options.fees;
this.logger = options.logger || bcoin.defaultLogger;
this.batches = {};
this.workerPool = null;
// We need one read lock for `get` and `create`.
// It will hold locks specific to wallet ids.
@ -72,6 +73,9 @@ function WalletDB(options) {
useFilter: true
});
if (bcoin.useWorkers)
this.workerPool = new bcoin.workers();
this.watchers = {};
this._init();