Add heightConfirmed for outputs

This commit is contained in:
eordano 2015-03-19 15:13:23 -03:00
parent 492a325c18
commit 599d1166cf
3 changed files with 45 additions and 29 deletions

View File

@ -44,6 +44,16 @@ AddressService.prototype.getSummary = function(address, confirmations) {
}); });
}; };
AddressService.processOutput = function(data) {
var elements = data.key.split('-');
var output = _.extend(JSON.parse(data.value), {
address: elements[1],
txId: elements[2],
outputIndex: elements[3]
});
return output;
};
AddressService.prototype.getAllOutputs = function(address) { AddressService.prototype.getAllOutputs = function(address) {
var results = []; var results = [];
var self = this; var self = this;
@ -53,7 +63,7 @@ AddressService.prototype.getAllOutputs = function(address) {
gte: TransactionService.Index.getOutputsForAddress(address, NULLTXHASH, 0), gte: TransactionService.Index.getOutputsForAddress(address, NULLTXHASH, 0),
lte: TransactionService.Index.getOutputsForAddress(address, LASTTXHASH, MAXOUTPUT) lte: TransactionService.Index.getOutputsForAddress(address, LASTTXHASH, MAXOUTPUT)
}).on('data', function(element) { }).on('data', function(element) {
results.push(element.value); results.push(AddressService.processOutput(element));
}).on('close', function() { }).on('close', function() {
reject(); reject();
}).on('end', function() { }).on('end', function() {
@ -71,7 +81,7 @@ AddressService.prototype.getSpent = function(address) {
gte: TransactionService.Index.getSpentOutputsForAddress(address, NULLTXHASH, 0), gte: TransactionService.Index.getSpentOutputsForAddress(address, NULLTXHASH, 0),
lte: TransactionService.Index.getSpentOutputsForAddress(address, LASTTXHASH, MAXOUTPUT) lte: TransactionService.Index.getSpentOutputsForAddress(address, LASTTXHASH, MAXOUTPUT)
}).on('data', function(element) { }).on('data', function(element) {
results.push(element.value); results.push(JSON.parse(element.value));
}).on('error', function(err) { }).on('error', function(err) {
return reject(err); return reject(err);
}).on('end', function() { }).on('end', function() {
@ -98,8 +108,12 @@ AddressService.prototype.buildAddressSummary = function(address, tip, allOutputs
sent: 0, sent: 0,
received: 0 received: 0
}; };
var outputValues = {};
_.each(allOutputs, function(output) { _.each(allOutputs, function(output) {
var value = output.satoshis; var value = output.satoshis;
outputValues[output.txId + '-' + output.outputIndex] = value;
result.unconfirmed.balance += value; result.unconfirmed.balance += value;
result.unconfirmed.received += value; result.unconfirmed.received += value;
if (tip.height - output.heightConfirmed - 1 >= confirmations) { if (tip.height - output.heightConfirmed - 1 >= confirmations) {
@ -108,7 +122,8 @@ AddressService.prototype.buildAddressSummary = function(address, tip, allOutputs
} }
}); });
_.each(spent, function(output) { _.each(spent, function(output) {
var value = output.satoshis; var value = outputValues[output.spendInput.prevTxId + '-' + output.spendInput.outputIndex];
if (!transactionsAppended[output.spentTx]) { if (!transactionsAppended[output.spentTx]) {
transactionsAppended[output.spentTx] = true; transactionsAppended[output.spentTx] = true;
result.transactions.push(output.spentTx); result.transactions.push(output.spentTx);

View File

@ -97,7 +97,7 @@ BlockService.blockRPCtoBitcore = function(blockData, transactions) {
$.checkArgument(_.all(transactions, function(transaction) { $.checkArgument(_.all(transactions, function(transaction) {
return transaction instanceof bitcore.Transaction; return transaction instanceof bitcore.Transaction;
}), 'All transactions must be instances of bitcore.Transaction'); }), 'All transactions must be instances of bitcore.Transaction');
return new bitcore.Block({ var block = new bitcore.Block({
header: new bitcore.BlockHeader({ header: new bitcore.BlockHeader({
version: blockData.version, version: blockData.version,
prevHash: blockData.previousblockhash ? prevHash: blockData.previousblockhash ?
@ -115,6 +115,8 @@ BlockService.blockRPCtoBitcore = function(blockData, transactions) {
}), }),
transactions: transactions transactions: transactions
}); });
block.height = blockData.height;
return block;
}; };
/** /**

View File

@ -110,7 +110,7 @@ TransactionService.prototype._confirmOutput = function(ops, block, transaction)
ops.push({ ops.push({
type: 'put', type: 'put',
key: Index.getOutput(transaction.id, index), key: Index.getOutput(transaction.id, index),
value: output.toObject() value: output.toJSON()
}); });
var address; var address;
// TODO: Move this logic to bitcore // TODO: Move this logic to bitcore
@ -124,7 +124,9 @@ TransactionService.prototype._confirmOutput = function(ops, block, transaction)
ops.push({ ops.push({
type: 'put', type: 'put',
key: Index.getOutputsForAddress(address, transaction.id, index), key: Index.getOutputsForAddress(address, transaction.id, index),
value: output.toObject() value: JSON.stringify(_.extend(output.toObject(), {
heightConfirmed: block.height
}))
}); });
} }
}; };
@ -139,13 +141,13 @@ TransactionService.prototype._confirmInput = function(ops, block, transaction) {
ops.push({ ops.push({
type: 'put', type: 'put',
key: Index.getOutput(transaction.id, index), key: Index.getOutput(transaction.id, index),
value: _.extend(input.toObject(), { value: JSON.stringify(_.extend(input.toObject(), {
heightConfirmed: block.height heightConfirmed: block.height
}) }))
}); });
var script = input.script; var script = input.script;
if (!(script.isPublicKeyHashIn() || script.isPublicKeyIn() || script.isScriptHashIn())) { if (!(script.isPublicKeyHashIn() || script.isPublicKeyIn() || script.isScriptHashIn())) {
return Promise.resolve(); return;
} }
return self._getAddressForInput(input).then(function(address) { return self._getAddressForInput(input).then(function(address) {
@ -153,12 +155,12 @@ TransactionService.prototype._confirmInput = function(ops, block, transaction) {
ops.push({ ops.push({
type: 'put', type: 'put',
key: Index.getSpentOutputsForAddress(address, transaction.id, index), key: Index.getSpentOutputsForAddress(address, transaction.id, index),
value: { value: JSON.stringify({
heightSpent: block.height, heightSpent: block.height,
spentTx: transaction.id, spentTx: transaction.id,
spentTxInputIndex: index, spentTxInputIndex: index,
spendInput: input.toObject() spendInput: input.toObject()
} })
}); });
} }
}); });
@ -171,40 +173,37 @@ TransactionService.prototype._getAddressForInput = function(input) {
if (script.isPublicKeyHashIn()) { if (script.isPublicKeyHashIn()) {
var hash = bitcore.crypto.Hash.sha256ripemd160(script.chunks[0].buf); var hash = bitcore.crypto.Hash.sha256ripemd160(script.chunks[0].buf);
return Promise.resolve(new bitcore.Address( return new bitcore.Address(
hash, bitcore.Networks.defaultNetwork, bitcore.Address.PayToPublicKeyHash hash, bitcore.Networks.defaultNetwork, bitcore.Address.PayToPublicKeyHash
)); );
} else if (script.isPublicKeyIn()) { } else if (script.isPublicKeyIn()) {
return self.getTransaction(input.prevTxId.toString('hex')).then(function(transaction) { return self.getTransaction(input.prevTxId.toString('hex')).then(function(transaction) {
var outputScript = transaction.outputs[input.outputIndex].script; var outputScript = transaction.outputs[input.outputIndex].script;
if (outputScript.isPublicKeyOut()) { if (outputScript.isPublicKeyOut()) {
return Promise.resolve(new bitcore.Address( return new bitcore.Address(
bitcore.crypto.Hash.sha256ripemd160(outputScript.chunks[0].buf), bitcore.crypto.Hash.sha256ripemd160(outputScript.chunks[0].buf),
bitcore.Networks.defaultNetwork, bitcore.Address.PayToPublicKeyHash bitcore.Networks.defaultNetwork, bitcore.Address.PayToPublicKeyHash
)); );
} else {
return Promise.resolve(undefined);
} }
return;
}); });
} else { } else {
return Promise.resolve(new bitcore.Script(script.chunks[script.chunks.length - 1]).toAddress()); return new bitcore.Script(script.chunks[script.chunks.length - 1]).toAddress();
} }
}; };
TransactionService.prototype._confirmTransaction = function(ops, block, transaction) { TransactionService.prototype._confirmTransaction = function(ops, block, transaction) {
var self = this; var self = this;
return Promise.try(function() { ops.push({
ops.push({ type: 'put',
type: 'put', key: Index.getBlockForTransaction(transaction),
key: Index.getBlockForTransaction(transaction), value: block.id
value: block.id
});
return Promise.all(
_.each(transaction.outputs, self._confirmOutput(ops, block, transaction))
.concat(
_.each(transaction.inputs, self._confirmInput(ops, block, transaction))
));
}); });
return Promise.all(
_.map(transaction.outputs, self._confirmOutput(ops, block, transaction))
.concat(
_.map(transaction.inputs, self._confirmInput(ops, block, transaction))
));
}; };
module.exports = TransactionService; module.exports = TransactionService;