use leveldb iterators for getting by address.
This commit is contained in:
parent
6a644be03f
commit
8a3b0161c0
@ -513,6 +513,96 @@ BlockDB.prototype.getCoinsByAddress = function getCoinsByAddress(addresses, call
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BlockDB.prototype.getCoinsByAddress = function getCoinsByAddress(addresses, options, callback) {
|
||||||
|
var self = this;
|
||||||
|
var coins = [];
|
||||||
|
|
||||||
|
if (!callback) {
|
||||||
|
callback = options;
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof addresses === 'string')
|
||||||
|
addresses = [addresses];
|
||||||
|
|
||||||
|
addresses = utils.uniqs(addresses);
|
||||||
|
|
||||||
|
utils.forEach(addresses, function(address, done) {
|
||||||
|
var iter = self.index.db.iterator({
|
||||||
|
gte: 'u/a/' + address,
|
||||||
|
lte: 'u/a/' + address + '~',
|
||||||
|
keys: true,
|
||||||
|
values: true,
|
||||||
|
fillCache: true,
|
||||||
|
keyAsBuffer: false,
|
||||||
|
valueAsBuffer: true
|
||||||
|
});
|
||||||
|
|
||||||
|
(function next() {
|
||||||
|
iter.next(function(err, key, value) {
|
||||||
|
var record, parts, hash, index;
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
return iter.end(function() {
|
||||||
|
done(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// iter.end() here?
|
||||||
|
if (!key)
|
||||||
|
return done();
|
||||||
|
|
||||||
|
parts = key.split('/').slice(3);
|
||||||
|
hash = parts[0];
|
||||||
|
index = +parts[1];
|
||||||
|
record = self.parseOffset(value);
|
||||||
|
|
||||||
|
self.data.getAsync(record.size, record.offset, function(err, data) {
|
||||||
|
var coin;
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
return iter.end(function() {
|
||||||
|
done(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
return done();
|
||||||
|
|
||||||
|
try {
|
||||||
|
data = self.parser.parseOutput(data);
|
||||||
|
} catch (e) {
|
||||||
|
return iter.end(function() {
|
||||||
|
done(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
coin = bcoin.coin({
|
||||||
|
version: 1,
|
||||||
|
hash: hash,
|
||||||
|
index: index,
|
||||||
|
height: record.height,
|
||||||
|
script: data.script,
|
||||||
|
value: data.value,
|
||||||
|
spent: false
|
||||||
|
});
|
||||||
|
|
||||||
|
if (self.options.cache)
|
||||||
|
self.cache.unspent.set(id, coin);
|
||||||
|
|
||||||
|
coins.push(coin);
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
}, function(err) {
|
||||||
|
if (err)
|
||||||
|
return callback(err);
|
||||||
|
return callback(null, coins);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
BlockDB.prototype._getCoinsByAddress = function _getCoinsByAddress(address, callback) {
|
BlockDB.prototype._getCoinsByAddress = function _getCoinsByAddress(address, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var pending = 0;
|
var pending = 0;
|
||||||
@ -640,23 +730,25 @@ BlockDB.prototype.getCoin = function getCoin(hash, index, callback) {
|
|||||||
if (err)
|
if (err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
|
|
||||||
if (data) {
|
if (!data)
|
||||||
try {
|
return callback();
|
||||||
data = self.parser.parseOutput(data);
|
|
||||||
} catch (e) {
|
try {
|
||||||
return callback(e);
|
data = self.parser.parseOutput(data);
|
||||||
}
|
} catch (e) {
|
||||||
coin = bcoin.coin({
|
return callback(e);
|
||||||
version: 1,
|
|
||||||
hash: hash,
|
|
||||||
index: index,
|
|
||||||
height: record.height,
|
|
||||||
script: data.script,
|
|
||||||
value: data.value,
|
|
||||||
spent: false
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
coin = bcoin.coin({
|
||||||
|
version: 1,
|
||||||
|
hash: hash,
|
||||||
|
index: index,
|
||||||
|
height: record.height,
|
||||||
|
script: data.script,
|
||||||
|
value: data.value,
|
||||||
|
spent: false
|
||||||
|
});
|
||||||
|
|
||||||
return callback(null, coin);
|
return callback(null, coin);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -688,6 +780,119 @@ BlockDB.prototype.getTXByAddress = function getTXByAddress(addresses, callback)
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BlockDB.prototype.getTXByAddress = function getTXByAddress(addresses, options, callback) {
|
||||||
|
var self = this;
|
||||||
|
var txs = [];
|
||||||
|
var have = {};
|
||||||
|
|
||||||
|
if (!callback) {
|
||||||
|
callback = options;
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof addresses === 'string')
|
||||||
|
addresses = [addresses];
|
||||||
|
|
||||||
|
addresses = utils.uniqs(addresses);
|
||||||
|
|
||||||
|
utils.forEach(addresses, function(address, done) {
|
||||||
|
var iter = self.index.db.iterator({
|
||||||
|
gte: 't/a/' + address,
|
||||||
|
lte: 't/a/' + address + '~',
|
||||||
|
keys: true,
|
||||||
|
values: true,
|
||||||
|
fillCache: true,
|
||||||
|
keyAsBuffer: false,
|
||||||
|
valueAsBuffer: true
|
||||||
|
});
|
||||||
|
|
||||||
|
(function next() {
|
||||||
|
iter.next(function(err, key, value) {
|
||||||
|
var record, parts, hash, index;
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
return iter.end(function() {
|
||||||
|
done(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// iter.end() here?
|
||||||
|
if (!key)
|
||||||
|
return done();
|
||||||
|
|
||||||
|
parts = key.split('/').slice(3);
|
||||||
|
hash = parts[0];
|
||||||
|
record = self.parseOffset(value);
|
||||||
|
|
||||||
|
if (addresses.length > 1) {
|
||||||
|
if (have[hash])
|
||||||
|
return next();
|
||||||
|
|
||||||
|
have[hash] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.options.cache && self.cache.tx.has(hash)) {
|
||||||
|
txs.push(self.cache.tx.get(hash));
|
||||||
|
return done();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.data.getAsync(record.size, record.offset, function(err, data) {
|
||||||
|
var coin;
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
return iter.end(function() {
|
||||||
|
done(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
return next();
|
||||||
|
|
||||||
|
try {
|
||||||
|
tx = self.parser.parseTX(data);
|
||||||
|
tx = new bcoin.tx(tx);
|
||||||
|
} catch (e) {
|
||||||
|
return iter.end(function() {
|
||||||
|
done(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return self._getEntry(record.height, function(err, entry) {
|
||||||
|
if (err) {
|
||||||
|
return iter.end(function() {
|
||||||
|
done(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
tx.network = true;
|
||||||
|
tx.height = record.height;
|
||||||
|
|
||||||
|
if (entry) {
|
||||||
|
tx.ts = entry.ts;
|
||||||
|
tx.block = entry.hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
txs.push(tx);
|
||||||
|
|
||||||
|
if (self.options.cache)
|
||||||
|
self.cache.tx.set(hash, tx);
|
||||||
|
|
||||||
|
if (self.options.paranoid && tx.hash('hex') !== hash)
|
||||||
|
return next(new Error('BlockDB is corrupt. All is lost.'));
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
}, function(err) {
|
||||||
|
if (err)
|
||||||
|
return callback(err);
|
||||||
|
return callback(null, txs);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
BlockDB.prototype._getTXByAddress = function _getTXByAddress(address, callback) {
|
BlockDB.prototype._getTXByAddress = function _getTXByAddress(address, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var pending = 0;
|
var pending = 0;
|
||||||
@ -711,11 +916,11 @@ BlockDB.prototype._getTXByAddress = function _getTXByAddress(address, callback)
|
|||||||
pending++;
|
pending++;
|
||||||
|
|
||||||
if (self.options.cache && self.cache.tx.has(hash)) {
|
if (self.options.cache && self.cache.tx.has(hash)) {
|
||||||
coins.push(self.cache.tx.get(hash));
|
txs.push(self.cache.tx.get(hash));
|
||||||
pending--;
|
pending--;
|
||||||
if (done) {
|
if (done) {
|
||||||
if (!pending)
|
if (!pending)
|
||||||
return callback(null, coins);
|
return callback(null, txs);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user