http tests. caches.

This commit is contained in:
Christopher Jeffrey 2016-07-13 14:53:37 -07:00
parent a60a48da9a
commit 682596fb05
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
9 changed files with 167 additions and 59 deletions

View File

@ -209,7 +209,7 @@ function ChainDB(chain, options) {
// Key size: 66b (* 2)
this.coinWindow = ((165 * 1024 + 2300 * 4) + (2300 * 66 * 2)) * 5;
this.coinCache = new NullCache(this.coinWindow);
this.coinCache = new bcoin.lru.nil(this.coinWindow);
this.cacheHash = new bcoin.lru(this.cacheWindow, 1);
this.cacheHeight = new bcoin.lru(this.cacheWindow, 1);
}
@ -1482,20 +1482,6 @@ ChainDB.prototype._pruneBlock = function _pruneBlock(block, batch, callback) {
});
};
/**
* A null cache. Every method is a NOP.
* @constructor
* @param {Number} size
*/
function NullCache(size) {}
NullCache.prototype.set = function set(key, value) {};
NullCache.prototype.remove = function remove(key) {};
NullCache.prototype.get = function get(key) {};
NullCache.prototype.has = function has(key) {};
NullCache.prototype.reset = function reset() {};
/*
* Helpers
*/

View File

@ -194,7 +194,9 @@ HTTPBase.prototype._initIO = function _initIO() {
if (!IOServer)
return;
this.io = new IOServer();
this.io = new IOServer({
transports: ['websocket']
});
this.io.attach(this.server);

View File

@ -75,7 +75,10 @@ HTTPClient.prototype._open = function _open(callback) {
if (!IOClient)
return callback();
this.socket = new IOClient(this.uri);
this.socket = new IOClient(this.uri, {
transports: ['websocket'],
forceNew: true
});
this.socket.on('error', function(err) {
self.emit('error', err);

View File

@ -353,8 +353,23 @@ function LRUItem(key, value) {
this.prev = null;
}
/**
* A null cache. Every method is a NOP.
* @constructor
* @param {Number} size
*/
function NullCache(size) {}
NullCache.prototype.set = function set(key, value) {};
NullCache.prototype.remove = function remove(key) {};
NullCache.prototype.get = function get(key) {};
NullCache.prototype.has = function has(key) {};
NullCache.prototype.reset = function reset() {};
/*
* Expose
*/
LRU.nil = NullCache;
module.exports = LRU;

View File

@ -1868,7 +1868,7 @@ TX.prototype.inspect = function inspect() {
value: utils.btc(this.getOutputValue()),
fee: utils.btc(this.getFee()),
minFee: utils.btc(this.getMinFee()),
rate: utils.btc(this.getRate()),
rate: this.getRate(), // Rate can sometimes exceed 53 bits in testing
confirmations: this.getConfirmations(),
priority: this.getPriority(),
date: utils.date(this.ts || this.ps),

View File

@ -1720,12 +1720,15 @@ Account.prototype.fromOptions = function fromOptions(options) {
assert(options, 'Options are required.');
assert(utils.isAlpha(options.id), 'Wallet ID must be alphanumeric.');
assert(utils.isAlpha(options.name), 'Account name must be alphanumeric.');
assert(bcoin.hd.isHD(options.accountKey), 'Account key is required.');
assert(utils.isNumber(options.accountIndex), 'Account index is required.');
this.id = options.id;
this.name = options.name;
if (options.name != null) {
assert(utils.isAlpha(options.name), 'Account name must be alphanumeric.');
this.name = options.name;
}
if (options.witness != null) {
assert(typeof options.witness === 'boolean');

View File

@ -54,6 +54,9 @@ function WalletDB(options) {
// We need one read lock for `get` and `create`.
// It will hold locks specific to wallet ids.
this.readLock = new ReadLock(this);
this.accountCache = new bcoin.lru(100000, 1);
this.walletCache = new bcoin.lru(100000, 1);
this.pathCache = new bcoin.lru(100000, 1);
this.db = bcoin.ldb({
location: this.options.location,
@ -425,19 +428,13 @@ WalletDB.prototype.get = function get(id, callback) {
return callback(null, watcher.object);
}
this.db.get('w/' + id, function(err, data) {
this._get(id, function(err, wallet) {
if (err)
return callback(err);
if (!data)
if (!wallet)
return callback();
try {
wallet = bcoin.wallet.fromRaw(self, data);
} catch (e) {
return callback(e);
}
try {
self.register(wallet);
} catch (e) {
@ -453,6 +450,37 @@ WalletDB.prototype.get = function get(id, callback) {
});
};
WalletDB.prototype._get = function get(id, callback) {
var self = this;
var wallet;
if (!id)
return callback();
wallet = this.walletCache.get(id);
if (wallet)
return callback(null, wallet);
this.db.get('w/' + id, function(err, data) {
if (err)
return callback(err);
if (!data)
return callback();
try {
wallet = bcoin.wallet.fromRaw(self, data);
} catch (e) {
return callback(e);
}
self.walletCache.set(id, wallet);
return callback(null, wallet);
});
};
/**
* Save a wallet to the database.
* @param {Wallet} wallet
@ -463,6 +491,8 @@ WalletDB.prototype.save = function save(wallet, callback) {
if (!utils.isAlpha(wallet.id))
return callback(new Error('Wallet IDs must be alphanumeric.'));
this.walletCache.set(wallet.id, wallet);
this.db.put('w/' + wallet.id, wallet.toRaw(), callback);
};
@ -480,19 +510,13 @@ WalletDB.prototype.auth = function auth(id, token, callback) {
if (!id)
return callback(new Error('Wallet not found.'));
this.db.get('w/' + id, function(err, data) {
this._get(id, function(err, wallet) {
if (err)
return callback(err);
if (!data)
if (!wallet)
return callback(new Error('Wallet not found.'));
try {
wallet = bcoin.wallet.fromRaw(self, data);
} catch (e) {
return callback(e);
}
if (typeof token === 'string') {
if (!utils.isHex(token))
return callback(new Error('Authentication error.'));
@ -614,19 +638,13 @@ WalletDB.prototype.getAccount = function getAccount(id, name, callback) {
if (index === -1)
return callback();
self.db.get('a/' + id + '/' + index, function(err, data) {
self._getAccount(id, index, function(err, account) {
if (err)
return callback(err);
if (!data)
if (!account)
return callback();
try {
account = bcoin.account.fromRaw(self, data);
} catch (e) {
return callback(e);
}
account.open(function(err) {
if (err)
return callback(err);
@ -637,6 +655,33 @@ WalletDB.prototype.getAccount = function getAccount(id, name, callback) {
});
};
WalletDB.prototype._getAccount = function getAccount(id, index, callback) {
var self = this;
var key = id + '/' + index;
var account = this.accountCache.get(key);
if (account)
return callback(null, account);
this.db.get('a/' + key, function(err, data) {
if (err)
return callback(err);
if (!data)
return callback();
try {
account = bcoin.account.fromRaw(self, data);
} catch (e) {
return callback(e);
}
self.accountCache.set(key, account);
return callback(null, account);
});
};
/**
* List account names and indexes from the db.
* @param {WalletID} id
@ -675,6 +720,9 @@ WalletDB.prototype.getAccounts = function getAccounts(id, callback) {
*/
WalletDB.prototype.getAccountIndex = function getAccountIndex(id, name, callback) {
if (!id)
return callback(null, -1);
if (name == null)
return callback(null, -1);
@ -699,7 +747,7 @@ WalletDB.prototype.getAccountIndex = function getAccountIndex(id, name, callback
*/
WalletDB.prototype.saveAccount = function saveAccount(account, callback) {
var index, batch;
var index, key, batch;
if (!utils.isAlpha(account.name))
return callback(new Error('Account names must be alphanumeric.'));
@ -709,9 +757,13 @@ WalletDB.prototype.saveAccount = function saveAccount(account, callback) {
index = new Buffer(4);
index.writeUInt32LE(account.accountIndex, 0, true);
batch.put('a/' + account.id + '/' + account.accountIndex, account.toRaw());
key = account.id + '/' + account.accountIndex;
batch.put('a/' + key, account.toRaw());
batch.put('i/' + account.id + '/' + account.name, index);
this.accountCache.set(key, account);
batch.write(callback);
};
@ -816,7 +868,7 @@ WalletDB.prototype.saveAddress = function saveAddress(id, addresses, callback) {
self.emit('save address', address, path);
self.db.fetch('W/' + hash, parsePaths, function(err, paths) {
self._getPaths(hash, function(err, paths) {
if (err)
return next(err);
@ -828,6 +880,8 @@ WalletDB.prototype.saveAddress = function saveAddress(id, addresses, callback) {
paths[id] = path;
self.pathCache.set(hash, paths);
batch.put('W/' + hash, serializePaths(paths));
next();
@ -840,6 +894,31 @@ WalletDB.prototype.saveAddress = function saveAddress(id, addresses, callback) {
});
};
WalletDB.prototype._getPaths = function _getPaths(hash, callback) {
var self = this;
var paths;
if (!hash)
return callback();
paths = this.pathCache.get(hash);
if (paths)
return callback(null, paths);
this.db.fetch('W/' + hash, parsePaths, function(err, paths) {
if (err)
return callback(err);
if (!paths)
return callback();
self.pathCache.set(hash, paths);
return callback(null, paths);
});
};
/**
* Test whether an address hash exists in the
* path map and is relevant to the wallet id.
@ -867,10 +946,7 @@ WalletDB.prototype.hasAddress = function hasAddress(id, address, callback) {
*/
WalletDB.prototype.getAddress = function getAddress(address, callback) {
if (!address)
return callback();
this.db.fetch('W/' + address, parsePaths, callback);
this._getPaths(address, callback);
};
/**

View File

@ -93,7 +93,7 @@ describe('HTTP', function() {
*/
it('should fill with funds', function(cb) {
var balance, receive;
var balance, receive, tx;
// Coinbase
var t1 = bcoin.mtx()
@ -112,10 +112,13 @@ describe('HTTP', function() {
receive = r[0];
});
wallet.once('tx', function(t, map) {
tx = t;
});
node.walletdb.addTX(t1, function(err) {
assert.ifError(err);
setTimeout(function() {
return cb();
assert(receive);
assert.equal(receive.id, 'test');
assert.equal(receive.type, 'pubkeyhash');
@ -124,8 +127,10 @@ describe('HTTP', function() {
assert.equal(balance.confirmed, 0);
assert.equal(balance.unconfirmed, 201840);
assert.equal(balance.total, 201840);
assert(tx);
assert.equal(tx.hash('hex'), t1.hash('hex'));
cb();
}, 2000);
}, 300);
});
});
@ -171,6 +176,24 @@ describe('HTTP', function() {
});
});
it('should generate new api key', function(cb) {
var t = wallet.token.toString('hex');
wallet.retoken(null, function(err, token) {
assert.ifError(err);
assert(token.length === 64);
assert.notEqual(token, t);
cb();
});
});
it('should get balance', function(cb) {
wallet.getBalance(function(err, balance) {
assert.ifError(err);
assert.equal(balance.total, 199570);
cb();
});
});
it('should cleanup', function(cb) {
constants.tx.COINBASE_MATURITY = 100;
node.close(cb);

View File

@ -86,10 +86,10 @@ describe('Wallet', function() {
w1.destroy();
walletdb.get(w1.id, function(err, w1_) {
assert.ifError(err);
assert(w1 !== w1_);
assert(w1.master !== w1_.master);
// assert(w1 !== w1_);
// assert(w1.master !== w1_.master);
assert.equal(w1.master.key.xprivkey, w1.master.key.xprivkey);
assert(w1.account !== w1_.account);
// assert(w1.account !== w1_.account);
assert.equal(w1.account.accountKey.xpubkey, w1.account.accountKey.xpubkey);
cb();
});
@ -819,8 +819,8 @@ describe('Wallet', function() {
assert.ifError(err);
assert.equal(account.name, 'foo');
assert.equal(account.accountIndex, 1);
assert(account !== w1.account);
assert(account !== acc);
// assert(account !== w1.account);
// assert(account !== acc);
assert(account.accountKey.xpubkey === acc.accountKey.xpubkey);
assert(w1.account.accountIndex === 0);
assert(account.receiveAddress.getAddress('base58') !== w1.account.receiveAddress.getAddress('base58'));