flocore-node/lib/services/timestamp/index.js
Chris Kleeschulte b51179274f wip
2017-05-23 08:53:54 -04:00

153 lines
3.4 KiB
JavaScript

'use strict';
var Encoding = require('./encoding');
var BaseService = require('../../service');
var inherits = require('util').inherits;
var LRU = require('lru-cache');
var utils = require('../../../lib/utils');
var bitcore = require('bitcore-lib');
function TimestampService(options) {
BaseService.call(this, options);
this.currentBlock = null;
this.currentTimestamp = null;
this._cache = LRU(50);
this._cache.set(new Array(65).join('0'), { time: 0 });
this._setHandlers();
}
inherits(TimestampService, BaseService);
TimestampService.dependencies = [ 'db', 'block' ];
TimestampService.prototype.start = function(callback) {
var self = this;
this.db = this.node.services.db;
this.node.services.db.getPrefix(this.name, function(err, prefix) {
if(err) {
return callback(err);
}
self.prefix = prefix;
self.encoding = new Encoding(self.prefix);
callback();
});
};
TimestampService.prototype.stop = function(callback) {
setImmediate(callback);
};
TimestampService.prototype._setHandlers = function() {
var self = this;
};
TimestampService.prototype._processBlockHandlerQueue = function(block) {
var self = this;
var blockTime = block.header.timestamp;
var prevHash = utils.reverseBufferToString(block.header.prevHash);
var prev = self._cache.get(prevHash);
if (prev && !prev.prevHash) {
if (blockTime <= prev.time) {
blockTime = prev.time + 1;
}
self._cache.del(prevHash);
self._cache.set(block.hash, { time: blockTime });
return [{ hash: block.hash, time: blockTime }];
}
self._cache.set(block.hash, { time: blockTime, prevHash: prevHash });
var additionalBlocks = [];
var dependentHash = block.hash;
self._cache.rforEach(function(value, key) {
if (dependentHash === value.prevHash) {
additionalBlocks.push({ hash: key, time: value.time });
dependentHash = value.prevHash;
self._cache.del(key);
}
});
return additionalBlocks;
};
TimestampService.prototype.blockHandler = function(block, connectBlock, callback) {
var self = this;
var action = connectBlock ? 'put' : 'del';
var queue = self._processBlockHandlerQueue(block);
var operations = [];
if (queue.length === 0) {
return callback(null, queue);
}
for(var i = 0; i < queue.length; i++) {
var item = queue[i];
operations = operations.concat([
{
type: action,
key: self.encoding.encodeTimestampBlockKey(item.time),
value: self.encoding.encodeTimestampBlockValue(item.hash)
},
{
type: action,
key: self.encoding.encodeBlockTimestampKey(item.hash),
value: self.encoding.encodeBlockTimestampValue(item.time)
}
]);
}
callback(null, operations);
};
TimestampService.prototype.getTimestamp = function(hash, callback) {
this._getValue(hash, callback);
};
TimestampService.prototype.getHash = function(timestamp, callback) {
this._getValue(timestamp, callback);
};
TimestampService.prototype._getValue = function(key, callback) {
var self = this;
var keyBuf, fn;
if (key.length === 64){
keyBuf = self.encoding.encodeBlockTimestampKey(key);
fn = self.encoding.decodeBlockTimestampValue;
} else {
keyBuf = self.encoding.encodeTimestampBlockKey(key);
fn = self.encoding.decodeTimestampBlockValue;
}
self.db.get(keyBuf, function(err, value) {
if (err) {
return callback(err);
}
callback(null, fn(value));
});
};
module.exports = TimestampService;