Fix #377; db must contain hash type, not just hash.
Prevents erroneous crediting of all transactions to both the p2pkh and the corresponding p2sh address.
This commit is contained in:
parent
858182a346
commit
3214390d4c
@ -726,8 +726,9 @@ describe('Node Functionality', function() {
|
||||
node.services.bitcoind.sendTransaction(tx.serialize());
|
||||
|
||||
setImmediate(function() {
|
||||
var hashBuffer = bitcore.Address(address).hashBuffer;
|
||||
node.services.address._getOutputsMempool(address, hashBuffer, function(err, outs) {
|
||||
var addrObj = node.services.address._getAddressInfo(address);
|
||||
node.services.address._getOutputsMempool(address, addrObj.hashBuffer,
|
||||
addrObj.hashTypeBuffer, function(err, outs) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
@ -70,6 +70,27 @@ AddressService.MEMPREFIXES = {
|
||||
SPENTSMAP: new Buffer('03', 'hex') // Query mempool for the input that spends an output
|
||||
};
|
||||
|
||||
// To save space, we're only storing the PubKeyHash or ScriptHash in our index.
|
||||
// To avoid intentional unspendable collisions, which have been seen on the blockchain,
|
||||
// we must store the hash type (PK or Script) as well.
|
||||
AddressService.HASH_TYPES = {
|
||||
PUBKEY: new Buffer('01', 'hex'),
|
||||
REDEEMSCRIPT: new Buffer('02', 'hex')
|
||||
};
|
||||
|
||||
// Translates from our enum type back into the hash types returned by
|
||||
// bitcore-lib/address.
|
||||
AddressService.HASH_TYPES_READABLE = {
|
||||
'01': 'pubkeyhash',
|
||||
'02': 'scripthash'
|
||||
};
|
||||
|
||||
// Trnaslates from address types to our enum type.
|
||||
AddressService.HASH_TYPES_MAP = {
|
||||
'pubkeyhash': AddressService.HASH_TYPES.PUBKEY,
|
||||
'scripthash': AddressService.HASH_TYPES.REDEEMSCRIPT
|
||||
};
|
||||
|
||||
AddressService.SPACER_MIN = new Buffer('00', 'hex');
|
||||
AddressService.SPACER_MAX = new Buffer('ff', 'hex');
|
||||
|
||||
@ -303,6 +324,7 @@ AddressService.prototype.updateMempoolIndex = function(tx, add, callback) {
|
||||
var outKey = Buffer.concat([
|
||||
AddressService.MEMPREFIXES.OUTPUTS,
|
||||
addressInfo.hashBuffer,
|
||||
addressInfo.hashTypeBuffer,
|
||||
txidBuffer,
|
||||
outputIndexBuffer
|
||||
]);
|
||||
@ -355,16 +377,20 @@ AddressService.prototype.updateMempoolIndex = function(tx, add, callback) {
|
||||
|
||||
// Update input index
|
||||
var inputHashBuffer;
|
||||
var inputHashType;
|
||||
if (input.script.isPublicKeyHashIn()) {
|
||||
inputHashBuffer = Hash.sha256ripemd160(input.script.chunks[1].buf);
|
||||
inputHashType = AddressService.HASH_TYPES.PUBKEY;
|
||||
} else if (input.script.isScriptHashIn()) {
|
||||
inputHashBuffer = Hash.sha256ripemd160(input.script.chunks[input.script.chunks.length - 1].buf);
|
||||
inputHashType = AddressService.HASH_TYPES.REDEEMSCRIPT;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
var inputKey = Buffer.concat([
|
||||
AddressService.MEMPREFIXES.SPENTS,
|
||||
inputHashBuffer,
|
||||
inputHashType,
|
||||
input.prevTxId,
|
||||
inputOutputIndexBuffer
|
||||
]);
|
||||
@ -389,7 +415,6 @@ AddressService.prototype.updateMempoolIndex = function(tx, add, callback) {
|
||||
}
|
||||
|
||||
this.mempoolIndex.batch(operations, callback);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@ -401,16 +426,20 @@ AddressService.prototype.updateMempoolIndex = function(tx, add, callback) {
|
||||
AddressService.prototype._extractAddressInfoFromScript = function(script) {
|
||||
var hashBuffer;
|
||||
var addressType;
|
||||
var hashTypeBuffer;
|
||||
if (script.isPublicKeyHashOut()) {
|
||||
hashBuffer = script.chunks[2].buf;
|
||||
hashTypeBuffer = AddressService.HASH_TYPES.PUBKEY;
|
||||
addressType = Address.PayToPublicKeyHash;
|
||||
} else if (script.isScriptHashOut()) {
|
||||
hashBuffer = script.chunks[1].buf;
|
||||
hashTypeBuffer = AddressService.HASH_TYPES.REDEEMSCRIPT;
|
||||
addressType = Address.PayToScriptHash;
|
||||
} else if (script.isPublicKeyOut()) {
|
||||
var pubkey = script.chunks[0].buf;
|
||||
var address = Address.fromPublicKey(new PublicKey(pubkey), this.node.network);
|
||||
hashBuffer = address.hashBuffer;
|
||||
hashTypeBuffer = AddressService.HASH_TYPES.PUBKEY;
|
||||
// pay-to-publickey doesn't have an address, however for compatibility
|
||||
// purposes, we can create an address
|
||||
addressType = Address.PayToPublicKeyHash;
|
||||
@ -419,6 +448,7 @@ AddressService.prototype._extractAddressInfoFromScript = function(script) {
|
||||
}
|
||||
return {
|
||||
hashBuffer: hashBuffer,
|
||||
hashTypeBuffer: hashTypeBuffer,
|
||||
addressType: addressType
|
||||
};
|
||||
};
|
||||
@ -474,7 +504,8 @@ AddressService.prototype.blockHandler = function(block, addOutput, callback) {
|
||||
// can have a time that is previous to the previous block (however not
|
||||
// less than the mean of the 11 previous blocks) and not greater than 2
|
||||
// hours in the future.
|
||||
var key = this._encodeOutputKey(addressInfo.hashBuffer, height, txidBuffer, outputIndex);
|
||||
var key = this._encodeOutputKey(addressInfo.hashBuffer, addressInfo.hashTypeBuffer,
|
||||
height, txidBuffer, outputIndex);
|
||||
var value = this._encodeOutputValue(output.satoshis, output._scriptBuffer);
|
||||
operations.push({
|
||||
type: action,
|
||||
@ -514,11 +545,14 @@ AddressService.prototype.blockHandler = function(block, addOutput, callback) {
|
||||
|
||||
var input = inputs[inputIndex];
|
||||
var inputHash;
|
||||
var inputHashType;
|
||||
|
||||
if (input.script.isPublicKeyHashIn()) {
|
||||
inputHash = Hash.sha256ripemd160(input.script.chunks[1].buf);
|
||||
inputHashType = AddressService.HASH_TYPES.PUBKEY;
|
||||
} else if (input.script.isScriptHashIn()) {
|
||||
inputHash = Hash.sha256ripemd160(input.script.chunks[input.script.chunks.length - 1].buf);
|
||||
inputHashType = AddressService.HASH_TYPES.REDEEMSCRIPT;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
@ -526,7 +560,7 @@ AddressService.prototype.blockHandler = function(block, addOutput, callback) {
|
||||
var prevTxIdBuffer = new Buffer(input.prevTxId, 'hex');
|
||||
|
||||
// To be able to query inputs by address and spent height
|
||||
var inputKey = this._encodeInputKey(inputHash, height, prevTxIdBuffer, input.outputIndex);
|
||||
var inputKey = this._encodeInputKey(inputHash, inputHashType, height, prevTxIdBuffer, input.outputIndex);
|
||||
var inputValue = this._encodeInputValue(txidBuffer, inputIndex);
|
||||
|
||||
operations.push({
|
||||
@ -563,7 +597,7 @@ AddressService.prototype._encodeSpentIndexSyncKey = function(txidBuffer, outputI
|
||||
return key.toString('binary');
|
||||
};
|
||||
|
||||
AddressService.prototype._encodeOutputKey = function(hashBuffer, height, txidBuffer, outputIndex) {
|
||||
AddressService.prototype._encodeOutputKey = function(hashBuffer, hashTypeBuffer, height, txidBuffer, outputIndex) {
|
||||
var heightBuffer = new Buffer(4);
|
||||
heightBuffer.writeUInt32BE(height);
|
||||
var outputIndexBuffer = new Buffer(4);
|
||||
@ -571,6 +605,7 @@ AddressService.prototype._encodeOutputKey = function(hashBuffer, height, txidBuf
|
||||
var key = Buffer.concat([
|
||||
AddressService.PREFIXES.OUTPUTS,
|
||||
hashBuffer,
|
||||
hashTypeBuffer,
|
||||
AddressService.SPACER_MIN,
|
||||
heightBuffer,
|
||||
txidBuffer,
|
||||
@ -583,6 +618,7 @@ AddressService.prototype._decodeOutputKey = function(buffer) {
|
||||
var reader = new BufferReader(buffer);
|
||||
var prefix = reader.read(1);
|
||||
var hashBuffer = reader.read(20);
|
||||
var hashTypeBuffer = reader.read(1);
|
||||
var spacer = reader.read(1);
|
||||
var height = reader.readUInt32BE();
|
||||
var txid = reader.read(32);
|
||||
@ -590,6 +626,7 @@ AddressService.prototype._decodeOutputKey = function(buffer) {
|
||||
return {
|
||||
prefix: prefix,
|
||||
hashBuffer: hashBuffer,
|
||||
hashTypeBuffer: hashTypeBuffer,
|
||||
height: height,
|
||||
txid: txid,
|
||||
outputIndex: outputIndex
|
||||
@ -611,7 +648,7 @@ AddressService.prototype._decodeOutputValue = function(buffer) {
|
||||
};
|
||||
};
|
||||
|
||||
AddressService.prototype._encodeInputKey = function(hashBuffer, height, prevTxIdBuffer, outputIndex) {
|
||||
AddressService.prototype._encodeInputKey = function(hashBuffer, hashTypeBuffer, height, prevTxIdBuffer, outputIndex) {
|
||||
var heightBuffer = new Buffer(4);
|
||||
heightBuffer.writeUInt32BE(height);
|
||||
var outputIndexBuffer = new Buffer(4);
|
||||
@ -619,6 +656,7 @@ AddressService.prototype._encodeInputKey = function(hashBuffer, height, prevTxId
|
||||
return Buffer.concat([
|
||||
AddressService.PREFIXES.SPENTS,
|
||||
hashBuffer,
|
||||
hashTypeBuffer,
|
||||
AddressService.SPACER_MIN,
|
||||
heightBuffer,
|
||||
prevTxIdBuffer,
|
||||
@ -630,6 +668,7 @@ AddressService.prototype._decodeInputKey = function(buffer) {
|
||||
var reader = new BufferReader(buffer);
|
||||
var prefix = reader.read(1);
|
||||
var hashBuffer = reader.read(20);
|
||||
var hashTypeBuffer = reader.read(1);
|
||||
var spacer = reader.read(1);
|
||||
var height = reader.readUInt32BE();
|
||||
var prevTxId = reader.read(32);
|
||||
@ -637,6 +676,7 @@ AddressService.prototype._decodeInputKey = function(buffer) {
|
||||
return {
|
||||
prefix: prefix,
|
||||
hashBuffer: hashBuffer,
|
||||
hashTypeBuffer: hashTypeBuffer,
|
||||
height: height,
|
||||
prevTxId: prevTxId,
|
||||
outputIndex: outputIndex
|
||||
@ -698,6 +738,17 @@ AddressService.prototype._decodeInputValueMap = function(buffer) {
|
||||
};
|
||||
};
|
||||
|
||||
AddressService.prototype._getAddressInfo = function(addressStr) {
|
||||
var addrObj = bitcore.Address(addressStr);
|
||||
var hashTypeBuffer = AddressService.HASH_TYPES_MAP[addrObj.type];
|
||||
|
||||
return {
|
||||
hashBuffer: addrObj.hashBuffer,
|
||||
hashTypeBuffer: hashTypeBuffer,
|
||||
hashTypeReadable: addrObj.type
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* This function is responsible for emitting events to any subscribers to the
|
||||
* `address/transaction` event.
|
||||
@ -902,6 +953,7 @@ AddressService.prototype.getInputForOutput = function(txid, outputIndex, options
|
||||
/**
|
||||
* Will give inputs that spend previous outputs for an address as an object with:
|
||||
* address - The base58check encoded address
|
||||
* hashType - The type of the address, e.g. 'pubkeyhash' or 'scripthash'
|
||||
* txid - A string of the transaction hash
|
||||
* outputIndex - A number of corresponding transaction input
|
||||
* height - The height of the block the transaction was included, will be -1 for mempool transactions
|
||||
@ -921,7 +973,12 @@ AddressService.prototype.getInputs = function(addressStr, options, callback) {
|
||||
var inputs = [];
|
||||
var stream;
|
||||
|
||||
var hashBuffer = bitcore.Address(addressStr).hashBuffer;
|
||||
var addrObj = this._getAddressInfo(addressStr);
|
||||
var hashBuffer = addrObj.hashBuffer;
|
||||
var hashTypeBuffer = addrObj.hashTypeBuffer;
|
||||
if (!hashTypeBuffer) {
|
||||
return callback(new Error('Unknown address type: ' + addrObj.hashTypeReadable + ' for address: ' + addressStr));
|
||||
}
|
||||
|
||||
if (options.start && options.end) {
|
||||
|
||||
@ -935,12 +992,14 @@ AddressService.prototype.getInputs = function(addressStr, options, callback) {
|
||||
gte: Buffer.concat([
|
||||
AddressService.PREFIXES.SPENTS,
|
||||
hashBuffer,
|
||||
hashTypeBuffer,
|
||||
AddressService.SPACER_MIN,
|
||||
endBuffer
|
||||
]),
|
||||
lte: Buffer.concat([
|
||||
AddressService.PREFIXES.SPENTS,
|
||||
hashBuffer,
|
||||
hashTypeBuffer,
|
||||
AddressService.SPACER_MIN,
|
||||
startBuffer
|
||||
]),
|
||||
@ -948,7 +1007,7 @@ AddressService.prototype.getInputs = function(addressStr, options, callback) {
|
||||
keyEncoding: 'binary'
|
||||
});
|
||||
} else {
|
||||
var allKey = Buffer.concat([AddressService.PREFIXES.SPENTS, hashBuffer]);
|
||||
var allKey = Buffer.concat([AddressService.PREFIXES.SPENTS, hashBuffer, hashTypeBuffer]);
|
||||
stream = this.node.services.db.store.createReadStream({
|
||||
gte: Buffer.concat([allKey, AddressService.SPACER_MIN]),
|
||||
lte: Buffer.concat([allKey, AddressService.SPACER_MAX]),
|
||||
@ -964,6 +1023,7 @@ AddressService.prototype.getInputs = function(addressStr, options, callback) {
|
||||
|
||||
var input = {
|
||||
address: addressStr,
|
||||
hashType: addrObj.hashTypeReadable,
|
||||
txid: value.txid.toString('hex'),
|
||||
inputIndex: value.inputIndex,
|
||||
height: key.height,
|
||||
@ -988,7 +1048,7 @@ AddressService.prototype.getInputs = function(addressStr, options, callback) {
|
||||
}
|
||||
|
||||
if(options.queryMempool) {
|
||||
self._getInputsMempool(addressStr, hashBuffer, function(err, mempoolInputs) {
|
||||
self._getInputsMempool(addressStr, hashBuffer, hashTypeBuffer, function(err, mempoolInputs) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
@ -1005,7 +1065,7 @@ AddressService.prototype.getInputs = function(addressStr, options, callback) {
|
||||
|
||||
};
|
||||
|
||||
AddressService.prototype._getInputsMempool = function(addressStr, hashBuffer, callback) {
|
||||
AddressService.prototype._getInputsMempool = function(addressStr, hashBuffer, hashTypeBuffer, callback) {
|
||||
var self = this;
|
||||
var mempoolInputs = [];
|
||||
|
||||
@ -1013,11 +1073,13 @@ AddressService.prototype._getInputsMempool = function(addressStr, hashBuffer, ca
|
||||
gte: Buffer.concat([
|
||||
AddressService.MEMPREFIXES.SPENTS,
|
||||
hashBuffer,
|
||||
hashTypeBuffer,
|
||||
AddressService.SPACER_MIN
|
||||
]),
|
||||
lte: Buffer.concat([
|
||||
AddressService.MEMPREFIXES.SPENTS,
|
||||
hashBuffer,
|
||||
hashTypeBuffer,
|
||||
AddressService.SPACER_MAX
|
||||
]),
|
||||
valueEncoding: 'binary',
|
||||
@ -1029,6 +1091,7 @@ AddressService.prototype._getInputsMempool = function(addressStr, hashBuffer, ca
|
||||
var inputIndex = data.value.readUInt32BE(32);
|
||||
var output = {
|
||||
address: addressStr,
|
||||
hashType: AddressService.HASH_TYPES_READABLE[hashTypeBuffer.toString('hex')],
|
||||
txid: txid.toString('hex'), //TODO use a buffer
|
||||
inputIndex: inputIndex,
|
||||
height: -1,
|
||||
@ -1082,6 +1145,7 @@ AddressService.prototype._getSpentMempool = function(txidBuffer, outputIndex, ca
|
||||
/**
|
||||
* Will give outputs for an address as an object with:
|
||||
* address - The base58check encoded address
|
||||
* hashType - The type of the address, e.g. 'pubkeyhash' or 'scripthash'
|
||||
* txid - A string of the transaction hash
|
||||
* outputIndex - A number of corresponding transaction output
|
||||
* height - The height of the block the transaction was included, will be -1 for mempool transactions
|
||||
@ -1101,7 +1165,12 @@ AddressService.prototype.getOutputs = function(addressStr, options, callback) {
|
||||
$.checkArgument(_.isObject(options), 'Second argument is expected to be an options object.');
|
||||
$.checkArgument(_.isFunction(callback), 'Third argument is expected to be a callback function.');
|
||||
|
||||
var hashBuffer = bitcore.Address(addressStr).hashBuffer;
|
||||
var addrObj = this._getAddressInfo(addressStr);
|
||||
var hashBuffer = addrObj.hashBuffer;
|
||||
var hashTypeBuffer = addrObj.hashTypeBuffer;
|
||||
if (!hashTypeBuffer) {
|
||||
return callback(new Error('Unknown address type: ' + addrObj.hashTypeReadable + ' for address: ' + addressStr));
|
||||
}
|
||||
|
||||
var outputs = [];
|
||||
var stream;
|
||||
@ -1117,12 +1186,14 @@ AddressService.prototype.getOutputs = function(addressStr, options, callback) {
|
||||
gte: Buffer.concat([
|
||||
AddressService.PREFIXES.OUTPUTS,
|
||||
hashBuffer,
|
||||
hashTypeBuffer,
|
||||
AddressService.SPACER_MIN,
|
||||
endBuffer
|
||||
]),
|
||||
lte: Buffer.concat([
|
||||
AddressService.PREFIXES.OUTPUTS,
|
||||
hashBuffer,
|
||||
hashTypeBuffer,
|
||||
AddressService.SPACER_MIN,
|
||||
startBuffer
|
||||
]),
|
||||
@ -1130,7 +1201,7 @@ AddressService.prototype.getOutputs = function(addressStr, options, callback) {
|
||||
keyEncoding: 'binary'
|
||||
});
|
||||
} else {
|
||||
var allKey = Buffer.concat([AddressService.PREFIXES.OUTPUTS, hashBuffer]);
|
||||
var allKey = Buffer.concat([AddressService.PREFIXES.OUTPUTS, hashBuffer, hashTypeBuffer]);
|
||||
stream = this.node.services.db.store.createReadStream({
|
||||
gte: Buffer.concat([allKey, AddressService.SPACER_MIN]),
|
||||
lte: Buffer.concat([allKey, AddressService.SPACER_MAX]),
|
||||
@ -1146,6 +1217,7 @@ AddressService.prototype.getOutputs = function(addressStr, options, callback) {
|
||||
|
||||
var output = {
|
||||
address: addressStr,
|
||||
hashType: addrObj.hashTypeReadable,
|
||||
txid: key.txid.toString('hex'), //TODO use a buffer
|
||||
outputIndex: key.outputIndex,
|
||||
height: key.height,
|
||||
@ -1172,7 +1244,7 @@ AddressService.prototype.getOutputs = function(addressStr, options, callback) {
|
||||
}
|
||||
|
||||
if(options.queryMempool) {
|
||||
self._getOutputsMempool(addressStr, hashBuffer, function(err, mempoolOutputs) {
|
||||
self._getOutputsMempool(addressStr, hashBuffer, hashTypeBuffer, function(err, mempoolOutputs) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
@ -1188,7 +1260,7 @@ AddressService.prototype.getOutputs = function(addressStr, options, callback) {
|
||||
|
||||
};
|
||||
|
||||
AddressService.prototype._getOutputsMempool = function(addressStr, hashBuffer, callback) {
|
||||
AddressService.prototype._getOutputsMempool = function(addressStr, hashBuffer, hashTypeBuffer, callback) {
|
||||
var self = this;
|
||||
var mempoolOutputs = [];
|
||||
|
||||
@ -1196,11 +1268,13 @@ AddressService.prototype._getOutputsMempool = function(addressStr, hashBuffer, c
|
||||
gte: Buffer.concat([
|
||||
AddressService.MEMPREFIXES.OUTPUTS,
|
||||
hashBuffer,
|
||||
hashTypeBuffer,
|
||||
AddressService.SPACER_MIN
|
||||
]),
|
||||
lte: Buffer.concat([
|
||||
AddressService.MEMPREFIXES.OUTPUTS,
|
||||
hashBuffer,
|
||||
hashTypeBuffer,
|
||||
AddressService.SPACER_MAX
|
||||
]),
|
||||
valueEncoding: 'binary',
|
||||
@ -1208,12 +1282,13 @@ AddressService.prototype._getOutputsMempool = function(addressStr, hashBuffer, c
|
||||
});
|
||||
|
||||
stream.on('data', function(data) {
|
||||
// Format of data: prefix: 1, hashBuffer: 20, txid: 32, outputIndex: 4
|
||||
var txid = data.key.slice(21, 53);
|
||||
var outputIndex = data.key.readUInt32BE(53);
|
||||
// Format of data: prefix: 1, hashBuffer: 20, hashTypeBuffer: 1, txid: 32, outputIndex: 4
|
||||
var txid = data.key.slice(22, 54);
|
||||
var outputIndex = data.key.readUInt32BE(54);
|
||||
var value = self._decodeOutputValue(data.value);
|
||||
var output = {
|
||||
address: addressStr,
|
||||
hashType: AddressService.HASH_TYPES_READABLE[hashTypeBuffer.toString('hex')],
|
||||
txid: txid.toString('hex'), //TODO use a buffer
|
||||
outputIndex: outputIndex,
|
||||
height: -1,
|
||||
|
||||
@ -343,7 +343,9 @@ describe('Address Service', function() {
|
||||
});
|
||||
am.node.network = Networks.livenet;
|
||||
var address = '12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX';
|
||||
var hashHex = bitcore.Address(address).hashBuffer.toString('hex');
|
||||
var addrObj = bitcore.Address(address);
|
||||
var hashHex = addrObj.hashBuffer.toString('hex');
|
||||
var hashType = addrObj.type;
|
||||
var messages = {};
|
||||
am.transactionOutputHandler(messages, tx, 0, true);
|
||||
should.exist(messages[hashHex]);
|
||||
@ -351,6 +353,7 @@ describe('Address Service', function() {
|
||||
message.tx.should.equal(tx);
|
||||
message.outputIndexes.should.deep.equal([0]);
|
||||
message.addressInfo.hashBuffer.toString('hex').should.equal(hashHex);
|
||||
message.addressInfo.addressType.should.equal(hashType);
|
||||
message.addressInfo.hashHex.should.equal(hashHex);
|
||||
message.rejected.should.equal(true);
|
||||
});
|
||||
@ -446,16 +449,16 @@ describe('Address Service', function() {
|
||||
should.not.exist(err);
|
||||
operations.length.should.equal(151);
|
||||
operations[0].type.should.equal('put');
|
||||
operations[0].key.toString('hex').should.equal('0202a61d2066d19e9e2fd348a8320b7ebd4dd3ca2b00000543abfdbefe0d064729d85556bd3ab13c3a889b685d042499c02b4aa2064fb1e1692300000000');
|
||||
operations[0].key.toString('hex').should.equal('0202a61d2066d19e9e2fd348a8320b7ebd4dd3ca2b0100000543abfdbefe0d064729d85556bd3ab13c3a889b685d042499c02b4aa2064fb1e1692300000000');
|
||||
operations[0].value.toString('hex').should.equal('41e2a49ec1c0000076a91402a61d2066d19e9e2fd348a8320b7ebd4dd3ca2b88ac');
|
||||
operations[3].type.should.equal('put');
|
||||
operations[3].key.toString('hex').should.equal('03fdbd324b28ea69e49c998816407dc055fb81d06e00000543ab3d7d5d98df753ef2a4f82438513c509e3b11f3e738e94a7234967b03a03123a900000020');
|
||||
operations[3].key.toString('hex').should.equal('03fdbd324b28ea69e49c998816407dc055fb81d06e0100000543ab3d7d5d98df753ef2a4f82438513c509e3b11f3e738e94a7234967b03a03123a900000020');
|
||||
operations[3].value.toString('hex').should.equal('5780f3ee54889a0717152a01abee9a32cec1b0cdf8d5537a08c7bd9eeb6bfbca00000000');
|
||||
operations[4].type.should.equal('put');
|
||||
operations[4].key.toString('hex').should.equal('053d7d5d98df753ef2a4f82438513c509e3b11f3e738e94a7234967b03a03123a900000020');
|
||||
operations[4].value.toString('hex').should.equal('5780f3ee54889a0717152a01abee9a32cec1b0cdf8d5537a08c7bd9eeb6bfbca00000000');
|
||||
operations[121].type.should.equal('put');
|
||||
operations[121].key.toString('hex').should.equal('029780ccd5356e2acc0ee439ee04e0fe69426c752800000543abe66f3b989c790178de2fc1a5329f94c0d8905d0d3df4e7ecf0115e7f90a6283d00000001');
|
||||
operations[121].key.toString('hex').should.equal('029780ccd5356e2acc0ee439ee04e0fe69426c75280100000543abe66f3b989c790178de2fc1a5329f94c0d8905d0d3df4e7ecf0115e7f90a6283d00000001');
|
||||
operations[121].value.toString('hex').should.equal('4147a6b00000000076a9149780ccd5356e2acc0ee439ee04e0fe69426c752888ac');
|
||||
done();
|
||||
});
|
||||
@ -472,13 +475,13 @@ describe('Address Service', function() {
|
||||
should.not.exist(err);
|
||||
operations.length.should.equal(151);
|
||||
operations[0].type.should.equal('del');
|
||||
operations[0].key.toString('hex').should.equal('0202a61d2066d19e9e2fd348a8320b7ebd4dd3ca2b00000543abfdbefe0d064729d85556bd3ab13c3a889b685d042499c02b4aa2064fb1e1692300000000');
|
||||
operations[0].key.toString('hex').should.equal('0202a61d2066d19e9e2fd348a8320b7ebd4dd3ca2b0100000543abfdbefe0d064729d85556bd3ab13c3a889b685d042499c02b4aa2064fb1e1692300000000');
|
||||
operations[0].value.toString('hex').should.equal('41e2a49ec1c0000076a91402a61d2066d19e9e2fd348a8320b7ebd4dd3ca2b88ac');
|
||||
operations[3].type.should.equal('del');
|
||||
operations[3].key.toString('hex').should.equal('03fdbd324b28ea69e49c998816407dc055fb81d06e00000543ab3d7d5d98df753ef2a4f82438513c509e3b11f3e738e94a7234967b03a03123a900000020');
|
||||
operations[3].key.toString('hex').should.equal('03fdbd324b28ea69e49c998816407dc055fb81d06e0100000543ab3d7d5d98df753ef2a4f82438513c509e3b11f3e738e94a7234967b03a03123a900000020');
|
||||
operations[3].value.toString('hex').should.equal('5780f3ee54889a0717152a01abee9a32cec1b0cdf8d5537a08c7bd9eeb6bfbca00000000');
|
||||
operations[121].type.should.equal('del');
|
||||
operations[121].key.toString('hex').should.equal('029780ccd5356e2acc0ee439ee04e0fe69426c752800000543abe66f3b989c790178de2fc1a5329f94c0d8905d0d3df4e7ecf0115e7f90a6283d00000001');
|
||||
operations[121].key.toString('hex').should.equal('029780ccd5356e2acc0ee439ee04e0fe69426c75280100000543abe66f3b989c790178de2fc1a5329f94c0d8905d0d3df4e7ecf0115e7f90a6283d00000001');
|
||||
operations[121].value.toString('hex').should.equal('4147a6b00000000076a9149780ccd5356e2acc0ee439ee04e0fe69426c752888ac');
|
||||
done();
|
||||
});
|
||||
@ -818,6 +821,7 @@ describe('Address Service', function() {
|
||||
var am;
|
||||
var address = '1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W';
|
||||
var hashBuffer = bitcore.Address(address).hashBuffer;
|
||||
var hashTypeBuffer = AddressService.HASH_TYPES.PUBKEY;
|
||||
var db = {
|
||||
tip: {
|
||||
__height: 1
|
||||
@ -866,8 +870,9 @@ describe('Address Service', function() {
|
||||
end: 12,
|
||||
queryMempool: true
|
||||
};
|
||||
am._getInputsMempool = sinon.stub().callsArgWith(2, null, {
|
||||
am._getInputsMempool = sinon.stub().callsArgWith(3, null, {
|
||||
address: address,
|
||||
hashType: 'pubkeyhash',
|
||||
height: -1,
|
||||
confirmations: 0
|
||||
});
|
||||
@ -890,9 +895,11 @@ describe('Address Service', function() {
|
||||
var createReadStreamCallCount = 0;
|
||||
am.node.services.db.store = {
|
||||
createReadStream: function(ops) {
|
||||
var gte = Buffer.concat([AddressService.PREFIXES.SPENTS, hashBuffer, new Buffer('000000000c', 'hex')]);
|
||||
var gte = Buffer.concat([AddressService.PREFIXES.SPENTS, hashBuffer,
|
||||
hashTypeBuffer, new Buffer('000000000c', 'hex')]);
|
||||
ops.gte.toString('hex').should.equal(gte.toString('hex'));
|
||||
var lte = Buffer.concat([AddressService.PREFIXES.SPENTS, hashBuffer, new Buffer('0000000010', 'hex')]);
|
||||
var lte = Buffer.concat([AddressService.PREFIXES.SPENTS, hashBuffer,
|
||||
hashTypeBuffer, new Buffer('0000000010', 'hex')]);
|
||||
ops.lte.toString('hex').should.equal(lte.toString('hex'));
|
||||
createReadStreamCallCount++;
|
||||
return testStream;
|
||||
@ -901,7 +908,7 @@ describe('Address Service', function() {
|
||||
am.node.services.bitcoind = {
|
||||
getMempoolInputs: sinon.stub().returns([])
|
||||
};
|
||||
am._getInputsMempool = sinon.stub().callsArgWith(2, null, []);
|
||||
am._getInputsMempool = sinon.stub().callsArgWith(3, null, []);
|
||||
am.getInputs(address, args, function(err, inputs) {
|
||||
should.not.exist(err);
|
||||
inputs.length.should.equal(1);
|
||||
@ -913,7 +920,7 @@ describe('Address Service', function() {
|
||||
});
|
||||
createReadStreamCallCount.should.equal(1);
|
||||
var data = {
|
||||
key: new Buffer('33038a213afdfc551fc658e9a2a58a86e98d69b687000000000f125dd0e50fc732d67c37b6c56be7f9dc00b6859cebf982ee2cc83ed2d604bf8700000001', 'hex'),
|
||||
key: new Buffer('33038a213afdfc551fc658e9a2a58a86e98d69b68701000000000f125dd0e50fc732d67c37b6c56be7f9dc00b6859cebf982ee2cc83ed2d604bf8700000001', 'hex'),
|
||||
value: new Buffer('3b6bc2939d1a70ce04bc4f619ee32608fbff5e565c1f9b02e4eaa97959c59ae700000000', 'hex')
|
||||
};
|
||||
testStream.emit('data', data);
|
||||
@ -927,9 +934,9 @@ describe('Address Service', function() {
|
||||
var createReadStreamCallCount = 0;
|
||||
am.node.services.db.store = {
|
||||
createReadStream: function(ops) {
|
||||
var gte = Buffer.concat([AddressService.PREFIXES.SPENTS, hashBuffer, new Buffer('00', 'hex')]);
|
||||
var gte = Buffer.concat([AddressService.PREFIXES.SPENTS, hashBuffer, hashTypeBuffer, new Buffer('00', 'hex')]);
|
||||
ops.gte.toString('hex').should.equal(gte.toString('hex'));
|
||||
var lte = Buffer.concat([AddressService.PREFIXES.SPENTS, hashBuffer, new Buffer('ff', 'hex')]);
|
||||
var lte = Buffer.concat([AddressService.PREFIXES.SPENTS, hashBuffer, hashTypeBuffer, new Buffer('ff', 'hex')]);
|
||||
ops.lte.toString('hex').should.equal(lte.toString('hex'));
|
||||
createReadStreamCallCount++;
|
||||
return testStream;
|
||||
@ -949,7 +956,7 @@ describe('Address Service', function() {
|
||||
});
|
||||
createReadStreamCallCount.should.equal(1);
|
||||
var data = {
|
||||
key: new Buffer('33038a213afdfc551fc658e9a2a58a86e98d69b687000000000f125dd0e50fc732d67c37b6c56be7f9dc00b6859cebf982ee2cc83ed2d604bf8700000001', 'hex'),
|
||||
key: new Buffer('33038a213afdfc551fc658e9a2a58a86e98d69b68701000000000f125dd0e50fc732d67c37b6c56be7f9dc00b6859cebf982ee2cc83ed2d604bf8700000001', 'hex'),
|
||||
value: new Buffer('3b6bc2939d1a70ce04bc4f619ee32608fbff5e565c1f9b02e4eaa97959c59ae700000000', 'hex')
|
||||
};
|
||||
testStream.emit('data', data);
|
||||
@ -979,6 +986,7 @@ describe('Address Service', function() {
|
||||
var am;
|
||||
var address = '1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W';
|
||||
var hashBuffer = bitcore.Address(address).hashBuffer;
|
||||
var hashTypeBuffer = AddressService.HASH_TYPES.PUBKEY;
|
||||
var db = {
|
||||
tip: {
|
||||
__height: 1
|
||||
@ -1005,7 +1013,7 @@ describe('Address Service', function() {
|
||||
am.mempoolIndex = {};
|
||||
am.mempoolIndex.createReadStream = sinon.stub().returns(testStream);
|
||||
|
||||
am._getInputsMempool(address, hashBuffer, function(err, outputs) {
|
||||
am._getInputsMempool(address, hashBuffer, hashTypeBuffer, function(err, outputs) {
|
||||
should.exist(err);
|
||||
err.message.should.equal('readstreamerror');
|
||||
done();
|
||||
@ -1021,11 +1029,13 @@ describe('Address Service', function() {
|
||||
am.mempoolIndex = {};
|
||||
am.mempoolIndex.createReadStream = sinon.stub().returns(testStream);
|
||||
|
||||
am._getInputsMempool(address, hashBuffer, function(err, outputs) {
|
||||
am._getInputsMempool(address, hashBuffer, hashTypeBuffer, function(err, outputs) {
|
||||
should.not.exist(err);
|
||||
outputs.length.should.equal(1);
|
||||
outputs[0].address.should.equal(address);
|
||||
outputs[0].txid.should.equal(txid);
|
||||
outputs[0].hashType.should.equal('pubkeyhash');
|
||||
outputs[0].hashType.should.equal(AddressService.HASH_TYPES_READABLE[hashTypeBuffer.toString('hex')]);
|
||||
outputs[0].inputIndex.should.equal(5);
|
||||
outputs[0].height.should.equal(-1);
|
||||
outputs[0].confirmations.should.equal(0);
|
||||
@ -1099,6 +1109,7 @@ describe('Address Service', function() {
|
||||
var am;
|
||||
var address = '1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W';
|
||||
var hashBuffer = bitcore.Address('1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W').hashBuffer;
|
||||
var hashTypeBuffer = AddressService.HASH_TYPES.PUBKEY;
|
||||
var db = {
|
||||
tip: {
|
||||
__height: 1
|
||||
@ -1135,20 +1146,22 @@ describe('Address Service', function() {
|
||||
var createReadStreamCallCount = 0;
|
||||
am.node.services.db.store = {
|
||||
createReadStream: function(ops) {
|
||||
var gte = Buffer.concat([AddressService.PREFIXES.OUTPUTS, hashBuffer, new Buffer('000000000c', 'hex')]);
|
||||
var gte = Buffer.concat([AddressService.PREFIXES.OUTPUTS, hashBuffer, hashTypeBuffer, new Buffer('000000000c', 'hex')]);
|
||||
ops.gte.toString('hex').should.equal(gte.toString('hex'));
|
||||
var lte = Buffer.concat([AddressService.PREFIXES.OUTPUTS, hashBuffer, new Buffer('0000000010', 'hex')]);
|
||||
var lte = Buffer.concat([AddressService.PREFIXES.OUTPUTS, hashBuffer, hashTypeBuffer, new Buffer('0000000010', 'hex')]);
|
||||
ops.lte.toString('hex').should.equal(lte.toString('hex'));
|
||||
createReadStreamCallCount++;
|
||||
return testStream;
|
||||
}
|
||||
};
|
||||
am._getOutputsMempool = sinon.stub().callsArgWith(2, null, []);
|
||||
am._getOutputsMempool = sinon.stub().callsArgWith(3, null, []);
|
||||
am.getOutputs(address, args, function(err, outputs) {
|
||||
should.not.exist(err);
|
||||
outputs.length.should.equal(1);
|
||||
outputs[0].address.should.equal(address);
|
||||
outputs[0].txid.should.equal('125dd0e50fc732d67c37b6c56be7f9dc00b6859cebf982ee2cc83ed2d604bf87');
|
||||
outputs[0].hashType.should.equal('pubkeyhash');
|
||||
outputs[0].hashType.should.equal(AddressService.HASH_TYPES_READABLE[hashTypeBuffer.toString('hex')]);
|
||||
outputs[0].outputIndex.should.equal(1);
|
||||
outputs[0].satoshis.should.equal(4527773864);
|
||||
outputs[0].script.should.equal('76a914038a213afdfc551fc658e9a2a58a86e98d69b68788ac');
|
||||
@ -1157,7 +1170,7 @@ describe('Address Service', function() {
|
||||
});
|
||||
createReadStreamCallCount.should.equal(1);
|
||||
var data = {
|
||||
key: new Buffer('02038a213afdfc551fc658e9a2a58a86e98d69b687000000000f125dd0e50fc732d67c37b6c56be7f9dc00b6859cebf982ee2cc83ed2d604bf8700000001', 'hex'),
|
||||
key: new Buffer('02038a213afdfc551fc658e9a2a58a86e98d69b68701000000000f125dd0e50fc732d67c37b6c56be7f9dc00b6859cebf982ee2cc83ed2d604bf8700000001', 'hex'),
|
||||
value: new Buffer('41f0de058a80000076a914038a213afdfc551fc658e9a2a58a86e98d69b68788ac', 'hex')
|
||||
};
|
||||
testStream.emit('data', data);
|
||||
@ -1170,10 +1183,11 @@ describe('Address Service', function() {
|
||||
createReadStream: sinon.stub().returns(readStream1)
|
||||
};
|
||||
|
||||
am._getOutputsMempool = sinon.stub().callsArgWith(2, null, [
|
||||
am._getOutputsMempool = sinon.stub().callsArgWith(3, null, [
|
||||
{
|
||||
address: address,
|
||||
height: -1,
|
||||
hashType: 'pubkeyhash',
|
||||
confirmations: 0,
|
||||
txid: 'aa2db23f670596e96ed94c405fd11848c8f236d266ee96da37ecd919e53b4371',
|
||||
satoshis: 307627737,
|
||||
@ -1186,18 +1200,21 @@ describe('Address Service', function() {
|
||||
should.not.exist(err);
|
||||
outputs.length.should.equal(3);
|
||||
outputs[0].address.should.equal(address);
|
||||
outputs[0].hashType.should.equal('pubkeyhash');
|
||||
outputs[0].txid.should.equal('125dd0e50fc732d67c37b6c56be7f9dc00b6859cebf982ee2cc83ed2d604bf87');
|
||||
outputs[0].outputIndex.should.equal(1);
|
||||
outputs[0].satoshis.should.equal(4527773864);
|
||||
outputs[0].script.should.equal('76a914038a213afdfc551fc658e9a2a58a86e98d69b68788ac');
|
||||
outputs[0].height.should.equal(345000);
|
||||
outputs[1].address.should.equal(address);
|
||||
outputs[1].hashType.should.equal('pubkeyhash');
|
||||
outputs[1].txid.should.equal('3b6bc2939d1a70ce04bc4f619ee32608fbff5e565c1f9b02e4eaa97959c59ae7');
|
||||
outputs[1].outputIndex.should.equal(2);
|
||||
outputs[1].satoshis.should.equal(10000);
|
||||
outputs[1].script.should.equal('76a914038a213afdfc551fc658e9a2a58a86e98d69b68788ac');
|
||||
outputs[1].height.should.equal(345004);
|
||||
outputs[2].address.should.equal(address);
|
||||
outputs[2].hashType.should.equal('pubkeyhash');
|
||||
outputs[2].txid.should.equal('aa2db23f670596e96ed94c405fd11848c8f236d266ee96da37ecd919e53b4371');
|
||||
outputs[2].script.should.equal('76a914f6db95c81dea3d10f0ff8d890927751bf7b203c188ac');
|
||||
outputs[2].height.should.equal(-1);
|
||||
@ -1206,12 +1223,12 @@ describe('Address Service', function() {
|
||||
});
|
||||
|
||||
var data1 = {
|
||||
key: new Buffer('02038a213afdfc551fc658e9a2a58a86e98d69b68700000543a8125dd0e50fc732d67c37b6c56be7f9dc00b6859cebf982ee2cc83ed2d604bf8700000001', 'hex'),
|
||||
key: new Buffer('02038a213afdfc551fc658e9a2a58a86e98d69b6870100000543a8125dd0e50fc732d67c37b6c56be7f9dc00b6859cebf982ee2cc83ed2d604bf8700000001', 'hex'),
|
||||
value: new Buffer('41f0de058a80000076a914038a213afdfc551fc658e9a2a58a86e98d69b68788ac', 'hex')
|
||||
};
|
||||
|
||||
var data2 = {
|
||||
key: new Buffer('02038a213afdfc551fc658e9a2a58a86e98d69b68700000543ac3b6bc2939d1a70ce04bc4f619ee32608fbff5e565c1f9b02e4eaa97959c59ae700000002', 'hex'),
|
||||
key: new Buffer('02038a213afdfc551fc658e9a2a58a86e98d69b6870100000543ac3b6bc2939d1a70ce04bc4f619ee32608fbff5e565c1f9b02e4eaa97959c59ae700000002', 'hex'),
|
||||
value: new Buffer('40c388000000000076a914038a213afdfc551fc658e9a2a58a86e98d69b68788ac', 'hex')
|
||||
};
|
||||
|
||||
@ -1237,12 +1254,98 @@ describe('Address Service', function() {
|
||||
readStream2.emit('close');
|
||||
});
|
||||
});
|
||||
|
||||
it('should print outputs for a p2sh address', function(done) {
|
||||
// This address has the redeemScript 0x038a213afdfc551fc658e9a2a58a86e98d69b687,
|
||||
// which is the same as the pkhash for the address 1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W.
|
||||
// See https://github.com/bitpay/bitcore-node/issues/377
|
||||
var address = '321jRYeWBrLBWr2j1KYnAFGico3GUdd5q7';
|
||||
var hashBuffer = bitcore.Address(address).hashBuffer;
|
||||
var hashTypeBuffer = AddressService.HASH_TYPES.REDEEMSCRIPT;
|
||||
var testStream = new EventEmitter();
|
||||
var args = {
|
||||
start: 15,
|
||||
end: 12,
|
||||
queryMempool: true
|
||||
};
|
||||
var createReadStreamCallCount = 0;
|
||||
am.node.services.db.store = {
|
||||
createReadStream: function(ops) {
|
||||
var gte = Buffer.concat([AddressService.PREFIXES.OUTPUTS, hashBuffer, hashTypeBuffer, new Buffer('000000000c', 'hex')]);
|
||||
ops.gte.toString('hex').should.equal(gte.toString('hex'));
|
||||
var lte = Buffer.concat([AddressService.PREFIXES.OUTPUTS, hashBuffer, hashTypeBuffer, new Buffer('0000000010', 'hex')]);
|
||||
ops.lte.toString('hex').should.equal(lte.toString('hex'));
|
||||
createReadStreamCallCount++;
|
||||
return testStream;
|
||||
}
|
||||
};
|
||||
am._getOutputsMempool = sinon.stub().callsArgWith(3, null, []);
|
||||
am.getOutputs(address, args, function(err, outputs) {
|
||||
should.not.exist(err);
|
||||
outputs.length.should.equal(1);
|
||||
outputs[0].address.should.equal(address);
|
||||
outputs[0].txid.should.equal('125dd0e50fc732d67c37b6c56be7f9dc00b6859cebf982ee2cc83ed2d604bf87');
|
||||
outputs[0].hashType.should.equal('scripthash');
|
||||
outputs[0].hashType.should.equal(AddressService.HASH_TYPES_READABLE[hashTypeBuffer.toString('hex')]);
|
||||
outputs[0].outputIndex.should.equal(1);
|
||||
outputs[0].satoshis.should.equal(4527773864);
|
||||
outputs[0].script.should.equal('a914038a213afdfc551fc658e9a2a58a86e98d69b68787');
|
||||
outputs[0].height.should.equal(15);
|
||||
done();
|
||||
});
|
||||
createReadStreamCallCount.should.equal(1);
|
||||
var data = {
|
||||
// note '68702', '02' meaning p2sh redeemScript, not p2pkh
|
||||
// value is also the p2sh script, not p2pkh
|
||||
key: new Buffer('02038a213afdfc551fc658e9a2a58a86e98d69b68702000000000f125dd0e50fc732d67c37b6c56be7f9dc00b6859cebf982ee2cc83ed2d604bf8700000001', 'hex'),
|
||||
value: new Buffer('41f0de058a800000a914038a213afdfc551fc658e9a2a58a86e98d69b68787', 'hex')
|
||||
};
|
||||
testStream.emit('data', data);
|
||||
testStream.emit('close');
|
||||
});
|
||||
|
||||
it('should not print outputs for a p2pkh address, if the output was sent to a p2sh redeemScript', function(done) {
|
||||
// This address has the redeemScript 0x038a213afdfc551fc658e9a2a58a86e98d69b687,
|
||||
// which is the same as the pkhash for the address 1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W.
|
||||
// See https://github.com/bitpay/bitcore-node/issues/377
|
||||
var address = '321jRYeWBrLBWr2j1KYnAFGico3GUdd5q7';
|
||||
var hashBuffer = bitcore.Address(address).hashBuffer;
|
||||
var hashTypeBuffer = AddressService.HASH_TYPES.REDEEMSCRIPT;
|
||||
var testStream = new EventEmitter();
|
||||
var args = {
|
||||
start: 15,
|
||||
end: 12,
|
||||
queryMempool: true
|
||||
};
|
||||
var createReadStreamCallCount = 0;
|
||||
|
||||
// Verifying that the db query is looking for a redeemScript, *not* a p2pkh
|
||||
am.node.services.db.store = {
|
||||
createReadStream: function(ops) {
|
||||
var gte = Buffer.concat([AddressService.PREFIXES.OUTPUTS, hashBuffer, hashTypeBuffer, new Buffer('000000000c', 'hex')]);
|
||||
ops.gte.toString('hex').should.equal(gte.toString('hex'));
|
||||
var lte = Buffer.concat([AddressService.PREFIXES.OUTPUTS, hashBuffer, hashTypeBuffer, new Buffer('0000000010', 'hex')]);
|
||||
ops.lte.toString('hex').should.equal(lte.toString('hex'));
|
||||
createReadStreamCallCount++;
|
||||
return testStream;
|
||||
}
|
||||
};
|
||||
am._getOutputsMempool = sinon.stub().callsArgWith(3, null, []);
|
||||
am.getOutputs(address, args, function(err, outputs) {
|
||||
should.not.exist(err);
|
||||
outputs.length.should.equal(0);
|
||||
done();
|
||||
});
|
||||
createReadStreamCallCount.should.equal(1);
|
||||
testStream.emit('close');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#_getOutputsMempool', function() {
|
||||
var am;
|
||||
var address = '1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W';
|
||||
var hashBuffer = bitcore.Address(address).hashBuffer;
|
||||
var hashTypeBuffer = AddressService.HASH_TYPES.PUBKEY;
|
||||
var db = {
|
||||
tip: {
|
||||
__height: 1
|
||||
@ -1268,7 +1371,7 @@ describe('Address Service', function() {
|
||||
var testStream = new EventEmitter();
|
||||
am.mempoolIndex = {};
|
||||
am.mempoolIndex.createReadStream = sinon.stub().returns(testStream);
|
||||
am._getOutputsMempool(address, hashBuffer, function(err, outputs) {
|
||||
am._getOutputsMempool(address, hashBuffer, hashTypeBuffer, function(err, outputs) {
|
||||
should.exist(err);
|
||||
err.message.should.equal('readstreamerror');
|
||||
done();
|
||||
@ -1283,12 +1386,13 @@ describe('Address Service', function() {
|
||||
am.mempoolIndex = {};
|
||||
am.mempoolIndex.createReadStream = sinon.stub().returns(testStream);
|
||||
|
||||
am._getOutputsMempool(address, hashBuffer, function(err, outputs) {
|
||||
am._getOutputsMempool(address, hashBuffer, hashTypeBuffer, function(err, outputs) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
outputs.length.should.equal(1);
|
||||
outputs[0].address.should.equal(address);
|
||||
outputs[0].hashType.should.equal('pubkeyhash');
|
||||
outputs[0].txid.should.equal(txid);
|
||||
outputs[0].outputIndex.should.equal(outputIndex);
|
||||
outputs[0].height.should.equal(-1);
|
||||
@ -1304,8 +1408,9 @@ describe('Address Service', function() {
|
||||
var outputIndexBuffer = new Buffer(4);
|
||||
outputIndexBuffer.writeUInt32BE(outputIndex);
|
||||
var keyData = Buffer.concat([
|
||||
new Buffer('01', 'hex'),
|
||||
AddressService.MEMPREFIXES.OUTPUTS,
|
||||
hashBuffer,
|
||||
hashTypeBuffer,
|
||||
txidBuffer,
|
||||
outputIndexBuffer
|
||||
]);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user