use bloom filter for addresses in wallet db.

This commit is contained in:
Christopher Jeffrey 2016-05-20 17:11:40 -07:00
parent 292e077550
commit 3e2f43e178
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 75 additions and 9 deletions

View File

@ -59,6 +59,9 @@ function TXDB(db, options) {
this.busy = false;
this.jobs = [];
this.locker = new bcoin.locker(this);
this.filter = this.options.useFilter
? new bcoin.bloom.rolling(800000, 0.01)
: null;
if (this.options.mapAddress)
this.options.indexAddress = true;
@ -70,6 +73,43 @@ TXDB.prototype._lock = function _lock(func, args, force) {
return this.locker.lock(func, args, force);
};
TXDB.prototype._loadFilter = function loadFilter(callback) {
var self = this;
if (!this.filter)
return callback();
this.db.iterate({
gte: 'W',
lte: 'W~',
transform: function(key) {
return key.split('/')[1];
}
}, function(err, keys) {
if (err)
return callback(err);
for (i = 0; i < keys.length; i++)
self.filter.add(keys[i], 'hex');
return callback();
});
};
TXDB.prototype._testFilter = function _testFilter(addresses) {
var i;
if (!this.filter)
return true;
for (i = 0; i < addresses.length; i++) {
if (this.filter.test(addresses[i], 'hex'))
return true;
}
return false;
};
/**
* Map a transactions' addresses to wallet IDs.
* @param {TX} tx
@ -86,6 +126,9 @@ TXDB.prototype.getMap = function getMap(tx, callback) {
output = tx.getOutputHashes();
addresses = utils.uniq(input.concat(output));
if (!this._testFilter(addresses))
return callback();
function cb(err, table) {
if (err)
return callback(err);
@ -267,6 +310,9 @@ TXDB.prototype.add = function add(tx, callback, force) {
if (err)
return callback(err);
if (!map)
return callback(null, false);
if (self.options.mapAddress) {
if (map.all.length === 0)
return callback(null, false);
@ -757,6 +803,9 @@ TXDB.prototype.remove = function remove(hash, callback, force) {
if (err)
return callback(err);
if (!map)
return callback(null, false);
if (self.options.mapAddress) {
if (map.all.length === 0)
return callback(null, false);
@ -788,6 +837,9 @@ TXDB.prototype.lazyRemove = function lazyRemove(tx, callback, force) {
if (err)
return callback(err);
if (!map)
return callback(null, false);
if (self.options.mapAddress) {
if (map.all.length === 0)
return callback(null, false);
@ -938,6 +990,9 @@ TXDB.prototype.unconfirm = function unconfirm(hash, callback, force) {
if (err)
return callback(err);
if (!map)
return callback(null, false);
if (self.options.mapAddress) {
if (map.all.length === 0)
return callback(null, false);

View File

@ -107,20 +107,26 @@ WalletDB.prototype._init = function _init() {
writeBufferSize: 4 << 20
});
this.db.open(function(err) {
if (err)
return self.emit('error', err);
self.emit('open');
self.loaded = true;
});
this.tx = new bcoin.txdb(this.db, {
network: this.network,
indexExtra: true,
indexAddress: true,
mapAddress: true,
verify: this.options.verify
verify: this.options.verify,
useFilter: true
});
this.db.open(function(err) {
if (err)
return self.emit('error', err);
self.tx._loadFilter(function(err) {
if (err)
return self.emit('error', err);
self.emit('open');
self.loaded = true;
});
});
this.tx.on('error', function(err) {
@ -373,9 +379,14 @@ WalletDB.prototype.saveJSON = function saveJSON(id, json, callback) {
if (json) {
batch = self.db.batch();
Object.keys(json.addressMap).forEach(function(address) {
if (self.tx.filter)
self.tx.filter.add(address, 'hex');
batch.put('W/' + address + '/' + json.id, DUMMY);
});
return batch.write(function(err) {
if (err)
return callback(err);