wip
This commit is contained in:
parent
6cccce833d
commit
6fc170f7da
@ -91,7 +91,7 @@ BlockService.prototype.printTipInfo = function(prependedMessage) {
|
||||
log.info(
|
||||
prependedMessage + ' Serial Tip: ' + this.tip.hash +
|
||||
' Concurrent tip: ' + this.concurrentTip.hash +
|
||||
' Bitcoind tip: ' + this.bitcoind.tiphash
|
||||
' Network tip: ' + this.bitcoind.tiphash
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
@ -10,36 +10,38 @@ var index = require('../');
|
||||
var log = index.log;
|
||||
var Service = require('../../service');
|
||||
|
||||
/*
|
||||
Purpose:
|
||||
1. join a P2P
|
||||
2. relay messages
|
||||
3. publish new transactions (pub/sub)
|
||||
4. publish new blocks (pub/sub)
|
||||
5. broadcast messages on behalf of subscribers (block headers, blocks, bloom filters)
|
||||
*/
|
||||
var P2P = function(options) {
|
||||
if (!(this instanceof P2P)) {
|
||||
return new P2P(options);
|
||||
}
|
||||
|
||||
Service.call(this, options);
|
||||
this.options = options;
|
||||
this._maxPeers = this.options.maxPeers || 60;
|
||||
this._peers = this.options.peers;
|
||||
this._maxMempoolSize = this.options.maxMempoolSize || 100 * 1024 * 1024;
|
||||
this._synced = false;
|
||||
this.initialHeight = 0;
|
||||
this.subscriptions = {};
|
||||
};
|
||||
|
||||
util.inherits(P2P, Service);
|
||||
|
||||
P2P.dependencies = [ 'bitcoind', 'db' ];
|
||||
P2P.dependencies = [];
|
||||
|
||||
P2P.prototype.start = function(callback) {
|
||||
//Step 1: connect to peer(s) as per config
|
||||
//Step 2: memoize the tip
|
||||
//Step 3: wait for other services to register listeners
|
||||
var self = this;
|
||||
self.once('synced', function() {
|
||||
self._initPrefix(callback);
|
||||
self._initPool();
|
||||
self._initCache();
|
||||
self._pool.connect();
|
||||
self._synced = true;
|
||||
});
|
||||
callback();
|
||||
};
|
||||
|
||||
P2P.prototype.stop = function(callback) {
|
||||
@ -50,15 +52,17 @@ P2P.prototype.stop = function(callback) {
|
||||
});
|
||||
};
|
||||
|
||||
P2P.prototype._initPrefix = function(callback) {
|
||||
var self = this;
|
||||
self.node.services.db.getPrefix(self.name, function(err, prefix) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
self.prefix = prefix;
|
||||
callback();
|
||||
});
|
||||
P2P.prototype.subscribe = function(name, emitter) {
|
||||
this.subscriptions[name].push(emitter);
|
||||
log.info(emitter.remoteAddress, 'subscribe:', 'p2p/' + name, 'total:', this.subscriptions[name].length);
|
||||
};
|
||||
|
||||
P2P.prototype.unsubscribe = function(name, emitter) {
|
||||
var index = this.subscriptions[name].indexOf(emitter);
|
||||
if (index > -1) {
|
||||
this.subscriptions[name].splice(index, 1);
|
||||
}
|
||||
log.info(emitter.remoteAddress, 'unsubscribe:', 'p2p/' + name, 'total:', this.subscriptions[name].length);
|
||||
};
|
||||
|
||||
P2P.prototype._initCache = function() {
|
||||
@ -135,6 +139,26 @@ P2P.prototype.getAPIMethods = function() {
|
||||
};
|
||||
|
||||
P2P.prototype.getPublishEvents = function() {
|
||||
return [
|
||||
{
|
||||
name: 'p2p/transaction',
|
||||
scope: this,
|
||||
subscribe: this.subscribe.bind(this, 'transaction'),
|
||||
unsubscribe: this.unsubscribe.bind(this, 'transaction')
|
||||
},
|
||||
{
|
||||
name: 'p2p/block',
|
||||
scope: this,
|
||||
subscribe: this.subscribe.bind(this, 'block'),
|
||||
unsubscribe: this.unsubscribe.bind(this, 'block')
|
||||
},
|
||||
{
|
||||
name: 'bitcoind/rawblock',
|
||||
scope: this,
|
||||
subscribe: this.subscribe.bind(this, 'rawblock'),
|
||||
unsubscribe: this.unsubscribe.bind(this, 'rawblock')
|
||||
}
|
||||
];
|
||||
return [];
|
||||
};
|
||||
|
||||
|
||||
@ -10,7 +10,9 @@ function TimestampService(options) {
|
||||
BaseService.call(this, options);
|
||||
this.currentBlock = null;
|
||||
this.currentTimestamp = null;
|
||||
this._blockHandlerQueue = LRU(50);
|
||||
this._cache = LRU(50);
|
||||
var genesis = self.node.services.block.genesis;
|
||||
this._cache.set(genesis.hash, genesis.__height);
|
||||
}
|
||||
|
||||
inherits(TimestampService, BaseService);
|
||||
@ -40,28 +42,41 @@ TimestampService.prototype.stop = function(callback) {
|
||||
};
|
||||
|
||||
TimestampService.prototype._processBlockHandlerQueue = function(block) {
|
||||
|
||||
var self = this;
|
||||
//do we have a record in the queue that is waiting on me to consume it?
|
||||
|
||||
var blockTime = block.header.timestamp;
|
||||
|
||||
var prevHash = utils.reverseBufferToString(block.header.prevHash);
|
||||
if (prevHash.length !== 64) {
|
||||
return;
|
||||
}
|
||||
|
||||
var timestamp = self._blockHandlerQueue.get(prevHash);
|
||||
var prev = self._cache.get(prevHash);
|
||||
|
||||
if (timestamp) {
|
||||
if (block.header.timestamp <= timestamp) {
|
||||
timestamp = block.header.timestamp + 1;
|
||||
if (prev && !prev.prevHash) {
|
||||
|
||||
if (blockTime <= prev.time) {
|
||||
blockTime++;
|
||||
}
|
||||
self.counter++;
|
||||
timestamp = block.header.timestamp;
|
||||
self._blockHandlerQueue.del(prevHash);
|
||||
} else {
|
||||
timestamp = block.header.timestamp;
|
||||
|
||||
self._cache.del(prevHash);
|
||||
self._cache.set(block.hash, { time: blockTime });
|
||||
return [{ hash: block.hash, time: blockTime }];
|
||||
}
|
||||
|
||||
self._blockHandlerQueue.set(block.hash, timestamp);
|
||||
return timestamp;
|
||||
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) {
|
||||
@ -70,14 +85,14 @@ TimestampService.prototype.blockHandler = function(block, connectBlock, callback
|
||||
|
||||
var action = connectBlock ? 'put' : 'del';
|
||||
|
||||
var timestamp = self._processBlockHandlerQueue(block);
|
||||
|
||||
if (!timestamp) {
|
||||
return callback(null, []);
|
||||
}
|
||||
var queue = self._processBlockHandlerQueue(block);
|
||||
|
||||
var operations = [];
|
||||
|
||||
if (!queue.length < 1) {
|
||||
return callback(null, []);
|
||||
}
|
||||
|
||||
operations = operations.concat([
|
||||
{
|
||||
type: action,
|
||||
|
||||
@ -282,6 +282,7 @@ WebService.prototype.transformHttpsOptions = function() {
|
||||
WebService.prototype._endpointGetInfo = function() {
|
||||
var self = this;
|
||||
return function(req, res) {
|
||||
console.log(self.node.services);
|
||||
res.jsonp({
|
||||
result: 'ok',
|
||||
dbheight: self.node.services.block.tip.__height,
|
||||
|
||||
@ -82,5 +82,10 @@ utils.reverseBufferToString = function(buf) {
|
||||
return BufferUtil.reverse(buf).toString('hex');
|
||||
};
|
||||
|
||||
//TODO: write some code here
|
||||
utils.getIpAddressInfo = function(ipStr) {
|
||||
//is this ipv4 or ipv6, 4 is 32 bits, 6 is 128 bits
|
||||
//does this string have colons or periods?
|
||||
};
|
||||
|
||||
module.exports = utils;
|
||||
|
||||
1509
regtest/p2p.js
1509
regtest/p2p.js
File diff suppressed because it is too large
Load Diff
@ -53,7 +53,8 @@ var bitcore = {
|
||||
'address',
|
||||
'mempool',
|
||||
'wallet-api',
|
||||
'web'
|
||||
'web',
|
||||
'block'
|
||||
],
|
||||
servicesConfig: {
|
||||
bitcoind: {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user