Added Utxo index block handler.

This commit is contained in:
Chris Kleeschulte 2017-01-31 13:30:48 -05:00
parent 3b76463112
commit e2229a6516
2 changed files with 126 additions and 23 deletions

View File

@ -2,14 +2,8 @@
var bitcore = require('bitcore-lib');
var BufferReader = bitcore.encoding.BufferReader;
var Address = bitcore.Address;
var PublicKey = bitcore.PublicKey;
var constants = require('./constants');
var $ = bitcore.util.preconditions;
var utils = require('./utils');
var exports = {};
function Encoding(servicePrefix) {
this.servicePrefix = servicePrefix;
}
@ -21,12 +15,6 @@ Encoding.prototype.getTerminalKey = function(startKey) {
};
Encoding.prototype.encodeAddressIndexKey = function(address, height, txid) {
var args = Array.prototype.slice.call(arguments);
if (!utils.hasRequiredArgsForEncoding(args)) {
return null;
}
var prefix = new Buffer('00', 'hex');
var buffers = [this.servicePrefix, prefix];
@ -53,7 +41,7 @@ Encoding.prototype.encodeAddressIndexKey = function(address, height, txid) {
Encoding.prototype.decodeAddressIndexKey = function(buffer) {
var reader = new BufferReader(buffer);
var prefix = reader.read(3);
reader.read(3);
var addressSize = reader.readUInt8();
var address = reader.read(addressSize).toString('utf8');
@ -67,6 +55,7 @@ Encoding.prototype.decodeAddressIndexKey = function(buffer) {
};
Encoding.prototype.encodeUtxoIndexKey = function(address, txid, outputIndex) {
console.log('encodeUtxoIndexKey');
var prefix = new Buffer('01', 'hex');
var buffers = [this.servicePrefix, prefix];
@ -93,7 +82,7 @@ Encoding.prototype.encodeUtxoIndexKey = function(address, txid, outputIndex) {
Encoding.prototype.decodeUtxoIndexKey = function(buffer) {
var reader = new BufferReader(buffer);
var prefix = reader.read(3);
reader.read(3);
var addressSize = reader.readUInt8();
var address = reader.read(addressSize).toString('utf8');
@ -230,7 +219,7 @@ Encoding.prototype.encodeWalletTransactionKey = function(walletId, height, block
Encoding.prototype.decodeWalletTransactionKey = function(buffer) {
var reader = new BufferReader(buffer);
var prefix = reader.read(1);
reader.read(1);
var walletSize = reader.readUInt8();
var walletId = reader.read(walletSize).toString('utf8');
@ -278,10 +267,10 @@ Encoding.prototype.encodeWalletUtxoKey = function(walletId, txid, outputIndex) {
Encoding.prototype.decodeWalletUtxoKey = function(buffer) {
var reader = new BufferReader(buffer);
var prefix = reader.read(1);
reader.read(1);
var walletIdSizeBuffer = reader.readUInt8();
var walletIdBuffer = reader.read(walletIdSizeBuffer).toString('utf8');
var walletIdSize = reader.readUInt8();
var walletId = reader.read(walletIdSize).toString('utf8');
var txid = reader.read(32).toString('hex');
var outputIndex = reader.readUInt32BE();
return {
@ -347,16 +336,16 @@ Encoding.prototype.encodeWalletUtxoSatoshisKey = function(walletId, satoshis, tx
Encoding.prototype.decodeWalletUtxoSatoshisKey = function(buffer) {
var reader = new BufferReader(buffer);
var prefix = reader.read(1);
reader.read(1);
var walletIdSizeBuffer = reader.readUInt8();
var walletIdBuffer = reader.read(walletIdSizeBuffer).toString('utf8');
var walletId = reader.read(walletIdSizeBuffer).toString('utf8');
var satoshis = reader.readDoubleBE();
var txid = reader.read(32).toString('hex');
var outputIndex = reader.readUInt32BE();
return {
walletId: walletId,
sathosis: sathosis,
satoshis: satoshis,
txid: txid,
outputIndex: outputIndex
};
@ -408,6 +397,21 @@ Encoding.prototype.encodeWalletValue = function(addresses, balance) {
};
Encoding.prototype.decodeWalletValue = function(buffer) {
var reader = new BufferReader(buffer);
var addressesLength = reader.readUInt32BE();
var addresses = [];
var addressSize = 0;
for(var i = 0; i < addressesLength.length; i++) {
addressSize = reader.readUInt8(addressSize);
addresses.push(reader.read(addressSize).toString('utf8'));
}
var balance = reader.readDoubleBE();
return {
addresses: addresses,
balance: balance
};
};
module.exports = Encoding;

View File

@ -230,6 +230,105 @@ AddressService.prototype.concurrentBlockHandler = function(block, connectBlock,
});
};
AddressService.prototype.blockHandler = function(block, connectBlock, callback) {
var self = this;
var txs = block.transactions;
var height = block.__height;
var action = 'put';
var reverseAction = 'del';
if (!connectBlock) {
action = 'del';
reverseAction = 'put';
}
var operations = [];
async.eachSeries(txs, function(tx, next) {
var txid = tx.id;
var inputs = tx.inputs;
var outputs = tx.outputs;
// Subscription messages
var txmessages = {};
var outputLength = outputs.length;
for (var outputIndex = 0; outputIndex < outputLength; outputIndex++) {
var output = outputs[outputIndex];
var script = output.script;
if(!script) {
log.debug('Invalid script');
return next();
}
var address = self._getAddressString(script);
if(!address) {
return next();
}
var key = self.encoding.encodeUtxoIndexKey(address, txid, outputIndex);
var value = self.encoding.encodeUtxoIndexValue(output.satoshis, output.script);
operations.push({
type: action,
key: key,
value: value
});
}
if(tx.isCoinbase()) {
return next();
}
//TODO deal with P2PK
async.each(inputs, function(input, next) {
if(!input.script) {
log.debug('Invalid script');
return next();
}
var inputAddress = self._getAddressString(input.script);
if(!inputAddress) {
return next();
}
var inputKey = self.encoding.encodeUtxoIndexKey(inputAddress, input.prevTxId, input.outputIndex);
//common case is connecting blocks and deleting outputs spent by these inputs
if (connectBlock) {
operations.push({
type: 'del',
key: inputKey
});
} else { // uncommon and slower, this happens during a reorg
self.node.services.transaction.getTransaction(input.prevTxId, {}, function(err, tx) {
var utxo = tx.outputs[input.outputIndex];
var inputValue = self.encoding.encodeUtxoIndexValue(utxo.satoshis, utxo.script);
operations.push({
type: 'put',
key: inputKey,
value: inputValue
});
});
}
}, function(err) {
if(err) {
return next(err);
}
next();
});
}, function(err) {
//we are aync predicated on reorg sitch
setImmediate(function() {
callback(null, operations);
});
});
};
AddressService.prototype._getAddressString = function(script, output) {
var address = script.toAddress();
if(address) {
@ -242,7 +341,7 @@ AddressService.prototype._getAddressString = function(script, output) {
return pubkey.toString('hex');
}
} catch(e) {
log.warn('Error getting public key from: ', script.toASM(), script.toHex());
//log.warn('Error getting public key from: ', script.toASM(), script.toHex());
// if there is an error, it's because a pubkey can not be extracted from the script
// continue on and return null
}
@ -252,7 +351,7 @@ AddressService.prototype._getAddressString = function(script, output) {
return output.script.getPublicKey().toString('hex');
}
log.warn('No utxo given for script spending a P2PK: ', script.toASM(), script.toHex());
//log.warn('No utxo given for script spending a P2PK: ', script.toASM(), script.toHex());
return null;
};