From cbd7f06aba23455b6216111a8a5c59936f56c6ea Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Sun, 29 May 2016 12:09:07 -0700 Subject: [PATCH] stop using paths. --- lib/bcoin/keyring.js | 24 +++++++++---- lib/bcoin/wallet.js | 83 ++++++++----------------------------------- lib/bcoin/walletdb.js | 23 ++++++++---- 3 files changed, 48 insertions(+), 82 deletions(-) diff --git a/lib/bcoin/keyring.js b/lib/bcoin/keyring.js index 48ebe7d9..a2acc1b5 100644 --- a/lib/bcoin/keyring.js +++ b/lib/bcoin/keyring.js @@ -38,7 +38,9 @@ function KeyRing(options) { this.m = options.m || 1; this.n = options.n || 1; this.witness = options.witness || false; - this.path = options.path; + this.account = options.account; + this.change = options.change; + this.index = options.index; this.key = options.key; this.keys = []; @@ -525,7 +527,9 @@ KeyRing.prototype.toJSON = function toJSON() { m: this.m, n: this.n, witness: this.witness, - path: this.path, + account: this.account, + change: this.change, + index: this.index, key: utils.toBase58(this.key), keys: this.keys.map(utils.toBase58), address: this.getAddress() @@ -548,7 +552,9 @@ KeyRing.fromJSON = function fromJSON(json) { m: json.m, n: json.n, witness: json.witness, - path: json.path, + account: json.account, + change: json.change, + index: json.index, key: utils.fromBase58(json.key), keys: json.keys.map(utils.fromBase58) }); @@ -568,7 +574,9 @@ KeyRing.prototype.toRaw = function toRaw(writer) { p.writeU8(this.m); p.writeU8(this.n); p.writeU8(this.witness ? 1 : 0); - p.writeVarString(this.path, 'ascii'); + p.writeU32(this.account); + p.writeU32(this.change); + p.writeU32(this.index); p.writeVarBytes(this.key); p.writeU8(this.keys.length); @@ -593,7 +601,9 @@ KeyRing.fromRaw = function fromRaw(data) { var m = p.readU8(); var n = p.readU8(); var witness = p.readU8() === 1; - var path = p.readVarString('ascii'); + var account = p.readU32(); + var change = p.readU32(); + var index = p.readU32(); var key = p.readVarBytes(); var keys = new Array(p.readU8()); var i; @@ -607,7 +617,9 @@ KeyRing.fromRaw = function fromRaw(data) { m: m, n: n, witness: witness, - path: path, + account: account, + change: change, + index: index, key: key, keys: keys }); diff --git a/lib/bcoin/wallet.js b/lib/bcoin/wallet.js index 7364c858..3a8555b7 100644 --- a/lib/bcoin/wallet.js +++ b/lib/bcoin/wallet.js @@ -474,9 +474,6 @@ Wallet.prototype.createAddress = function createAddress(change, callback) { change = null; } - if (typeof change === 'string') - change = this.parsePath(change).change; - if (change) { address = this.deriveChange(this.changeDepth); addresses.push(address); @@ -510,9 +507,6 @@ Wallet.prototype.createAddress = function createAddress(change, callback) { */ Wallet.prototype.deriveReceive = function deriveReceive(index) { - if (typeof index === 'string') - index = this.parsePath(index).index; - return this.deriveAddress(false, index); }; @@ -523,9 +517,6 @@ Wallet.prototype.deriveReceive = function deriveReceive(index) { */ Wallet.prototype.deriveChange = function deriveChange(index) { - if (typeof index === 'string') - index = this.parsePath(index).index; - return this.deriveAddress(true, index); }; @@ -538,32 +529,20 @@ Wallet.prototype.deriveChange = function deriveChange(index) { Wallet.prototype.deriveAddress = function deriveAddress(change, index) { var self = this; - var i, path, data, key, options, address; + var i, key, options; assert(this.initialized); - if (typeof change === 'string') - path = change; + change = +change; - if (path) { - data = this.parsePath(path); - } else { - data = { - path: this.createPath(change, index), - change: change, - index: index - }; - } - - if (this.cache.has(data.path)) - return this.cache.get(data.path); - - key = this.accountKey.derive(data.path); + key = this.accountKey.derive(change).derive(index); options = { network: this.network, key: key.publicKey, - path: data.path, + account: this.accountIndex, + change: change, + index: index, type: this.type, witness: this.witness, m: this.m, @@ -573,16 +552,11 @@ Wallet.prototype.deriveAddress = function deriveAddress(change, index) { for (i = 0; i < this.keys.length; i++) { key = this.keys[i]; - path = this.createPath(data.change, data.index); - key = key.derive(path); + key = key.derive(change).derive(index); options.keys.push(key.publicKey); } - address = new bcoin.keyring(options); - - this.cache.set(data.path, address); - - return address; + return new bcoin.keyring(options); }; /** @@ -615,37 +589,6 @@ Wallet.prototype.hasAddress = function hasAddress(address, callback) { this.db.hasAddress(this.id, address, callback); }; -/** - * Create a path. - * @param {Boolean} change - Whether the key is on the change branch. - * @param {Number} index - The index to derive to. - * @returns {String} path - */ - -Wallet.prototype.createPath = function createPath(change, index) { - return 'm' - + '/' + (change ? 1 : 0) - + '/' + index; -}; - -/** - * Parse a path. - * @param {String} path - * @returns {Object} Contains `path`, `change`, and `index`. - */ - -Wallet.prototype.parsePath = function parsePath(path) { - var parts = path.split('/'); - - assert(/^m\/\d+\/\d+$/.test(path)); - - return { - path: path, - change: parseInt(parts[parts.length - 2], 10) === 1, - index: parseInt(parts[parts.length - 1], 10) - }; -}; - /** * Set receiving depth (depth is the index of the _next_ address). * Allocate all addresses up to depth. Note that this also allocates @@ -909,8 +852,10 @@ Wallet.prototype.deriveInputs = function deriveInputs(tx, callback) { if (err) return callback(err); - for (i = 0; i < paths.length; i++) - addresses.push(self.deriveAddress(paths[i])); + for (i = 0; i < paths.length; i++) { + path = paths[i]; + addresses.push(self.deriveAddress(path.change, path.index)); + } return callback(null, addresses); }); @@ -1031,7 +976,7 @@ Wallet.prototype.getOutputDepth = function getOutputDepth(tx, callback) { return callback(err); for (i = 0; i < paths.length; i++) { - path = self.parsePath(paths[i]); + path = paths[i]; if (path.change) { if (path.index > depth.changeDepth) depth.changeDepth = path.index; @@ -1291,7 +1236,7 @@ Wallet.prototype.sign = function sign(tx, options, callback) { for (i = 0; i < addresses.length; i++) { address = addresses[i]; - key = master.derive(address.path); + key = master.derive(address.change).derive(address.index); assert(utils.equal(key.getPublicKey(), address.key)); total += address.sign(tx, key, options.index, options.type); } diff --git a/lib/bcoin/walletdb.js b/lib/bcoin/walletdb.js index a7e373a7..387c5198 100644 --- a/lib/bcoin/walletdb.js +++ b/lib/bcoin/walletdb.js @@ -341,7 +341,7 @@ WalletDB.prototype.get = function get(id, callback) { }; /** - * Save a wallet to the database (setup ida and encrypt). + * Save a wallet to the database. * @param {Wallet} wallet * @param {Function} callback */ @@ -457,13 +457,13 @@ WalletDB.prototype.saveAddress = function saveAddress(id, addresses, callback) { for (i = 0; i < addresses.length; i++) { address = addresses[i]; - hashes.push([address.getKeyHash('hex'), address.path]); + hashes.push([address.getKeyHash('hex'), address]); if (address.type === 'multisig') - hashes.push([address.getScriptHash('hex'), address.path]); + hashes.push([address.getScriptHash('hex'), address]); if (address.witness) - hashes.push([address.getProgramHash('hex'), address.path]); + hashes.push([address.getProgramHash('hex'), address]); } utils.forEach(hashes, function(hash, next) { @@ -809,9 +809,16 @@ WalletDB.prototype.getRedeem = function getRedeem(id, hash, callback) { function parsePaths(data) { var p = new BufferReader(data); var out = {}; + var id; - while (p.left()) - out[p.readVarString('utf8')] = p.readVarString('ascii'); + while (p.left()) { + id = p.readVarString('utf8'); + out[id] = { + account: p.readU32(), + change: p.readU32(), + index: p.readU32() + }; + } return out; } @@ -825,7 +832,9 @@ function serializePaths(out) { id = keys[i]; path = out[id]; p.writeVarString(id, 'utf8'); - p.writeVarString(path, 'ascii'); + p.writeU32(path.account); + p.writeU32(path.change); + p.writeU32(path.index); } return p.render();