Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
7039ee8
address: refactor blockHandler to be async
Feb 22, 2016
69587e2
address: calculate sums for addresses
Feb 23, 2016
279deb4
db: increase default max open files
Feb 23, 2016
81765df
address: add unspent and txids indexes
Feb 23, 2016
4c54a15
address: decode txids buffer
Feb 24, 2016
231eb9d
address: new key for each address -> txid
Feb 24, 2016
4846ff2
address: update docs with new index
Feb 24, 2016
3ba1406
address: start update getBalance and getTransactionIds queries
Feb 24, 2016
987f040
address: removed outdated methods
Feb 24, 2016
a9a8f95
address: update indexes, start to update query methods
Feb 24, 2016
295c39d
db: index more block information for faster queries
Feb 25, 2016
6a56ffd
db: fix for timestamp decoding
Feb 25, 2016
c175570
db: restore transaction with populate method
Feb 25, 2016
ae1a0a2
address: update getAddressSummary method
Feb 25, 2016
744d676
address: restore populateInputs for transaction details
Feb 25, 2016
9f28e8f
db: bump version of db
Feb 25, 2016
7781fb5
address: concat txids at the end of the address summary
Mar 1, 2016
e921f4d
address: fix issue with count and txids buffer
Mar 1, 2016
07eb3f6
address: fix issue with getting transaction ids
Mar 1, 2016
c09eb40
address: fix pagination
Mar 1, 2016
8bdd3a3
db: start upgrade to mongodb
Mar 2, 2016
e75e8f6
db: add version to block info
Mar 2, 2016
321d0d0
address: start to update to use mongodb
Mar 2, 2016
7f47a90
db/address: continue update to mongodb
Mar 2, 2016
349f81f
address: fix issue with incrementing by null
Mar 2, 2016
739f4f7
db/address: use compressed document keys
Mar 2, 2016
5723efd
address: continue with updating indexer to use mongo
Mar 3, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ nodeVersionCheck(process.versions.node, packageData.engines.node);
module.exports = require('./lib');
module.exports.nodeVersionCheck = nodeVersionCheck;
module.exports.Node = require('./lib/node');
module.exports.Transaction = require('./lib/transaction');
module.exports.Service = require('./lib/service');
module.exports.errors = require('./lib/errors');

Expand Down
16 changes: 13 additions & 3 deletions lib/services/address/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
var exports = {};

exports.PREFIXES = {
OUTPUTS: new Buffer('02', 'hex'), // Query outputs by address and/or height
SPENTS: new Buffer('03', 'hex'), // Query inputs by address and/or height
SPENTSMAP: new Buffer('05', 'hex') // Get the input that spends an output
SUMMARY: new Buffer('02', 'hex'), // Query the balance of an address
UNSPENT: new Buffer('03', 'hex'), // Query unspent output positions
PREV: new Buffer('05', 'hex'), // Query the address and satoshis for an output by txid and output index
TXIDS: new Buffer('06', 'hex') // Query all of the txids for an address
};

exports.MEMPREFIXES = {
Expand All @@ -29,6 +30,13 @@ exports.HASH_TYPES_READABLE = {
'02': 'scripthash'
};

exports.ADDRESS_KEY_SIZE = 21;
exports.SPACER_SIZE = 1;
exports.PREFIX_SIZE = 1;
exports.HEIGHT_SIZE = 4;
exports.TXID_SIZE = 32;
exports.PAGE_SIZE = 10;

exports.HASH_TYPES_MAP = {
'pubkeyhash': exports.HASH_TYPES.PUBKEY,
'scripthash': exports.HASH_TYPES.REDEEMSCRIPT
Expand All @@ -51,6 +59,8 @@ exports.MAX_HISTORY_QUERY_LENGTH = 100;
exports.MAX_ADDRESSES_QUERY = 10000;
// The maximum number of simultaneous requests
exports.MAX_ADDRESSES_LIMIT = 5;
// The maximum number of transactions that can be queried with multiple addresses
exports.MAX_MULTI_HISTORY_COUNT = 1000000;

module.exports = exports;

181 changes: 116 additions & 65 deletions lib/services/address/encoding.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,104 @@ var $ = bitcore.util.preconditions;

var exports = {};

exports.encodeSpentIndexSyncKey = function(txidBuffer, outputIndex) {
var outputIndexBuffer = new Buffer(4);
exports.encodeAddressTxIdKey = function(hashBuffer, hashTypeBuffer) {
return Buffer.concat([
constants.PREFIXES.TXIDS,
hashBuffer,
hashTypeBuffer
]);
};

exports.decodeAddressTxIdValue = function(buffer, page, range) {
var pos = 0;
if (page) {
pos = 36 * page * range;
}
var txids = [];
while (pos < buffer.length) {
var height = buffer.readUInt32BE(pos);
var txid = buffer.slice(pos, pos + 32);
txids.push({
height: height,
txid: txid
});
pos += 36;
}
return txids;
};

exports.encodePrevOutputKey = function(prevTxIdBuffer, outputIndex) {
var outputIndexBuffer = new Buffer(new Array(4));
outputIndexBuffer.writeUInt32BE(outputIndex);
var key = Buffer.concat([
txidBuffer,
return Buffer.concat([
constants.PREFIXES.PREV,
prevTxIdBuffer,
outputIndexBuffer
]);
return key.toString('binary');
};

exports.encodeMempoolAddressIndexKey = function(hashBuffer, hashTypeBuffer) {
var key = Buffer.concat([
exports.encodePrevOutputValue = function(hashBuffer, hashTypeBuffer, satoshis) {
var satoshisBuffer = new Buffer(new Array(8));
satoshisBuffer.writeDoubleBE(satoshis);
return Buffer.concat([
hashBuffer,
hashTypeBuffer,
satoshisBuffer
]);
return key.toString('binary');
};

exports.encodeSummaryKey = function(hashBuffer, hashTypeBuffer) {
return Buffer.concat([
constants.PREFIXES.SUMMARY,
hashBuffer,
hashTypeBuffer
]);
};

exports.encodeOutputKey = function(hashBuffer, hashTypeBuffer, height, txidBuffer, outputIndex) {
var heightBuffer = new Buffer(4);
heightBuffer.writeUInt32BE(height);
/**
* This function is optimized to return address information about an output script
* without constructing a Bitcore Address instance.
* @param {Script} - An instance of a Bitcore Script
* @param {Network|String} - The network for the address
*/
exports.extractAddressInfoFromScript = function(script, network) {
$.checkArgument(network, 'Second argument is expected to be a network');
var hashBuffer;
var addressType;
var hashTypeBuffer;
if (script.isPublicKeyHashOut()) {
hashBuffer = script.chunks[2].buf;
hashTypeBuffer = constants.HASH_TYPES.PUBKEY;
addressType = Address.PayToPublicKeyHash;
} else if (script.isScriptHashOut()) {
hashBuffer = script.chunks[1].buf;
hashTypeBuffer = constants.HASH_TYPES.REDEEMSCRIPT;
addressType = Address.PayToScriptHash;
} else if (script.isPublicKeyOut()) {
var pubkey = script.chunks[0].buf;
var address = Address.fromPublicKey(new PublicKey(pubkey), network);
hashBuffer = address.hashBuffer;
hashTypeBuffer = constants.HASH_TYPES.PUBKEY;
// pay-to-publickey doesn't have an address, however for compatibility
// purposes, we can create an address
addressType = Address.PayToPublicKeyHash;
} else {
return false;
}
return {
hashBuffer: hashBuffer,
hashTypeBuffer: hashTypeBuffer,
addressType: addressType
};
};

exports.encodeUnspentKey = function(hashBuffer, hashTypeBuffer, height, txidBuffer, outputIndex) {
var outputIndexBuffer = new Buffer(4);
outputIndexBuffer.writeUInt32BE(outputIndex);
var heightBuffer = new Buffer(4);
heightBuffer.writeUInt32BE(height);
var key = Buffer.concat([
constants.PREFIXES.OUTPUTS,
constants.PREFIXES.UNSPENT,
hashBuffer,
hashTypeBuffer,
constants.SPACER_MIN,
Expand All @@ -53,21 +125,46 @@ exports.decodeOutputKey = function(buffer) {
var spacer = reader.read(1);
var height = reader.readUInt32BE();
var txid = reader.read(32);
var outputIndex = reader.readUInt32BE();
return {
prefix: prefix,
hashBuffer: hashBuffer,
hashTypeBuffer: hashTypeBuffer,
height: height,
txid: txid,
txid: txid
};
};

exports.encodeOutputValue = function(outputIndex, satoshis) {
var outputIndexBuffer = new Buffer(4);
outputIndexBuffer.writeUInt32BE(outputIndex);
return outputIndexBuffer;
};

exports.decodeOutputValue = function(buffer) {
var outputIndex = buffer.readUInt32BE(0);
return {
outputIndex: outputIndex
};
};

exports.encodeOutputValue = function(satoshis, scriptBuffer) {
var satoshisBuffer = new Buffer(8);
satoshisBuffer.writeDoubleBE(satoshis);
return Buffer.concat([satoshisBuffer, scriptBuffer]);
////////////////////////////////////////////////////////////////////////////////////

exports.encodeSpentIndexSyncKey = function(txidBuffer, outputIndex) {
var outputIndexBuffer = new Buffer(4);
outputIndexBuffer.writeUInt32BE(outputIndex);
var key = Buffer.concat([
txidBuffer,
outputIndexBuffer
]);
return key.toString('binary');
};

exports.encodeMempoolAddressIndexKey = function(hashBuffer, hashTypeBuffer) {
var key = Buffer.concat([
hashBuffer,
hashTypeBuffer,
]);
return key.toString('binary');
};

exports.encodeOutputMempoolValue = function(satoshis, timestampBuffer, scriptBuffer) {
Expand All @@ -76,15 +173,6 @@ exports.encodeOutputMempoolValue = function(satoshis, timestampBuffer, scriptBuf
return Buffer.concat([satoshisBuffer, timestampBuffer, scriptBuffer]);
};

exports.decodeOutputValue = function(buffer) {
var satoshis = buffer.readDoubleBE(0);
var scriptBuffer = buffer.slice(8, buffer.length);
return {
satoshis: satoshis,
scriptBuffer: scriptBuffer
};
};

exports.decodeOutputMempoolValue = function(buffer) {
var satoshis = buffer.readDoubleBE(0);
var timestamp = buffer.readDoubleBE(8);
Expand Down Expand Up @@ -259,49 +347,12 @@ exports.decodeSummaryCacheValue = function(buffer) {
exports.getAddressInfo = function(addressStr) {
var addrObj = bitcore.Address(addressStr);
var hashTypeBuffer = constants.HASH_TYPES_MAP[addrObj.type];

return {
hashBuffer: addrObj.hashBuffer,
hashTypeBuffer: hashTypeBuffer,
hashTypeReadable: addrObj.type
};
};

/**
* This function is optimized to return address information about an output script
* without constructing a Bitcore Address instance.
* @param {Script} - An instance of a Bitcore Script
* @param {Network|String} - The network for the address
*/
exports.extractAddressInfoFromScript = function(script, network) {
$.checkArgument(network, 'Second argument is expected to be a network');
var hashBuffer;
var addressType;
var hashTypeBuffer;
if (script.isPublicKeyHashOut()) {
hashBuffer = script.chunks[2].buf;
hashTypeBuffer = constants.HASH_TYPES.PUBKEY;
addressType = Address.PayToPublicKeyHash;
} else if (script.isScriptHashOut()) {
hashBuffer = script.chunks[1].buf;
hashTypeBuffer = constants.HASH_TYPES.REDEEMSCRIPT;
addressType = Address.PayToScriptHash;
} else if (script.isPublicKeyOut()) {
var pubkey = script.chunks[0].buf;
var address = Address.fromPublicKey(new PublicKey(pubkey), network);
hashBuffer = address.hashBuffer;
hashTypeBuffer = constants.HASH_TYPES.PUBKEY;
// pay-to-publickey doesn't have an address, however for compatibility
// purposes, we can create an address
addressType = Address.PayToPublicKeyHash;
} else {
return false;
}
return {
hashBuffer: hashBuffer,
hashTypeBuffer: hashTypeBuffer,
addressType: addressType
};
};

module.exports = exports;
Loading