getAddressHistory

This commit is contained in:
Patrick Nagurny 2017-01-23 16:59:26 -05:00
parent 831bf0b988
commit 3c27f07291
2 changed files with 117 additions and 25 deletions

View File

@ -13,30 +13,53 @@ function Encoding(prefix) {
this.prefix = prefix;
}
Encoding.prototype.getTerminalKey = function(startKey) {
var endKey = Buffer.from(startKey);
endKey.writeUInt8(startKey.readUInt8(startKey.length - 1) + 1, startKey.length - 1);
return endKey;
};
Encoding.prototype.encodeAddressIndexKey = function(address, isSpent, height, txid, index, spending) {
// TODO if later params are given but not earlier ones, throw an error
var buffers = [this.prefix];
var addressSizeBuffer = new Buffer(1);
addressSizeBuffer.writeUInt8(address.length);
var addressBuffer = new Buffer(address, 'utf8');
var heightBuffer = new Buffer(4);
heightBuffer.writeUInt32BE(height);
var txidBuffer = new Buffer(txid, 'hex');
var indexBuffer = new Buffer(4);
indexBuffer.writeUInt32BE(index);
var spendingBuffer = new Buffer(1);
spendingBuffer.writeUInt8(spending);
var isSpentBuffer = new Buffer(1);
isSpentBuffer.writeUInt8(isSpent);
return Buffer.concat([
this.prefix,
addressSizeBuffer,
addressBuffer,
isSpentBuffer,
heightBuffer,
txidBuffer,
indexBuffer,
spendingBuffer
]);
buffers.push(addressSizeBuffer);
buffers.push(addressBuffer);
if(isSpent !== undefined) {
var isSpentBuffer = new Buffer(1);
isSpentBuffer.writeUInt8(isSpent);
buffers.push(isSpentBuffer);
}
if(height !== undefined) {
var heightBuffer = new Buffer(4);
heightBuffer.writeUInt32BE(height);
buffers.push(heightBuffer);
}
if(txid) {
var txidBuffer = new Buffer(txid, 'hex');
buffers.push(txidBuffer);
}
if(index !== undefined) {
var indexBuffer = new Buffer(4);
indexBuffer.writeUInt32BE(index);
buffers.push(indexBuffer);
}
if(spending !== undefined) {
var spendingBuffer = new Buffer(1);
spendingBuffer.writeUInt8(spending);
buffers.push(spendingBuffer);
}
return Buffer.concat(buffers);
};
Encoding.prototype.decodeAddressIndexKey = function(buffer) {

View File

@ -1058,13 +1058,82 @@ AddressService.prototype.isSpent = function(output, options, callback) {
* @param {Function} callback
*/
AddressService.prototype.getAddressHistory = function(addresses, options, callback) {
var self = this;
//var history = new AddressHistory({
// node: this.node,
// options: options,
// addresses: addresses
//});
//history.get(callback);
var txids = [];
async.eachLimit(addresses, self.concurrency, function(address, next) {
self.getAddressTxids(address, options, function(err, tmpTxids) {
if(err) {
return next(err);
}
txids = _.union(txids, tmpTxids);
return next();
});
}, function(err) {
async.mapLimit(txids, self.concurrency, function(txid, next) {
self.node.services.transaction.getTransaction(txid, function(err, tx) {
if(err) {
return next(err);
}
var txObj = tx.toObject();
for(var i = 0; i < txObj.inputs.length; i++) {
txObj.inputs[i].satoshis = tx.__inputValues[i];
}
next(null, txObj);
});
}, callback);
});
};
AddressService.prototype.getAddressTxids = function(address, options, callback) {
var self = this;
self._getAddressTxidsByIndex(address, false, options.start, options.end, function(err, txids1) {
if(err) {
return callback(err);
}
self._getAddressTxidsByIndex(address, true, options.start, options.end, function(err, txids2) {
if(err) {
return callback(err);
}
callback(null, _.union(txids1, txids2));
});
});
};
AddressService.prototype._getAddressTxidsByIndex = function(address, isSpent, startHeight, endHeight, callback) {
var self = this;
var txids = {};
var start = self.encoding.encodeAddressIndexKey(address, isSpent, startHeight);
var end = self.encoding.encodeAddressIndexKey(address, isSpent, endHeight);
var stream = self.store.createKeyStream({
gte: start,
lt: end
});
var streamErr = null;
stream.on('data', function(buffer) {
var key = self.encoding.decodeAddressIndexKey(buffer);
txids[key.txid] = true;
});
stream.on('end', function() {
callback(streamErr, Object.keys(txids));
});
stream.on('error', function(err) {
streamErr = err;
});
};
/**