Unified all encodings/serialization functions into one,
centrally-accessible encodings file.
This commit is contained in:
parent
0627a14f18
commit
3b76463112
413
lib/encoding.js
Normal file
413
lib/encoding.js
Normal file
@ -0,0 +1,413 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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, 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];
|
||||||
|
|
||||||
|
var addressSizeBuffer = new Buffer(1);
|
||||||
|
addressSizeBuffer.writeUInt8(address.length);
|
||||||
|
var addressBuffer = new Buffer(address, 'utf8');
|
||||||
|
|
||||||
|
buffers.push(addressSizeBuffer);
|
||||||
|
buffers.push(addressBuffer);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Buffer.concat(buffers);
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.decodeAddressIndexKey = function(buffer) {
|
||||||
|
var reader = new BufferReader(buffer);
|
||||||
|
var prefix = reader.read(3);
|
||||||
|
|
||||||
|
var addressSize = reader.readUInt8();
|
||||||
|
var address = reader.read(addressSize).toString('utf8');
|
||||||
|
var height = reader.readUInt32BE();
|
||||||
|
var txid = reader.read(32).toString('hex');
|
||||||
|
return {
|
||||||
|
address: address,
|
||||||
|
height: height,
|
||||||
|
txid: txid,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.encodeUtxoIndexKey = function(address, txid, outputIndex) {
|
||||||
|
var prefix = new Buffer('01', 'hex');
|
||||||
|
var buffers = [this.servicePrefix, prefix];
|
||||||
|
|
||||||
|
var addressSizeBuffer = new Buffer(1);
|
||||||
|
addressSizeBuffer.writeUInt8(address.length);
|
||||||
|
var addressBuffer = new Buffer(address, 'utf8');
|
||||||
|
|
||||||
|
buffers.push(addressSizeBuffer);
|
||||||
|
buffers.push(addressBuffer);
|
||||||
|
|
||||||
|
if(txid) {
|
||||||
|
var txidBuffer = new Buffer(txid, 'hex');
|
||||||
|
buffers.push(txidBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(outputIndex !== undefined) {
|
||||||
|
var outputIndexBuffer = new Buffer(4);
|
||||||
|
outputIndexBuffer.writeUInt32BE(outputIndex);
|
||||||
|
buffers.push(outputIndexBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Buffer.concat(buffers);
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.decodeUtxoIndexKey = function(buffer) {
|
||||||
|
var reader = new BufferReader(buffer);
|
||||||
|
var prefix = reader.read(3);
|
||||||
|
|
||||||
|
var addressSize = reader.readUInt8();
|
||||||
|
var address = reader.read(addressSize).toString('utf8');
|
||||||
|
var txid = reader.read(32).toString('hex');
|
||||||
|
var outputIndex = reader.readUInt32BE(4);
|
||||||
|
|
||||||
|
return {
|
||||||
|
address: address,
|
||||||
|
txid: txid,
|
||||||
|
outputIndex: outputIndex
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.encodeUtxoIndexValue = function(satoshis, scriptBuffer) {
|
||||||
|
var satoshisBuffer = new Buffer(8);
|
||||||
|
satoshisBuffer.writeDoubleBE(satoshis);
|
||||||
|
return Buffer.concat([satoshisBuffer, scriptBuffer]);
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.decodeUtxoIndexValue = function(buffer) {
|
||||||
|
var satoshis = buffer.readDoubleBE(0);
|
||||||
|
var scriptBuffer = buffer.slice(8, buffer.length);
|
||||||
|
return {
|
||||||
|
satoshis: satoshis,
|
||||||
|
script: scriptBuffer
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.encodeTransactionKey = function(txid) {
|
||||||
|
return Buffer.concat([this.servicePrefix, new Buffer(txid, 'hex')]);
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.decodeTransactionKey = function(buffer) {
|
||||||
|
return buffer.slice(2).toString('hex');
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.encodeTransactionValue = function(transaction) {
|
||||||
|
var heightBuffer = new Buffer(4);
|
||||||
|
heightBuffer.writeUInt32BE(transaction.__height);
|
||||||
|
|
||||||
|
var timestampBuffer = new Buffer(8);
|
||||||
|
timestampBuffer.writeDoubleBE(transaction.__timestamp);
|
||||||
|
|
||||||
|
var inputValues = transaction.__inputValues;
|
||||||
|
var inputValuesBuffer = new Buffer(8 * inputValues.length);
|
||||||
|
for(var i = 0; i < inputValues.length; i++) {
|
||||||
|
inputValuesBuffer.writeDoubleBE(inputValues[i], i * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
var inputValuesLengthBuffer = new Buffer(2);
|
||||||
|
inputValuesLengthBuffer.writeUInt16BE(inputValues.length * 8);
|
||||||
|
|
||||||
|
return new Buffer.concat([heightBuffer, timestampBuffer,
|
||||||
|
inputValuesLengthBuffer, inputValuesBuffer, transaction.toBuffer()]);
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.decodeTransactionValue = function(buffer) {
|
||||||
|
var height = buffer.readUInt32BE();
|
||||||
|
|
||||||
|
var timestamp = buffer.readDoubleBE(4);
|
||||||
|
|
||||||
|
var inputValues = [];
|
||||||
|
var inputValuesLength = buffer.readUInt16BE(12);
|
||||||
|
for(var i = 0; i < inputValuesLength / 8; i++) {
|
||||||
|
inputValues.push(buffer.readDoubleBE(i * 8 + 14));
|
||||||
|
}
|
||||||
|
var transaction = new bitcore.Transaction(buffer.slice(inputValues.length * 8 + 14));
|
||||||
|
transaction.__height = height;
|
||||||
|
transaction.__inputValues = inputValues;
|
||||||
|
transaction.__timestamp = timestamp;
|
||||||
|
return transaction;
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.encodeBlockTimestampKey = function(hash) {
|
||||||
|
return Buffer.concat([this.servicePrefix, new Buffer(hash, 'hex')]);
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.decodeBlockTimestampKey = function(buffer) {
|
||||||
|
return buffer.slice(2).toString('hex');
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.encodeBlockTimestampValue = function(timestamp) {
|
||||||
|
var timestampBuffer = new Buffer(new Array(8));
|
||||||
|
timestampBuffer.writeDoubleBE(timestamp);
|
||||||
|
return timestampBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.decodeBlockTimestampValue = function(buffer) {
|
||||||
|
return buffer.readDoubleBE(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.encodeTimestampBlockKey = function(timestamp) {
|
||||||
|
var timestampBuffer = new Buffer(new Array(8));
|
||||||
|
timestampBuffer.writeDoubleBE(timestamp);
|
||||||
|
return Buffer.concat([this.servicePrefix, timestampBuffer]);
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.decodeTimestampBlockKey = function(buffer) {
|
||||||
|
return buffer.readDoubleBE(2);
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.encodeTimestampBlockValue = function(hash) {
|
||||||
|
return new Buffer(hash, 'hex');
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.decodeTimestampBlockValue = function(buffer) {
|
||||||
|
return buffer.toString('hex');
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.encodeWalletTransactionKey = function(walletId, height, blockIndex) {
|
||||||
|
var buffers = [this.servicePrefix];
|
||||||
|
|
||||||
|
var walletIdSizeBuffer = new Buffer(1);
|
||||||
|
walletIdSizeBuffer.writeUInt8(walletId.length);
|
||||||
|
var walletIdBuffer = new Buffer(walletId, 'utf8');
|
||||||
|
|
||||||
|
buffers.push(walletIdSizeBuffer);
|
||||||
|
buffers.push(walletIdBuffer);
|
||||||
|
|
||||||
|
if(height !== undefined) {
|
||||||
|
var heightBuffer = new Buffer(4);
|
||||||
|
heightBuffer.writeUInt32BE(height);
|
||||||
|
buffers.push(heightBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(blockIndex !== undefined) {
|
||||||
|
var blockIndexBuffer = new Buffer(4);
|
||||||
|
blockIndexBuffer.writeUInt32BE(blockIndex);
|
||||||
|
buffers.push(blockIndexBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Buffer.concat(buffers);
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.decodeWalletTransactionKey = function(buffer) {
|
||||||
|
var reader = new BufferReader(buffer);
|
||||||
|
var prefix = reader.read(1);
|
||||||
|
|
||||||
|
var walletSize = reader.readUInt8();
|
||||||
|
var walletId = reader.read(walletSize).toString('utf8');
|
||||||
|
var height = reader.readUInt32BE();
|
||||||
|
var blockIndex = reader.readUInt32BE();
|
||||||
|
|
||||||
|
return {
|
||||||
|
walletId: walletId,
|
||||||
|
height: height,
|
||||||
|
blockIndex: blockIndex
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.encodeWalletTransactionValue = function(txid) {
|
||||||
|
return new Buffer(txid, 'hex');
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.decodeWalletTransactionValue = function(buffer) {
|
||||||
|
return buffer.toString('hex');
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.encodeWalletUtxoKey = function(walletId, txid, outputIndex) {
|
||||||
|
var buffers = [this.servicePrefix];
|
||||||
|
|
||||||
|
var walletIdSizeBuffer = new Buffer(1);
|
||||||
|
walletIdSizeBuffer.writeUInt8(walletId.length);
|
||||||
|
var walletIdBuffer = new Buffer(walletId, 'utf8');
|
||||||
|
|
||||||
|
buffers.push(walletIdSizeBuffer);
|
||||||
|
buffers.push(walletIdBuffer);
|
||||||
|
|
||||||
|
if(txid) {
|
||||||
|
var txidBuffer = new Buffer(txid, 'hex');
|
||||||
|
buffers.push(txidBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(outputIndex !== undefined) {
|
||||||
|
var outputIndexBuffer = new Buffer(4);
|
||||||
|
outputIndexBuffer.writeUInt32BE(outputIndex);
|
||||||
|
buffers.push(outputIndexBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Buffer.concat(buffers);
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.decodeWalletUtxoKey = function(buffer) {
|
||||||
|
var reader = new BufferReader(buffer);
|
||||||
|
var prefix = reader.read(1);
|
||||||
|
|
||||||
|
var walletIdSizeBuffer = reader.readUInt8();
|
||||||
|
var walletIdBuffer = reader.read(walletIdSizeBuffer).toString('utf8');
|
||||||
|
var txid = reader.read(32).toString('hex');
|
||||||
|
var outputIndex = reader.readUInt32BE();
|
||||||
|
return {
|
||||||
|
walletId: walletId,
|
||||||
|
txid: txid,
|
||||||
|
outputIndex: outputIndex
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.encodeWalletUtxoValue = function(height, satoshis, address) {
|
||||||
|
var heightBuffer = new Buffer(4);
|
||||||
|
heightBuffer.writeUInt32BE(height);
|
||||||
|
var satoshisBuffer = new Buffer(8);
|
||||||
|
satoshisBuffer.writeDoubleBE(satoshis);
|
||||||
|
var addressSizeBuffer = new Buffer(1);
|
||||||
|
addressSizeBuffer.writeUInt8(address.length);
|
||||||
|
var addressBuffer = new Buffer(address, 'utf8');
|
||||||
|
return Buffer.concat([height, satoshisBuffer, addressBuffer]);
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.decodeWalletUtxoValue = function(buffer) {
|
||||||
|
var reader = new BufferReader(buffer);
|
||||||
|
var height = reader.readUInt32BE();
|
||||||
|
var satoshis = reader.readDoubleBE();
|
||||||
|
var addressSize = reader.readUInt8();
|
||||||
|
var address = reader.read(addressSize).toString('utf8');
|
||||||
|
return {
|
||||||
|
height: height,
|
||||||
|
satoshis: satoshis,
|
||||||
|
address: address
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.encodeWalletUtxoSatoshisKey = function(walletId, satoshis, txid, outputIndex) {
|
||||||
|
var buffers = [this.servicePrefix];
|
||||||
|
|
||||||
|
var walletIdSizeBuffer = new Buffer(1);
|
||||||
|
walletIdSizeBuffer.writeUInt8(walletId.length);
|
||||||
|
var walletIdBuffer = new Buffer(walletId, 'utf8');
|
||||||
|
|
||||||
|
buffers.push(walletIdSizeBuffer);
|
||||||
|
buffers.push(walletIdBuffer);
|
||||||
|
|
||||||
|
if(satoshis !== undefined) {
|
||||||
|
var satoshisBuffer = new Buffer(8);
|
||||||
|
satoshisBuffer.writeUInt32BE(satoshis);
|
||||||
|
buffers.push(satoshisBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(txid) {
|
||||||
|
var txidBuffer = new Buffer(txid, 'hex');
|
||||||
|
buffers.push(txidBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(outputIndex !== undefined) {
|
||||||
|
var outputIndexBuffer = new Buffer(4);
|
||||||
|
outputIndexBuffer.writeUInt32BE(outputIndex);
|
||||||
|
buffers.push(outputIndexBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Buffer.concat(buffers);
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.decodeWalletUtxoSatoshisKey = function(buffer) {
|
||||||
|
var reader = new BufferReader(buffer);
|
||||||
|
var prefix = reader.read(1);
|
||||||
|
|
||||||
|
var walletIdSizeBuffer = reader.readUInt8();
|
||||||
|
var walletIdBuffer = 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,
|
||||||
|
txid: txid,
|
||||||
|
outputIndex: outputIndex
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.encodeWalletUtxoSatoshisValue = function(height, address) {
|
||||||
|
var heightBuffer = new Buffer(4);
|
||||||
|
heightBuffer.writeUInt32BE(height);
|
||||||
|
var addressSizeBuffer = new Buffer(1);
|
||||||
|
addressSizeBuffer.writeUInt8(address.length);
|
||||||
|
var addressBuffer = new Buffer(address, 'utf8');
|
||||||
|
return Buffer.concat([height, addressBuffer]);
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.decodeWalletUtxoSatoshisValue = function(buffer) {
|
||||||
|
var reader = new BufferReader(buffer);
|
||||||
|
var height = reader.readUInt32BE();
|
||||||
|
var addressSize = reader.readUInt8();
|
||||||
|
var address = reader.read(addressSize).toString('utf8');
|
||||||
|
return {
|
||||||
|
height: height,
|
||||||
|
address: address
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.encodeWalletKey = function(walletId) {
|
||||||
|
return new Buffer(walletId, 'hex');
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.decodeWalletKey = function(buffer) {
|
||||||
|
return buffer.toString('hex');
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.encodeWalletValue = function(addresses, balance) {
|
||||||
|
var bufferList = [];
|
||||||
|
var addressesLengthBuffer = new Buffer(4);
|
||||||
|
addressesLengthBuffer.writeUInt32BE(addresses.length);
|
||||||
|
bufferList.push(addressesLengthBuffer);
|
||||||
|
for(var i = 0; i < addresses.length; i++) {
|
||||||
|
var addressSizeBuffer = new Buffer(1);
|
||||||
|
addressSizeBuffer.writeUInt8(addresses[i].length);
|
||||||
|
bufferList.push(addressSizeBuffer);
|
||||||
|
bufferList.push(new Buffer(addresses[i], 'utf8'));
|
||||||
|
}
|
||||||
|
var balanceBuffer = new Buffer(8);
|
||||||
|
balanceBuffer.writeUInt32BE(balance);
|
||||||
|
bufferList.push(balanceBuffer);
|
||||||
|
return Buffer.concat(bufferList);
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoding.prototype.decodeWalletValue = function(buffer) {
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = Encoding;
|
||||||
@ -1,474 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
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('../wallet-api/utils');
|
|
||||||
|
|
||||||
var exports = {};
|
|
||||||
|
|
||||||
function Encoding(servicePrefix) {
|
|
||||||
this.servicePrefix = servicePrefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
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, height, txid) {
|
|
||||||
// TODO if later params are given but not earlier ones, throw an error
|
|
||||||
var args = Array.prototype.slice.call(arguments);
|
|
||||||
//if (!utils.hasRequiredArgsForEncoding(args)) {
|
|
||||||
// return null;
|
|
||||||
//}
|
|
||||||
var prefix = new Buffer('00', 'hex');
|
|
||||||
var buffers = [this.servicePrefix, prefix];
|
|
||||||
|
|
||||||
var addressSizeBuffer = new Buffer(1);
|
|
||||||
addressSizeBuffer.writeUInt8(address.length);
|
|
||||||
var addressBuffer = new Buffer(address, 'utf8');
|
|
||||||
|
|
||||||
buffers.push(addressSizeBuffer);
|
|
||||||
buffers.push(addressBuffer);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Buffer.concat(buffers);
|
|
||||||
};
|
|
||||||
|
|
||||||
Encoding.prototype.decodeAddressIndexKey = function(buffer) {
|
|
||||||
var reader = new BufferReader(buffer);
|
|
||||||
var prefix = reader.read(3);
|
|
||||||
|
|
||||||
var addressSize = reader.readUInt8();
|
|
||||||
var address = reader.read(addressSize).toString('utf8');
|
|
||||||
var height = reader.readUInt32BE();
|
|
||||||
var txid = reader.read(32).toString('hex');
|
|
||||||
return {
|
|
||||||
address: address,
|
|
||||||
height: height,
|
|
||||||
txid: txid,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
Encoding.prototype.encodeUtxoIndexKey = function(address, txid, outputIndex) {
|
|
||||||
var prefix = new Buffer('01', 'hex');
|
|
||||||
var buffers = [this.servicePrefix, prefix];
|
|
||||||
|
|
||||||
var addressSizeBuffer = new Buffer(1);
|
|
||||||
addressSizeBuffer.writeUInt8(address.length);
|
|
||||||
var addressBuffer = new Buffer(address, 'utf8');
|
|
||||||
|
|
||||||
buffers.push(addressSizeBuffer);
|
|
||||||
buffers.push(addressBuffer);
|
|
||||||
|
|
||||||
if(txid) {
|
|
||||||
var txidBuffer = new Buffer(txid, 'hex');
|
|
||||||
buffers.push(txidBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(outputIndex !== undefined) {
|
|
||||||
var outputIndexBuffer = new Buffer(4);
|
|
||||||
outputIndexBuffer.writeUInt32BE(outputIndex);
|
|
||||||
buffers.push(outputIndexBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Buffer.concat(buffers);
|
|
||||||
};
|
|
||||||
|
|
||||||
Encoding.prototype.decodeUtxoIndexKey = function(buffer) {
|
|
||||||
var reader = new BufferReader(buffer);
|
|
||||||
var prefix = reader.read(3);
|
|
||||||
|
|
||||||
var addressSize = reader.readUInt8();
|
|
||||||
var address = reader.read(addressSize).toString('utf8');
|
|
||||||
var txid = reader.read(32).toString('hex');
|
|
||||||
var outputIndex = reader.readUInt32BE(4);
|
|
||||||
|
|
||||||
return {
|
|
||||||
address: address,
|
|
||||||
txid: txid,
|
|
||||||
outputIndex: outputIndex
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
Encoding.prototype.encodeUtxoIndexValue = function(satoshis, scriptBuffer) {
|
|
||||||
var satoshisBuffer = new Buffer(8);
|
|
||||||
satoshisBuffer.writeDoubleBE(satoshis);
|
|
||||||
return Buffer.concat([satoshisBuffer, scriptBuffer]);
|
|
||||||
};
|
|
||||||
|
|
||||||
Encoding.prototype.decodeUtxoIndexValue = function(buffer) {
|
|
||||||
var satoshis = buffer.readDoubleBE(0);
|
|
||||||
var scriptBuffer = buffer.slice(8, buffer.length);
|
|
||||||
return {
|
|
||||||
satoshis: satoshis,
|
|
||||||
script: scriptBuffer
|
|
||||||
};
|
|
||||||
};
|
|
||||||
// exports.encodeUnspentIndexKey = function(hashTypeBuffer, hashBuffer, txid, index) {
|
|
||||||
// var indexBuffer = new Buffer(4);
|
|
||||||
// indexBuffer.writeUInt32BE(index);
|
|
||||||
// var txidBuffer = new Buffer(txid, 'hex');
|
|
||||||
|
|
||||||
// var key = Buffer.concat([
|
|
||||||
// constants.PREFIXES.UNSPENT,
|
|
||||||
// hashTypeBuffer,
|
|
||||||
// hashBuffer,
|
|
||||||
// constants.SPACER_MIN,
|
|
||||||
// txidBuffer,
|
|
||||||
// indexBuffer
|
|
||||||
// ]);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// exports.decodeUnspentIndexKey = function(buffer) {
|
|
||||||
// var reader = new BufferReader(buffer);
|
|
||||||
// var prefix = reader.read(1);
|
|
||||||
// var hashTypeBuffer = reader.read(1);
|
|
||||||
// var hashBuffer = reader.read(20);
|
|
||||||
|
|
||||||
// var spacer = reader.read(1);
|
|
||||||
// var txid = reader.read(32);
|
|
||||||
// var index = reader.readUInt32BE();
|
|
||||||
// return {
|
|
||||||
// prefix: prefix,
|
|
||||||
// hashTypeBuffer: hashTypeBuffer,
|
|
||||||
// hashBuffer: hashBuffer,
|
|
||||||
// txid: txid,
|
|
||||||
// index: outputIndex
|
|
||||||
// };
|
|
||||||
// };
|
|
||||||
|
|
||||||
// exports.encodeUnspentIndexValue = function(satoshis, height, scriptBuffer) {
|
|
||||||
// var satoshisBuffer = new Buffer(8);
|
|
||||||
// satoshisBuffer.writeDoubleBE(satoshis);
|
|
||||||
|
|
||||||
// var heightBuffer = new Buffer(4);
|
|
||||||
// heightBuffer.writeUInt32BE(height);
|
|
||||||
|
|
||||||
// return Buffer.concat([satoshisBuffer, heightBuffer, scriptBuffer]);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// exports.decodeUnspentIndexValue = function(buffer) {
|
|
||||||
// var satoshis = buffer.readDoubleBE(0);
|
|
||||||
// var height = buffer.readUInt32BE(8);
|
|
||||||
// var scriptBuffer = buffer.slice(12, buffer.length);
|
|
||||||
|
|
||||||
// return {
|
|
||||||
// satoshis: satoshis,
|
|
||||||
// height: height,
|
|
||||||
// scriptBuffer: 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.encodeOutputKey = function(hashBuffer, hashTypeBuffer, height, txidBuffer, outputIndex) {
|
|
||||||
// var heightBuffer = new Buffer(4);
|
|
||||||
// heightBuffer.writeUInt32BE(height);
|
|
||||||
// var outputIndexBuffer = new Buffer(4);
|
|
||||||
// outputIndexBuffer.writeUInt32BE(outputIndex);
|
|
||||||
// var key = Buffer.concat([
|
|
||||||
// constants.PREFIXES.OUTPUTS,
|
|
||||||
// hashBuffer,
|
|
||||||
// hashTypeBuffer,
|
|
||||||
// constants.SPACER_MIN,
|
|
||||||
// heightBuffer,
|
|
||||||
// txidBuffer,
|
|
||||||
// outputIndexBuffer
|
|
||||||
// ]);
|
|
||||||
// return key;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// exports.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);
|
|
||||||
// var outputIndex = reader.readUInt32BE();
|
|
||||||
// return {
|
|
||||||
// prefix: prefix,
|
|
||||||
// hashBuffer: hashBuffer,
|
|
||||||
// hashTypeBuffer: hashTypeBuffer,
|
|
||||||
// height: height,
|
|
||||||
// txid: txid,
|
|
||||||
// outputIndex: outputIndex
|
|
||||||
// };
|
|
||||||
// };
|
|
||||||
|
|
||||||
// exports.encodeOutputValue = function(satoshis, scriptBuffer) {
|
|
||||||
// var satoshisBuffer = new Buffer(8);
|
|
||||||
// satoshisBuffer.writeDoubleBE(satoshis);
|
|
||||||
// return Buffer.concat([satoshisBuffer, scriptBuffer]);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// exports.encodeOutputMempoolValue = function(satoshis, timestampBuffer, scriptBuffer) {
|
|
||||||
// var satoshisBuffer = new Buffer(8);
|
|
||||||
// satoshisBuffer.writeDoubleBE(satoshis);
|
|
||||||
// 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);
|
|
||||||
// var scriptBuffer = buffer.slice(16, buffer.length);
|
|
||||||
// return {
|
|
||||||
// satoshis: satoshis,
|
|
||||||
// timestamp: timestamp,
|
|
||||||
// scriptBuffer: scriptBuffer
|
|
||||||
// };
|
|
||||||
// };
|
|
||||||
|
|
||||||
// exports.encodeInputKey = function(hashBuffer, hashTypeBuffer, height, prevTxIdBuffer, outputIndex) {
|
|
||||||
// var heightBuffer = new Buffer(4);
|
|
||||||
// heightBuffer.writeUInt32BE(height);
|
|
||||||
// var outputIndexBuffer = new Buffer(4);
|
|
||||||
// outputIndexBuffer.writeUInt32BE(outputIndex);
|
|
||||||
// return Buffer.concat([
|
|
||||||
// constants.PREFIXES.SPENTS,
|
|
||||||
// hashBuffer,
|
|
||||||
// hashTypeBuffer,
|
|
||||||
// constants.SPACER_MIN,
|
|
||||||
// heightBuffer,
|
|
||||||
// prevTxIdBuffer,
|
|
||||||
// outputIndexBuffer
|
|
||||||
// ]);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// exports.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);
|
|
||||||
// var outputIndex = reader.readUInt32BE();
|
|
||||||
// return {
|
|
||||||
// prefix: prefix,
|
|
||||||
// hashBuffer: hashBuffer,
|
|
||||||
// hashTypeBuffer: hashTypeBuffer,
|
|
||||||
// height: height,
|
|
||||||
// prevTxId: prevTxId,
|
|
||||||
// outputIndex: outputIndex
|
|
||||||
// };
|
|
||||||
// };
|
|
||||||
|
|
||||||
// exports.encodeInputValue = function(txidBuffer, inputIndex) {
|
|
||||||
// var inputIndexBuffer = new Buffer(4);
|
|
||||||
// inputIndexBuffer.writeUInt32BE(inputIndex);
|
|
||||||
// return Buffer.concat([
|
|
||||||
// txidBuffer,
|
|
||||||
// inputIndexBuffer
|
|
||||||
// ]);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// exports.decodeInputValue = function(buffer) {
|
|
||||||
// var txid = buffer.slice(0, 32);
|
|
||||||
// var inputIndex = buffer.readUInt32BE(32);
|
|
||||||
// return {
|
|
||||||
// txid: txid,
|
|
||||||
// inputIndex: inputIndex
|
|
||||||
// };
|
|
||||||
// };
|
|
||||||
|
|
||||||
// exports.encodeInputKeyMap = function(outputTxIdBuffer, outputIndex) {
|
|
||||||
// var outputIndexBuffer = new Buffer(4);
|
|
||||||
// outputIndexBuffer.writeUInt32BE(outputIndex);
|
|
||||||
// return Buffer.concat([
|
|
||||||
// constants.PREFIXES.SPENTSMAP,
|
|
||||||
// outputTxIdBuffer,
|
|
||||||
// outputIndexBuffer
|
|
||||||
// ]);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// exports.decodeInputKeyMap = function(buffer) {
|
|
||||||
// var txid = buffer.slice(1, 33);
|
|
||||||
// var outputIndex = buffer.readUInt32BE(33);
|
|
||||||
// return {
|
|
||||||
// outputTxId: txid,
|
|
||||||
// outputIndex: outputIndex
|
|
||||||
// };
|
|
||||||
// };
|
|
||||||
|
|
||||||
// exports.encodeInputValueMap = function(inputTxIdBuffer, inputIndex) {
|
|
||||||
// var inputIndexBuffer = new Buffer(4);
|
|
||||||
// inputIndexBuffer.writeUInt32BE(inputIndex);
|
|
||||||
// return Buffer.concat([
|
|
||||||
// inputTxIdBuffer,
|
|
||||||
// inputIndexBuffer
|
|
||||||
// ]);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// exports.decodeInputValueMap = function(buffer) {
|
|
||||||
// var txid = buffer.slice(0, 32);
|
|
||||||
// var inputIndex = buffer.readUInt32BE(32);
|
|
||||||
// return {
|
|
||||||
// inputTxId: txid,
|
|
||||||
// inputIndex: inputIndex
|
|
||||||
// };
|
|
||||||
// };
|
|
||||||
|
|
||||||
// exports.encodeSummaryCacheKey = function(address) {
|
|
||||||
// return Buffer.concat([address.hashBuffer, constants.HASH_TYPES_MAP[address.type]]);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// exports.decodeSummaryCacheKey = function(buffer, network) {
|
|
||||||
// var hashBuffer = buffer.read(20);
|
|
||||||
// var type = constants.HASH_TYPES_READABLE[buffer.read(20, 2).toString('hex')];
|
|
||||||
// var address = new Address({
|
|
||||||
// hashBuffer: hashBuffer,
|
|
||||||
// type: type,
|
|
||||||
// network: network
|
|
||||||
// });
|
|
||||||
// return address;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// exports.encodeSummaryCacheValue = function(cache, tipHeight, tipHash) {
|
|
||||||
// var tipHashBuffer = new Buffer(tipHash, 'hex');
|
|
||||||
// var buffer = new Buffer(new Array(20));
|
|
||||||
// buffer.writeUInt32BE(tipHeight);
|
|
||||||
// buffer.writeDoubleBE(cache.result.totalReceived, 4);
|
|
||||||
// buffer.writeDoubleBE(cache.result.balance, 12);
|
|
||||||
// var txidBuffers = [];
|
|
||||||
// for (var i = 0; i < cache.result.txids.length; i++) {
|
|
||||||
// var buf = new Buffer(new Array(36));
|
|
||||||
// var txid = cache.result.txids[i];
|
|
||||||
// buf.write(txid, 'hex');
|
|
||||||
// buf.writeUInt32BE(cache.result.appearanceIds[txid], 32);
|
|
||||||
// txidBuffers.push(buf);
|
|
||||||
// }
|
|
||||||
// var txidsBuffer = Buffer.concat(txidBuffers);
|
|
||||||
// var value = Buffer.concat([tipHashBuffer, buffer, txidsBuffer]);
|
|
||||||
|
|
||||||
// return value;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// exports.decodeSummaryCacheValue = function(buffer) {
|
|
||||||
|
|
||||||
// var hash = buffer.slice(0, 32).toString('hex');
|
|
||||||
// var height = buffer.readUInt32BE(32);
|
|
||||||
// var totalReceived = buffer.readDoubleBE(36);
|
|
||||||
// var balance = buffer.readDoubleBE(44);
|
|
||||||
|
|
||||||
// // read 32 byte chunks until exhausted
|
|
||||||
// var appearanceIds = {};
|
|
||||||
// var txids = [];
|
|
||||||
// var pos = 52;
|
|
||||||
// while(pos < buffer.length) {
|
|
||||||
// var txid = buffer.slice(pos, pos + 32).toString('hex');
|
|
||||||
// var txidHeight = buffer.readUInt32BE(pos + 32);
|
|
||||||
// txids.push(txid);
|
|
||||||
// appearanceIds[txid] = txidHeight;
|
|
||||||
// pos += 36;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var cache = {
|
|
||||||
// height: height,
|
|
||||||
// hash: hash,
|
|
||||||
// result: {
|
|
||||||
// appearanceIds: appearanceIds,
|
|
||||||
// txids: txids,
|
|
||||||
// totalReceived: totalReceived,
|
|
||||||
// balance: balance,
|
|
||||||
// unconfirmedAppearanceIds: {}, // unconfirmed values are never stored in cache
|
|
||||||
// unconfirmedBalance: 0
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// return cache;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// 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 = Encoding;
|
|
||||||
@ -4,7 +4,7 @@ var bitcore = require('bitcore-lib');
|
|||||||
var async = require('async');
|
var async = require('async');
|
||||||
var _ = bitcore.deps._;
|
var _ = bitcore.deps._;
|
||||||
|
|
||||||
var constants = require('./constants');
|
var constants = require('../../constants');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This represents an instance that keeps track of data over a series of
|
* This represents an instance that keeps track of data over a series of
|
||||||
|
|||||||
@ -19,8 +19,8 @@ var Hash = bitcore.crypto.Hash;
|
|||||||
var EventEmitter = require('events').EventEmitter;
|
var EventEmitter = require('events').EventEmitter;
|
||||||
var Address = bitcore.Address;
|
var Address = bitcore.Address;
|
||||||
var AddressHistory = require('./history');
|
var AddressHistory = require('./history');
|
||||||
var constants = require('./constants');
|
var constants = require('../../constants');
|
||||||
var Encoding = require('./encoding');
|
var Encoding = require('../../encoding');
|
||||||
var InputsTransformStream = require('./streams/inputs-transform');
|
var InputsTransformStream = require('./streams/inputs-transform');
|
||||||
var OutputsTransformStream = require('./streams/outputs-transform');
|
var OutputsTransformStream = require('./streams/outputs-transform');
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
var Transform = require('stream').Transform;
|
var Transform = require('stream').Transform;
|
||||||
var inherits = require('util').inherits;
|
var inherits = require('util').inherits;
|
||||||
var bitcore = require('bitcore-lib');
|
var bitcore = require('bitcore-lib');
|
||||||
var encodingUtil = require('../encoding');
|
var encodingUtil = require('../../../encoding');
|
||||||
var $ = bitcore.util.preconditions;
|
var $ = bitcore.util.preconditions;
|
||||||
|
|
||||||
function InputsTransformStream(options) {
|
function InputsTransformStream(options) {
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
var Transform = require('stream').Transform;
|
var Transform = require('stream').Transform;
|
||||||
var inherits = require('util').inherits;
|
var inherits = require('util').inherits;
|
||||||
var bitcore = require('bitcore-lib');
|
var bitcore = require('bitcore-lib');
|
||||||
var encodingUtil = require('../encoding');
|
var encodingUtil = require('../../../encoding');
|
||||||
var $ = bitcore.util.preconditions;
|
var $ = bitcore.util.preconditions;
|
||||||
|
|
||||||
function OutputsTransformStream(options) {
|
function OutputsTransformStream(options) {
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
var Encoding = require('../encoding');
|
||||||
var BaseService = require('../service');
|
var BaseService = require('../service');
|
||||||
var inherits = require('util').inherits;
|
var inherits = require('util').inherits;
|
||||||
|
|
||||||
@ -25,7 +26,7 @@ TimestampService.prototype.start = function(callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.prefix = prefix;
|
self.prefix = prefix;
|
||||||
|
self.encoding = new Encoding(self.prefix);
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -73,13 +74,13 @@ TimestampService.prototype.blockHandler = function(block, connectBlock, callback
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
type: action,
|
type: action,
|
||||||
key: self._encodeTimestampBlockKey(timestamp),
|
key: self.encoding.encodeTimestampBlockKey(timestamp),
|
||||||
value: self._encodeTimestampBlockValue(block.header.hash)
|
value: self.encoding.encodeTimestampBlockValue(block.header.hash)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: action,
|
type: action,
|
||||||
key: self._encodeBlockTimestampKey(block.header.hash),
|
key: self.encoding.encodeBlockTimestampKey(block.header.hash),
|
||||||
value: self._encodeBlockTimestampValue(timestamp)
|
value: self.encoding.encodeBlockTimestampValue(timestamp)
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
@ -97,50 +98,14 @@ TimestampService.prototype.getTimestamp = function(hash, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var key = self._encodeBlockTimestampKey(hash);
|
var key = self.encoding.encodeBlockTimestampKey(hash);
|
||||||
self.store.get(key, function(err, buffer) {
|
self.store.get(key, function(err, buffer) {
|
||||||
if(err) {
|
if(err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
return callback(null, self._decodeBlockTimestampValue(buffer));
|
return callback(null, self.encoding.decodeBlockTimestampValue(buffer));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
TimestampService.prototype._encodeBlockTimestampKey = function(hash) {
|
|
||||||
return Buffer.concat([this.prefix, new Buffer(hash, 'hex')]);
|
|
||||||
};
|
|
||||||
|
|
||||||
TimestampService.prototype._decodeBlockTimestampKey = function(buffer) {
|
|
||||||
return buffer.slice(2).toString('hex');
|
|
||||||
};
|
|
||||||
|
|
||||||
TimestampService.prototype._encodeBlockTimestampValue = function(timestamp) {
|
|
||||||
var timestampBuffer = new Buffer(new Array(8));
|
|
||||||
timestampBuffer.writeDoubleBE(timestamp);
|
|
||||||
return timestampBuffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
TimestampService.prototype._decodeBlockTimestampValue = function(buffer) {
|
|
||||||
return buffer.readDoubleBE(0);
|
|
||||||
};
|
|
||||||
|
|
||||||
TimestampService.prototype._encodeTimestampBlockKey = function(timestamp) {
|
|
||||||
var timestampBuffer = new Buffer(new Array(8));
|
|
||||||
timestampBuffer.writeDoubleBE(timestamp);
|
|
||||||
return Buffer.concat([this.prefix, timestampBuffer]);
|
|
||||||
};
|
|
||||||
|
|
||||||
TimestampService.prototype._decodeTimestampBlockKey = function(buffer) {
|
|
||||||
return buffer.readDoubleBE(2);
|
|
||||||
};
|
|
||||||
|
|
||||||
TimestampService.prototype._encodeTimestampBlockValue = function(hash) {
|
|
||||||
return new Buffer(hash, 'hex');
|
|
||||||
};
|
|
||||||
|
|
||||||
TimestampService.prototype._decodeTimestampBlockValue = function(buffer) {
|
|
||||||
return buffer.toString('hex');
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = TimestampService;
|
module.exports = TimestampService;
|
||||||
|
|||||||
@ -5,6 +5,7 @@ var BaseService = require('../service');
|
|||||||
var inherits = require('util').inherits;
|
var inherits = require('util').inherits;
|
||||||
var bitcore = require('bitcore-lib');
|
var bitcore = require('bitcore-lib');
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
|
var Encoding = require('../encoding');
|
||||||
var LRU = require('lru-cache');
|
var LRU = require('lru-cache');
|
||||||
var utils = require('./wallet-api/utils');
|
var utils = require('./wallet-api/utils');
|
||||||
var index = require('../');
|
var index = require('../');
|
||||||
@ -78,6 +79,7 @@ TransactionService.prototype.start = function(callback) {
|
|||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
self.prefix = prefix;
|
self.prefix = prefix;
|
||||||
|
self.encoding = new Encoding(self.prefix);
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
}], function(err) {
|
}], function(err) {
|
||||||
@ -154,8 +156,8 @@ TransactionService.prototype.blockHandler = function(block, connectBlock, callba
|
|||||||
|
|
||||||
operations.push({
|
operations.push({
|
||||||
type: action,
|
type: action,
|
||||||
key: self._encodeTransactionKey(tx.id),
|
key: self.encoding.encodeTransactionKey(tx.id),
|
||||||
value: self._encodeTransactionValue(tx)
|
value: self.encoding.encodeTransactionValue(tx)
|
||||||
});
|
});
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
@ -220,61 +222,17 @@ TransactionService.prototype.getTransaction = function(txid, options, callback)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//transaction was not in our mempool, lookup in the database
|
//transaction was not in our mempool, lookup in the database
|
||||||
var key = self._encodeTransactionKey(txid);
|
var key = self.encoding.encodeTransactionKey(txid);
|
||||||
|
|
||||||
self.node.services.db.store.get(key, function(err, buffer) {
|
self.node.services.db.store.get(key, function(err, buffer) {
|
||||||
if(err) {
|
if(err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx = self._decodeTransactionValue(buffer);
|
var tx = self.encoding.decodeTransactionValue(buffer);
|
||||||
callback(null, tx);
|
callback(null, tx);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionService.prototype._encodeTransactionKey = function(txid) {
|
|
||||||
return Buffer.concat([this.prefix, new Buffer(txid, 'hex')]);
|
|
||||||
};
|
|
||||||
|
|
||||||
TransactionService.prototype._decodeTransactionKey = function(buffer) {
|
|
||||||
return buffer.slice(2).toString('hex');
|
|
||||||
};
|
|
||||||
|
|
||||||
TransactionService.prototype._encodeTransactionValue = function(transaction) {
|
|
||||||
var heightBuffer = new Buffer(4);
|
|
||||||
heightBuffer.writeUInt32BE(transaction.__height);
|
|
||||||
|
|
||||||
var timestampBuffer = new Buffer(8);
|
|
||||||
timestampBuffer.writeDoubleBE(transaction.__timestamp);
|
|
||||||
|
|
||||||
var inputValues = transaction.__inputValues;
|
|
||||||
var inputValuesBuffer = new Buffer(8 * inputValues.length);
|
|
||||||
for(var i = 0; i < inputValues.length; i++) {
|
|
||||||
inputValuesBuffer.writeDoubleBE(inputValues[i], i * 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
var inputValuesLengthBuffer = new Buffer(2);
|
|
||||||
inputValuesLengthBuffer.writeUInt16BE(inputValues.length * 8);
|
|
||||||
|
|
||||||
return new Buffer.concat([heightBuffer, timestampBuffer,
|
|
||||||
inputValuesLengthBuffer, inputValuesBuffer, transaction.toBuffer()]);
|
|
||||||
};
|
|
||||||
|
|
||||||
TransactionService.prototype._decodeTransactionValue = function(buffer) {
|
|
||||||
var height = buffer.readUInt32BE();
|
|
||||||
|
|
||||||
var timestamp = buffer.readDoubleBE(4);
|
|
||||||
|
|
||||||
var inputValues = [];
|
|
||||||
var inputValuesLength = buffer.readUInt16BE(12);
|
|
||||||
for(var i = 0; i < inputValuesLength / 8; i++) {
|
|
||||||
inputValues.push(buffer.readDoubleBE(i * 8 + 14));
|
|
||||||
}
|
|
||||||
var transaction = new bitcore.Transaction(buffer.slice(inputValues.length * 8 + 14));
|
|
||||||
transaction.__height = height;
|
|
||||||
transaction.__inputValues = inputValues;
|
|
||||||
transaction.__timestamp = timestamp;
|
|
||||||
return transaction;
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = TransactionService;
|
module.exports = TransactionService;
|
||||||
|
|||||||
@ -725,10 +725,6 @@ exports.parseByteCount = function(byteCountString) {
|
|||||||
* output: bool args are valid for encoding a key to the database
|
* output: bool args are valid for encoding a key to the database
|
||||||
*/
|
*/
|
||||||
exports.hasRequiredArgsForEncoding = function(args) {
|
exports.hasRequiredArgsForEncoding = function(args) {
|
||||||
//for encoding a key to the database, the passed in args must:
|
|
||||||
// the first atg should exist
|
|
||||||
// the second arg is optional, but must exist if there is a third, fourth, nth arg
|
|
||||||
// the third arg is optional, but not if the second arg is missing, etc.
|
|
||||||
function exists(arg) {
|
function exists(arg) {
|
||||||
return !(arg === null || arg === undefined);
|
return !(arg === null || arg === undefined);
|
||||||
}
|
}
|
||||||
|
|||||||
58
lib/utils.js
58
lib/utils.js
@ -39,4 +39,62 @@ utils.parseParamsWithJSON = function parseParamsWithJSON(paramsArg) {
|
|||||||
return params;
|
return params;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* input: string representing a number + multiple of bytes, e.g. 500MB, 200KB, 100B
|
||||||
|
* output: integer representing the byte count
|
||||||
|
*/
|
||||||
|
utils.parseByteCount = function(byteCountString) {
|
||||||
|
|
||||||
|
function finish(n, m) {
|
||||||
|
var num = parseInt(n);
|
||||||
|
if (num > 0) {
|
||||||
|
return num * m;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_.isString(byteCountString)) {
|
||||||
|
return byteCountString;
|
||||||
|
}
|
||||||
|
var str = byteCountString.replace(/\s+/g, '');
|
||||||
|
var map = { 'MB': 1E6, 'kB': 1000, 'KB': 1000, 'MiB': (1024 * 1024),
|
||||||
|
'KiB': 1024, 'GiB': Math.pow(1024, 3), 'GB': 1E9 };
|
||||||
|
var keys = Object.keys(map);
|
||||||
|
for(var i = 0; i < keys.length; i++) {
|
||||||
|
var re = new RegExp(keys[i] + '$');
|
||||||
|
var match = str.match(re);
|
||||||
|
if (match) {
|
||||||
|
var num = str.slice(0, match.index);
|
||||||
|
return finish(num, map[keys[i]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return finish(byteCountString, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* input: arguments passed into originating function (whoever called us)
|
||||||
|
* output: bool args are valid for encoding a key to the database
|
||||||
|
*/
|
||||||
|
utils.hasRequiredArgsForEncoding = function(args) {
|
||||||
|
function exists(arg) {
|
||||||
|
return !(arg === null || arg === undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!exists(args[0])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var pastArgMissing;
|
||||||
|
|
||||||
|
for(var i = 1; i < args.length; i++) {
|
||||||
|
var argMissing = exists(args[i]);
|
||||||
|
if (argMissing && pastArgMissing) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pastArgMissing = argMissing;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = utils;
|
module.exports = utils;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user