walletdb: fixes.
This commit is contained in:
parent
17b176141e
commit
cfad740b09
@ -956,7 +956,7 @@ HDPrivateKey.prototype.derive = function derive(index, hardened) {
|
||||
if (this.depth >= 0xff)
|
||||
throw new Error('Depth too high.');
|
||||
|
||||
id = this.xprivkey + '/' + index;
|
||||
id = this.getID(index);
|
||||
child = HD.cache.get(id);
|
||||
|
||||
if (child)
|
||||
@ -1002,6 +1002,19 @@ HDPrivateKey.prototype.derive = function derive(index, hardened) {
|
||||
return child;
|
||||
};
|
||||
|
||||
/**
|
||||
* Unique HD key ID.
|
||||
* @private
|
||||
* @param {Number} index
|
||||
* @returns {String}
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.getID = function getID(index) {
|
||||
return this.network.keyPrefix.xprivkey58
|
||||
+ this.publicKey.toString('hex')
|
||||
+ '/' + index;
|
||||
};
|
||||
|
||||
/**
|
||||
* Derive a BIP44 account key.
|
||||
* @param {Number} accountIndex
|
||||
@ -1603,7 +1616,7 @@ HDPublicKey.prototype.derive = function derive(index, hardened) {
|
||||
if (this.depth >= 0xff)
|
||||
throw new Error('Depth too high.');
|
||||
|
||||
id = this.xpubkey + '/' + index;
|
||||
id = this.getID(index);
|
||||
child = HD.cache.get(id);
|
||||
|
||||
if (child)
|
||||
@ -1640,6 +1653,19 @@ HDPublicKey.prototype.derive = function derive(index, hardened) {
|
||||
return child;
|
||||
};
|
||||
|
||||
/**
|
||||
* Unique HD key ID.
|
||||
* @private
|
||||
* @param {Number} index
|
||||
* @returns {String}
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.getID = function getID(index) {
|
||||
return this.network.keyPrefix.xpubkey58
|
||||
+ this.publicKey.toString('hex')
|
||||
+ '/' + index;
|
||||
};
|
||||
|
||||
/**
|
||||
* Derive a BIP44 account key (does not derive, only ensures account key).
|
||||
* @method
|
||||
|
||||
@ -1493,7 +1493,7 @@ Wallet.prototype.addTX = function addTX(tx, callback) {
|
||||
*/
|
||||
|
||||
Wallet.prototype.getHistory = function getHistory(account, callback) {
|
||||
this._getKey(account, callback, function(account, callback) {
|
||||
this._getIndex(account, callback, function(account, callback) {
|
||||
this.tx.getHistory(account, callback);
|
||||
});
|
||||
};
|
||||
@ -1505,7 +1505,7 @@ Wallet.prototype.getHistory = function getHistory(account, callback) {
|
||||
*/
|
||||
|
||||
Wallet.prototype.getCoins = function getCoins(account, callback) {
|
||||
this._getKey(account, callback, function(account, callback) {
|
||||
this._getIndex(account, callback, function(account, callback) {
|
||||
this.tx.getCoins(account, callback);
|
||||
});
|
||||
};
|
||||
@ -1517,7 +1517,7 @@ Wallet.prototype.getCoins = function getCoins(account, callback) {
|
||||
*/
|
||||
|
||||
Wallet.prototype.getUnconfirmed = function getUnconfirmed(account, callback) {
|
||||
this._getKey(account, callback, function(account, callback) {
|
||||
this._getIndex(account, callback, function(account, callback) {
|
||||
this.tx.getUnconfirmed(account, callback);
|
||||
});
|
||||
};
|
||||
@ -1529,7 +1529,7 @@ Wallet.prototype.getUnconfirmed = function getUnconfirmed(account, callback) {
|
||||
*/
|
||||
|
||||
Wallet.prototype.getBalance = function getBalance(account, callback) {
|
||||
this._getKey(account, callback, function(account, callback) {
|
||||
this._getIndex(account, callback, function(account, callback) {
|
||||
this.tx.getBalance(account, callback);
|
||||
});
|
||||
};
|
||||
@ -1543,7 +1543,7 @@ Wallet.prototype.getBalance = function getBalance(account, callback) {
|
||||
*/
|
||||
|
||||
Wallet.prototype.getLastTime = function getLastTime(account, callback) {
|
||||
this._getKey(account, callback, function(account, callback) {
|
||||
this._getIndex(account, callback, function(account, callback) {
|
||||
this.tx.getLastTime(account, callback);
|
||||
});
|
||||
};
|
||||
@ -1561,7 +1561,7 @@ Wallet.prototype.getLast = function getLast(account, limit, callback) {
|
||||
limit = account;
|
||||
account = null;
|
||||
}
|
||||
this._getKey(account, callback, function(account, callback) {
|
||||
this._getIndex(account, callback, function(account, callback) {
|
||||
this.tx.getLast(account, limit, callback);
|
||||
});
|
||||
};
|
||||
@ -1581,7 +1581,7 @@ Wallet.prototype.getTimeRange = function getTimeRange(account, options, callback
|
||||
options = account;
|
||||
account = null;
|
||||
}
|
||||
this._getKey(account, callback, function(account, callback) {
|
||||
this._getIndex(account, callback, function(account, callback) {
|
||||
this.tx.getTimeRange(account, options, callback);
|
||||
});
|
||||
};
|
||||
@ -1599,7 +1599,7 @@ Wallet.prototype.zap = function zap(account, age, callback) {
|
||||
age = account;
|
||||
account = null;
|
||||
}
|
||||
this._getKey(account, callback, function(account, callback) {
|
||||
this._getIndex(account, callback, function(account, callback) {
|
||||
this.tx.zap(account, age, callback);
|
||||
});
|
||||
};
|
||||
@ -1610,15 +1610,8 @@ Wallet.prototype.zap = function zap(account, age, callback) {
|
||||
* @param {Function} callback - Returns [Error].
|
||||
*/
|
||||
|
||||
Wallet.prototype.abandon = function abandon(account, hash, callback) {
|
||||
if (typeof hash === 'function') {
|
||||
callback = hash;
|
||||
hash = account;
|
||||
account = null;
|
||||
}
|
||||
this._getKey(account, callback, function(account, callback) {
|
||||
this.tx.abandon(account, hash, callback);
|
||||
});
|
||||
Wallet.prototype.abandon = function abandon(hash, callback) {
|
||||
this.tx.abandon(hash, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1629,7 +1622,7 @@ Wallet.prototype.abandon = function abandon(account, hash, callback) {
|
||||
* @param {Function} callback
|
||||
*/
|
||||
|
||||
Wallet.prototype._getKey = function _getKey(account, errback, callback) {
|
||||
Wallet.prototype._getIndex = function _getIndex(account, errback, callback) {
|
||||
var self = this;
|
||||
|
||||
if (typeof account === 'function') {
|
||||
@ -2715,9 +2708,6 @@ Account.prototype.toRaw = function toRaw(writer) {
|
||||
var i;
|
||||
|
||||
p.writeU32(this.network.magic);
|
||||
// NOTE: Passed in by caller.
|
||||
// p.writeU32(this.wid);
|
||||
// p.writeVarString(this.id, 'utf8');
|
||||
p.writeVarString(this.name, 'utf8');
|
||||
p.writeU8(this.initialized ? 1 : 0);
|
||||
p.writeU8(this.type === 'pubkeyhash' ? 0 : 1);
|
||||
@ -2751,9 +2741,6 @@ Account.prototype.fromRaw = function fromRaw(data) {
|
||||
var i, count;
|
||||
|
||||
this.network = bcoin.network.fromMagic(p.readU32());
|
||||
// NOTE: Passed in by caller.
|
||||
// this.wid = p.readU32();
|
||||
// this.id = p.readVarString('utf8');
|
||||
this.name = p.readVarString('utf8');
|
||||
this.initialized = p.readU8() === 1;
|
||||
this.type = p.readU8() === 0 ? 'pubkeyhash' : 'multisig';
|
||||
@ -3039,8 +3026,9 @@ MasterKey.prototype.encrypt = function encrypt(passphrase, callback) {
|
||||
if (!passphrase)
|
||||
return callback();
|
||||
|
||||
iv = bcoin.ec.random(16);
|
||||
data = this.key.toExtended();
|
||||
iv = bcoin.ec.random(16);
|
||||
|
||||
this.stop();
|
||||
|
||||
utils.encrypt(data, passphrase, iv, function(err, data) {
|
||||
|
||||
@ -9,15 +9,15 @@
|
||||
|
||||
/*
|
||||
* Database Layout:
|
||||
* (inherits all from txdb)
|
||||
* p/[address] -> wid & path data
|
||||
* p/[address] -> path data
|
||||
* w/[wid] -> wallet
|
||||
* l/[label] -> wallet wid
|
||||
* l/[id] -> wid
|
||||
* a/[wid]/[index] -> account
|
||||
* i/[wid]/[name] -> account index
|
||||
* t/[wid]/* -> txdb
|
||||
* R -> tip
|
||||
* b/[hash] -> wallet block
|
||||
* t/[hash] -> tx->wallet-wid map
|
||||
* t/[hash] -> tx->wid map
|
||||
*/
|
||||
|
||||
var bcoin = require('./env');
|
||||
@ -186,7 +186,7 @@ WalletDB.prototype.getDepth = function getDepth(callback) {
|
||||
// This may seem like a strange way to do
|
||||
// this, but updating a global state when
|
||||
// creating a new wallet is actually pretty
|
||||
// damn tricky. They would be major atomicity
|
||||
// damn tricky. There would be major atomicity
|
||||
// issues if updating a global state inside
|
||||
// a "scoped" state. So, we avoid all the
|
||||
// nonsense of adding a global lock to
|
||||
@ -290,8 +290,8 @@ WalletDB.prototype.loadFilter = function loadFilter(callback) {
|
||||
return callback();
|
||||
|
||||
this.db.iterate({
|
||||
gte: 'W',
|
||||
lte: 'W~',
|
||||
gte: 'p/' + constants.NULL_HASH,
|
||||
lte: 'p/' + constants.HIGH_HASH,
|
||||
transform: function(key) {
|
||||
key = key.split('/')[1];
|
||||
self.filter.add(key, 'hex');
|
||||
@ -563,12 +563,12 @@ WalletDB.prototype.create = function create(options, callback) {
|
||||
|
||||
/**
|
||||
* Test for the existence of a wallet.
|
||||
* @param {WalletID?} wid
|
||||
* @param {WalletID} id
|
||||
* @param {Function} callback
|
||||
*/
|
||||
|
||||
WalletDB.prototype.has = function has(wid, callback) {
|
||||
this.getWalletID(wid, function(err, wid) {
|
||||
WalletDB.prototype.has = function has(id, callback) {
|
||||
this.getWalletID(id, function(err, wid) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
return callback(null, wid != null);
|
||||
@ -577,7 +577,6 @@ WalletDB.prototype.has = function has(wid, callback) {
|
||||
|
||||
/**
|
||||
* Attempt to create wallet, return wallet if already exists.
|
||||
* @param {WalletID?} wid
|
||||
* @param {Object} options - See {@link Wallet}.
|
||||
* @param {Function} callback
|
||||
*/
|
||||
@ -663,9 +662,6 @@ WalletDB.prototype.getAccounts = function getAccounts(wid, callback) {
|
||||
var map = [];
|
||||
var i, accounts;
|
||||
|
||||
if (!utils.isNumber(wid))
|
||||
return callback(new Error('Wallet IDs must be alphanumeric.'));
|
||||
|
||||
this.db.iterate({
|
||||
gte: 'i/' + pad32(wid) + '/',
|
||||
lte: 'i/' + pad32(wid) + '/~',
|
||||
@ -944,8 +940,8 @@ WalletDB.prototype.getAddresses = function getAddresses(wid, callback) {
|
||||
}
|
||||
|
||||
this.db.iterate({
|
||||
gte: 'W',
|
||||
lte: 'W~',
|
||||
gte: 'p/' + constants.NULL_HASH,
|
||||
lte: 'p/' + constants.HIGH_HASH,
|
||||
values: true,
|
||||
parse: function(value, key) {
|
||||
var paths = parsePaths(value);
|
||||
@ -965,8 +961,8 @@ WalletDB.prototype.getAddresses = function getAddresses(wid, callback) {
|
||||
|
||||
WalletDB.prototype.getWallets = function getWallets(callback) {
|
||||
this.db.iterate({
|
||||
gte: 'w',
|
||||
lte: 'w~',
|
||||
gte: 'l/',
|
||||
lte: 'l/~',
|
||||
transform: function(key) {
|
||||
return key.split('/')[1];
|
||||
}
|
||||
@ -1194,15 +1190,7 @@ WalletDB.prototype.writeBlock = function writeBlock(block, matches, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
batch.write(function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
self.tip = block.hash;
|
||||
self.height = block.height;
|
||||
|
||||
return callback();
|
||||
});
|
||||
batch.write(callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1219,15 +1207,7 @@ WalletDB.prototype.unwriteBlock = function unwriteBlock(block, callback) {
|
||||
batch.put('R', prev.toTip());
|
||||
batch.del('b/' + block.hash);
|
||||
|
||||
batch.write(function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
self.tip = prev.hash;
|
||||
self.height = prev.height;
|
||||
|
||||
return callback();
|
||||
});
|
||||
batch.write(callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1277,6 +1257,11 @@ WalletDB.prototype.addBlock = function addBlock(entry, txs, callback, force) {
|
||||
block = WalletBlock.fromEntry(entry);
|
||||
matches = [];
|
||||
|
||||
// Update these early so transactions
|
||||
// get correct confirmation calculations.
|
||||
this.tip = block.hash;
|
||||
this.height = block.height;
|
||||
|
||||
// NOTE: Atomicity doesn't matter here. If we crash
|
||||
// during this loop, the automatic rescan will get
|
||||
// the database back into the correct state.
|
||||
@ -1359,7 +1344,15 @@ WalletDB.prototype.removeBlock = function removeBlock(entry, callback, force) {
|
||||
|
||||
wallet.tx.unconfirm(hash, next);
|
||||
});
|
||||
}, callback);
|
||||
}, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
self.tip = block.hash;
|
||||
self.height = block.height;
|
||||
|
||||
return callback();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -222,8 +222,8 @@ describe('Chain', function() {
|
||||
var txs = [];
|
||||
walletdb.getAddresses(function(err, hashes) {
|
||||
assert.ifError(err);
|
||||
chain.db.scan(null, hashes, function(tx, block, next) {
|
||||
txs.push(tx);
|
||||
chain.db.scan(null, hashes, function(block, tx, next) {
|
||||
txs = txs.concat(tx);
|
||||
next();
|
||||
}, function(err) {
|
||||
assert.ifError(err);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user