diff --git a/lib/bcoin/spvnode.js b/lib/bcoin/spvnode.js index d9106cf7..b1b09a14 100644 --- a/lib/bcoin/spvnode.js +++ b/lib/bcoin/spvnode.js @@ -140,7 +140,7 @@ SPVNode.prototype._init = function _init() { }); }); - this.walletdb.on('save address', function(address) { + this.walletdb.on('save address', function(address, path) { self.pool.watch(address.getHash()); }); diff --git a/lib/bcoin/walletdb.js b/lib/bcoin/walletdb.js index d5aee1ae..973b55c5 100644 --- a/lib/bcoin/walletdb.js +++ b/lib/bcoin/walletdb.js @@ -932,7 +932,7 @@ WalletDB.prototype.hasAccount = function hasAccount(wid, account, callback) { }; /** - * Save an address to the path map. + * Save addresses to the path map. * The path map exists in the form of: * `p/[address-hash] -> {walletid1=path1, walletid2=path2, ...}` * @param {WalletID} wid @@ -943,7 +943,6 @@ WalletDB.prototype.hasAccount = function hasAccount(wid, account, callback) { WalletDB.prototype.saveAddress = function saveAddress(wid, rings, callback) { var self = this; var items = []; - var batch = this.batch(wid); var i, ring, path; for (i = 0; i < rings.length; i++) { @@ -952,41 +951,56 @@ WalletDB.prototype.saveAddress = function saveAddress(wid, rings, callback) { items.push([ring.getAddress(), path]); - if (ring.witness) + if (ring.witness) { + path = path.clone(); + path.hash = ring.getProgramHash('hex'); items.push([ring.getProgramAddress(), path]); + } } utils.forEachSerial(items, function(item, next) { - var ring = item[0]; - var path = item[1]; - var hash = ring.getHash('hex'); - - if (self.filter) - self.filter.add(hash, 'hex'); - - self.emit('save address', ring, path); - - self.getAddressPaths(hash, function(err, paths) { - if (err) - return next(err); - - if (!paths) - paths = {}; - - if (paths[wid]) - return next(); - - paths[wid] = path; - - self.pathCache.set(hash, paths); - - batch.put(layout.p(hash), serializePaths(paths)); - - next(); - }); + self.writeAddress(wid, item[0], item[1], next); }, callback); }; +/** + * Save a single address to the path map. + * @param {WalletID} wid + * @param {KeyRing} rings + * @param {Path} path + * @param {Function} callback + */ + +WalletDB.prototype.writeAddress = function writeAddress(wid, address, path, callback) { + var self = this; + var hash = address.getHash('hex'); + var batch = this.batch(wid); + + if (this.filter) + this.filter.add(hash, 'hex'); + + this.emit('save address', address, path); + + this.getAddressPaths(hash, function(err, paths) { + if (err) + return callback(err); + + if (!paths) + paths = {}; + + if (paths[wid]) + return callback(); + + paths[wid] = path; + + self.pathCache.set(hash, paths); + + batch.put(layout.p(hash), serializePaths(paths)); + + callback(); + }); +}; + /** * Retrieve paths by hash. * @param {Hash} hash @@ -1617,6 +1631,33 @@ function Path() { this.hash = null; } +/** + * Clone the path object. + * @returns {Path} + */ + +Path.prototype.clone = function clone() { + var path = new Path(); + + path.wid = this.wid; + path.name = this.name; + path.account = this.account; + path.change = this.change; + path.index = this.index; + + path.encrypted = this.encrypted; + path.imported = this.imported; + path.script = this.script; + + path.type = this.type; + path.version = this.version; + + path.id = this.id; + path.hash = this.hash; + + return path; +}; + /** * Inject properties from serialized data. * @private