refactor wallet and walletdb.

This commit is contained in:
Christopher Jeffrey 2016-06-02 03:34:13 -07:00
parent ac21ebd151
commit cde8fdafa6
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 212 additions and 216 deletions

View File

@ -477,7 +477,7 @@ Wallet.prototype.createAddress = function createAddress(account, change, callbac
*/ */
Wallet.prototype.save = function save(callback) { Wallet.prototype.save = function save(callback) {
this.db.save(this, callback); return this.db.save(this, callback);
}; };
/** /**
@ -487,7 +487,17 @@ Wallet.prototype.save = function save(callback) {
*/ */
Wallet.prototype.hasAddress = function hasAddress(address, callback) { Wallet.prototype.hasAddress = function hasAddress(address, callback) {
this.db.hasAddress(this.id, address, callback); return this.db.hasAddress(this.id, address, callback);
};
/**
* Get path by address hash.
* @param {Hash} address
* @param {Function} callback - Returns [Error, {@link Path}].
*/
Wallet.prototype.getPath = function getPath(address, callback) {
return this.db.getPath(this.id, address, callback);
}; };
/** /**
@ -570,37 +580,6 @@ Wallet.prototype.fill = function fill(tx, options, callback) {
}); });
}; };
/**
* Fill transaction with coins (accesses db).
* @param {TX} tx
* @param {Function} callback - Returns [Error, {@link TX}].
*/
Wallet.prototype.fillCoins = function fillCoins(tx, callback) {
return this.db.fillHistory(this.id, tx, callback);
};
/**
* Get a coin from the wallet (accesses db).
* @param {Hash} hash
* @param {Number} index
* @param {Function} callback - Returns [Error, {@link Coin}].
*/
Wallet.prototype.getCoin = function getCoin(hash, index, callback) {
return this.db.getCoin(hash, index, callback);
};
/**
* Get a transaction from the wallet (accesses db).
* @param {Hash} hash
* @param {Function} callback - Returns [Error, {@link TX}].
*/
Wallet.prototype.getTX = function getTX(hash, callback) {
return this.db.getTX(hash, callback);
};
/** /**
* Build a transaction, fill it with outputs and inputs, * Build a transaction, fill it with outputs and inputs,
* sort the members according to BIP69, set locktime, * sort the members according to BIP69, set locktime,
@ -713,16 +692,6 @@ Wallet.prototype.deriveInputs = function deriveInputs(tx, callback) {
}); });
}; };
/**
* Get path by address hash.
* @param {Hash} address
* @param {Function} callback - Returns [Error, {@link Path}].
*/
Wallet.prototype.getPath = function getPath(address, callback) {
this.db.getPath(this.id, address, callback);
};
/** /**
* Map input addresses to paths. * Map input addresses to paths.
* @param {TX|Input} tx * @param {TX|Input} tx
@ -806,7 +775,8 @@ Wallet.prototype.getOutputPaths = function getOutputPaths(tx, callback) {
Wallet.prototype.syncOutputDepth = function syncOutputDepth(tx, callback) { Wallet.prototype.syncOutputDepth = function syncOutputDepth(tx, callback) {
var self = this; var self = this;
var accounts = {}; var accounts = {};
var result = false; var change = [];
var receive = [];
var i, path, unlock; var i, path, unlock;
unlock = this.locker.lock(syncOutputDepth, [tx, callback]); unlock = this.locker.lock(syncOutputDepth, [tx, callback]);
@ -854,29 +824,24 @@ Wallet.prototype.syncOutputDepth = function syncOutputDepth(tx, callback) {
if (!account) if (!account)
return next(); return next();
account.setChangeDepth(depth.changeDepth + 1, function(err, res) { account.setDepth(depth.receiveDepth + 1, depth.changeDepth + 1, function(err, rec, chng) {
if (err) if (err)
return next(err); return next(err);
if (res) if (rec)
result = true; receive.push(rec);
account.setReceiveDepth(depth.receiveDepth + 1, function(err, res) { if (chng)
if (err) change.push(chng);
return next(err);
if (res) next();
result = true;
next();
});
}); });
}, true); }, true);
}, function(err) { }, function(err) {
if (err) if (err)
return callback(err); return callback(err);
return callback(null, result); return callback(null, receive, change);
}); });
}); });
}; };
@ -920,27 +885,6 @@ Wallet.prototype.getRedeem = function getRedeem(hash, callback) {
}); });
}; };
/**
* Zap stale TXs from wallet (accesses db).
* @param {(Number|String)?} account
* @param {Number} age - Age threshold (unix time, default=72 hours).
* @param {Function} callback - Returns [Error].
*/
Wallet.prototype.zap = function zap(account, age, callback) {
var self = this;
if (typeof age === 'function') {
callback = age;
age = account;
account = 0;
}
this._getKey(account, callback, function(id, callback) {
self.db.zap(id, age, callback);
});
};
/** /**
* Scan for active accounts and addresses. Used for importing a wallet. * Scan for active accounts and addresses. Used for importing a wallet.
* @param {Function} getByAddress - Must be a function which accepts * @param {Function} getByAddress - Must be a function which accepts
@ -1061,6 +1005,37 @@ Wallet.prototype.sign = function sign(tx, options, callback) {
}); });
}; };
/**
* Fill transaction with coins (accesses db).
* @param {TX} tx
* @param {Function} callback - Returns [Error, {@link TX}].
*/
Wallet.prototype.fillCoins = function fillCoins(tx, callback) {
return this.db.fillHistory(tx, callback);
};
/**
* Get a coin from the wallet (accesses db).
* @param {Hash} hash
* @param {Number} index
* @param {Function} callback - Returns [Error, {@link Coin}].
*/
Wallet.prototype.getCoin = function getCoin(hash, index, callback) {
return this.db.getCoin(hash, index, callback);
};
/**
* Get a transaction from the wallet (accesses db).
* @param {Hash} hash
* @param {Function} callback - Returns [Error, {@link TX}].
*/
Wallet.prototype.getTX = function getTX(hash, callback) {
return this.db.getTX(hash, callback);
};
/** /**
* Add a transaction to the wallets TX history (accesses db). * Add a transaction to the wallets TX history (accesses db).
* @param {TX} tx * @param {TX} tx
@ -1078,41 +1053,7 @@ Wallet.prototype.addTX = function addTX(tx, callback) {
*/ */
Wallet.prototype.getHistory = function getHistory(account, callback) { Wallet.prototype.getHistory = function getHistory(account, callback) {
var self = this; return this.db.getHistory(this.id, account, callback);
this._getKey(account, callback, function(id, callback) {
self.db.getHistory(id, callback);
});
};
/**
* Parse arguments and return an id
* consisting of `walletid/accountname`.
* @private
* @param {String|Number} account
* @param {Function} errback
* @param {Function} callback - Returns [String, Function].
*/
Wallet.prototype._getKey = function _getKey(account, errback, callback) {
var self = this;
if (typeof account === 'function') {
errback = account;
account = null;
}
if (account == null)
return callback(this.id, errback);
this.db.getAccountIndex(this.id, account, function(err, index) {
if (err)
return errback(err);
if (index === -1)
return errback(new Error('Account not found.'));
return callback(self.id + '/' + index, errback);
});
}; };
/** /**
@ -1122,10 +1063,7 @@ Wallet.prototype._getKey = function _getKey(account, errback, callback) {
*/ */
Wallet.prototype.getCoins = function getCoins(account, callback) { Wallet.prototype.getCoins = function getCoins(account, callback) {
var self = this; return this.db.getCoins(this.id, account, callback);
this._getKey(account, callback, function(id, callback) {
self.db.getCoins(id, callback);
});
}; };
/** /**
@ -1135,10 +1073,7 @@ Wallet.prototype.getCoins = function getCoins(account, callback) {
*/ */
Wallet.prototype.getUnconfirmed = function getUnconfirmed(account, callback) { Wallet.prototype.getUnconfirmed = function getUnconfirmed(account, callback) {
var self = this; return this.db.getUnconfirmed(this.id, account, callback);
this._getKey(account, callback, function(id, callback) {
self.db.getUnconfirmed(id, callback);
});
}; };
/** /**
@ -1148,10 +1083,7 @@ Wallet.prototype.getUnconfirmed = function getUnconfirmed(account, callback) {
*/ */
Wallet.prototype.getBalance = function getBalance(account, callback) { Wallet.prototype.getBalance = function getBalance(account, callback) {
var self = this; return this.db.getBalance(this.id, account, callback);
this._getKey(account, callback, function(id, callback) {
self.db.getBalance(id, callback);
});
}; };
/** /**
@ -1163,10 +1095,7 @@ Wallet.prototype.getBalance = function getBalance(account, callback) {
*/ */
Wallet.prototype.getLastTime = function getLastTime(account, callback) { Wallet.prototype.getLastTime = function getLastTime(account, callback) {
var self = this; return this.db.getLastTime(this.id, account, callback);
this._getKey(account, callback, function(id, callback) {
self.db.getLastTime(id, callback);
});
}; };
/** /**
@ -1177,17 +1106,7 @@ Wallet.prototype.getLastTime = function getLastTime(account, callback) {
*/ */
Wallet.prototype.getLast = function getLast(account, limit, callback) { Wallet.prototype.getLast = function getLast(account, limit, callback) {
var self = this; return this.db.getLast(this.id, account, limit, callback);
if (typeof limit === 'function') {
callback = limit;
limit = account;
account = null;
}
this._getKey(account, callback, function(id, callback) {
self.db.getLast(id, callback);
});
}; };
/** /**
@ -1200,17 +1119,18 @@ Wallet.prototype.getLast = function getLast(account, limit, callback) {
*/ */
Wallet.prototype.getTimeRange = function getTimeRange(account, options, callback) { Wallet.prototype.getTimeRange = function getTimeRange(account, options, callback) {
var self = this; return this.db.getTimeRange(this.id, account, options, callback);
};
if (typeof options === 'function') { /**
callback = options; * Zap stale TXs from wallet (accesses db).
options = account; * @param {(Number|String)?} account
account = null; * @param {Number} age - Age threshold (unix time, default=72 hours).
} * @param {Function} callback - Returns [Error].
*/
this._getKey(account, callback, function(id, callback) { Wallet.prototype.zap = function zap(account, age, callback) {
self.db.getTimeRange(id, options, callback); return this.db.zap(this.id, account, age, callback);
});
}; };
/** /**
@ -2080,30 +2000,46 @@ Account.prototype.saveAddress = function saveAddress(address, callback) {
}; };
/** /**
* Set receiving depth (depth is the index of the _next_ address). * Set change and receiving depth (depth is the index of the _next_ address).
* Allocate all addresses up to depth. Note that this also allocates * Allocate all addresses up to depth. Note that this also allocates
* new lookahead addresses. * new lookahead addresses.
* @param {Number} depth * @param {Number} depth
* @returns {Boolean} True if new addresses were allocated. * @param {Function} callback - Returns [Error, {@link KeyRing}, {@link KeyRing}].
*/ */
Account.prototype.setReceiveDepth = function setReceiveDepth(depth, callback) { Account.prototype.setDepth = function setDepth(receiveDepth, changeDepth, callback) {
var self = this; var self = this;
var addresses = []; var addresses = [];
var i; var i, receive, change;
if (!(depth > this.receiveDepth)) if (receiveDepth > this.receiveDepth) {
return callback(null, false); for (i = this.receiveDepth; i < receiveDepth; i++) {
receive = this.deriveReceive(i);
addresses.push(receive);
}
for (i = this.receiveDepth; i < depth; i++) { for (i = receiveDepth; i < receiveDepth + this.lookahead; i++)
this.receiveAddress = this.deriveReceive(i); addresses.push(this.deriveReceive(i));
addresses.push(this.receiveAddress);
this.receiveAddress = receive;
this.receiveDepth = receiveDepth;
} }
for (i = this.receiveDepth + this.lookahead; i < depth + this.lookahead; i++) if (changeDepth > this.changeDepth) {
addresses.push(this.deriveReceive(i)); for (i = this.changeDepth; i < changeDepth; i++) {
change = this.deriveChange(i);
addresses.push(this.changeAddress);
}
this.receiveDepth = depth; for (i = changeDepth; i < changeDepth + this.lookahead; i++)
addresses.push(this.deriveChange(i));
this.changeAddress = change;
this.changeDepth = changeDepth;
}
if (addresses.length === 0)
return callback(null, false);
this.saveAddress(addresses, function(err) { this.saveAddress(addresses, function(err) {
if (err) if (err)
@ -2113,44 +2049,7 @@ Account.prototype.setReceiveDepth = function setReceiveDepth(depth, callback) {
if (err) if (err)
return callback(err); return callback(err);
return callback(null, true); return callback(null, receive, change);
});
});
};
/**
* Set change depth (depth is the index of the _next_ address).
* Allocate all addresses up to depth. Note that this also allocates
* new lookahead addresses.
* @param {Number} depth
* @returns {Boolean} True if new addresses were allocated.
*/
Account.prototype.setChangeDepth = function setChangeDepth(depth, callback) {
var self = this;
var addresses = [];
var i;
if (!(depth > this.changeDepth))
return callback(null, false);
for (i = this.changeDepth; i < depth; i++) {
this.changeAddress = this.deriveChange(i);
addresses.push(this.changeAddress);
}
for (i = this.changeDepth + this.lookahead; i < depth + this.lookahead; i++)
addresses.push(this.deriveChange(i));
this.changeDepth = depth;
this.saveAddress(addresses, function(err) {
if (err)
return callback(err);
self.save(function(err) {
if (err)
return callback(err);
return callback(null, true);
}); });
}); });
}; };

View File

@ -781,56 +781,112 @@ WalletDB.prototype.getCoin = function getCoin(hash, index, callback) {
* @see {@link TXDB#getHistory}. * @see {@link TXDB#getHistory}.
*/ */
WalletDB.prototype.getHistory = function getHistory(id, callback) { WalletDB.prototype.getHistory = function getHistory(id, account, callback) {
return this.tx.getHistory(id, callback); var self = this;
this._getKey(id, account, callback, function(id, callback) {
self.tx.getHistory(id, callback);
});
}; };
/** /**
* @see {@link TXDB#getCoins}. * @see {@link TXDB#getCoins}.
*/ */
WalletDB.prototype.getCoins = function getCoins(id, callback) { WalletDB.prototype.getCoins = function getCoins(id, account, callback) {
return this.tx.getCoins(id, callback); var self = this;
this._getKey(id, account, callback, function(id, callback) {
self.tx.getCoins(id, callback);
});
}; };
/** /**
* @see {@link TXDB#getUnconfirmed}. * @see {@link TXDB#getUnconfirmed}.
*/ */
WalletDB.prototype.getUnconfirmed = function getUnconfirmed(id, callback) { WalletDB.prototype.getUnconfirmed = function getUnconfirmed(id, account, callback) {
return this.tx.getUnconfirmed(id, callback); var self = this;
this._getKey(id, account, callback, function(id, callback) {
self.tx.getUnconfirmed(id, callback);
});
}; };
/** /**
* @see {@link TXDB#getBalance}. * @see {@link TXDB#getBalance}.
*/ */
WalletDB.prototype.getBalance = function getBalance(id, callback) { WalletDB.prototype.getBalance = function getBalance(id, account, callback) {
return this.tx.getBalance(id, callback); var self = this;
this._getKey(id, account, callback, function(id, callback) {
self.tx.getBalance(id, callback);
});
}; };
/** /**
* @see {@link TXDB#getLastTime}. * @see {@link TXDB#getLastTime}.
*/ */
WalletDB.prototype.getLastTime = function getLastTime(id, callback) { WalletDB.prototype.getLastTime = function getLastTime(id, account, callback) {
return this.tx.getLastTime(id, callback); var self = this;
if (typeof options === 'function') {
callback = options;
options = account;
account = null;
}
this._getKey(id, account, callback, function(id, callback) {
self.tx.getLastTime(id, callback);
});
}; };
/** /**
* @see {@link TXDB#getLast}. * @see {@link TXDB#getLast}.
*/ */
WalletDB.prototype.getLast = function getLast(id, limit, callback) { WalletDB.prototype.getLast = function getLast(id, account, limit, callback) {
return this.tx.getLast(id, limit, callback); var self = this;
if (typeof limit === 'function') {
callback = limit;
limit = account;
account = null;
}
this._getKey(id, account, callback, function(id, callback) {
self.tx.getLast(id, limit, callback);
});
};
WalletDB.prototype.getTimeRange = function getTimeRange(id, account, limit, callback) {
var self = this;
if (typeof limit === 'function') {
callback = limit;
limit = account;
account = null;
}
this._getKey(id, account, callback, function(id, callback) {
self.tx.getTimeRange(id, options, callback);
});
}; };
/** /**
* @see {@link TXDB#getRange}. * @see {@link TXDB#getRange}.
*/ */
WalletDB.prototype.getRange = function getRange(id, options, callback) { WalletDB.prototype.getRange = function getRange(id, account, options, callback) {
return this.tx.getRange(id, options, callback); var self = this;
if (typeof options === 'function') {
callback = options;
options = account;
account = null;
}
this._getKey(id, account, callback, function(id, callback) {
self.tx.getRange(id, options, callback);
});
}; };
/** /**
@ -838,7 +894,7 @@ WalletDB.prototype.getRange = function getRange(id, options, callback) {
*/ */
WalletDB.prototype.fillHistory = function fillHistory(tx, callback) { WalletDB.prototype.fillHistory = function fillHistory(tx, callback) {
return this.tx.fillHistory(tx, callback); this.tx.fillHistory(tx, callback);
}; };
/** /**
@ -846,7 +902,7 @@ WalletDB.prototype.fillHistory = function fillHistory(tx, callback) {
*/ */
WalletDB.prototype.fillCoins = function fillCoins(tx, callback) { WalletDB.prototype.fillCoins = function fillCoins(tx, callback) {
return this.tx.fillCoins(tx, callback); this.tx.fillCoins(tx, callback);
}; };
/** /**
@ -854,8 +910,49 @@ WalletDB.prototype.fillCoins = function fillCoins(tx, callback) {
* @see {@link TXDB#zap}. * @see {@link TXDB#zap}.
*/ */
WalletDB.prototype.zap = function zap(id, age, callback) { WalletDB.prototype.zap = function zap(id, account, age, callback) {
return this.tx.zap(id, age, callback); var self = this;
if (typeof age === 'function') {
callback = age;
age = account;
account = null;
}
this._getKey(id, account, callback, function(id, callback) {
self.tx.zap(id, age, callback);
});
};
/**
* Parse arguments and return an id
* consisting of `walletid/accountname`.
* @private
* @param {String|Number} account
* @param {Function} errback
* @param {Function} callback - Returns [String, Function].
*/
WalletDB.prototype._getKey = function _getKey(id, account, errback, callback) {
var self = this;
if (typeof account === 'function') {
errback = account;
account = null;
}
if (account == null)
return callback(id, errback);
this.getAccountIndex(id, account, function(err, index) {
if (err)
return errback(err);
if (index === -1)
return errback(new Error('Account not found.'));
return callback(id + '/' + index, errback);
});
}; };
/** /**