wip
This commit is contained in:
parent
35a21288b4
commit
b4a66d969c
@ -406,8 +406,13 @@ AddressService.prototype._onReorg = function(commonAncestorHeader, oldBlockList)
|
|||||||
};
|
};
|
||||||
|
|
||||||
AddressService.prototype.onBlock = function(block, callback) {
|
AddressService.prototype.onBlock = function(block, callback) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
if (self.node.stopping) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
|
||||||
var operations = [];
|
var operations = [];
|
||||||
|
|
||||||
block.txs.forEach(function(tx) {
|
block.txs.forEach(function(tx) {
|
||||||
|
|||||||
@ -49,7 +49,7 @@ inherits(BlockService, BaseService);
|
|||||||
|
|
||||||
BlockService.dependencies = [ 'p2p', 'db', 'header' ];
|
BlockService.dependencies = [ 'p2p', 'db', 'header' ];
|
||||||
|
|
||||||
BlockService.MAX_BLOCKS = 3
|
BlockService.MAX_BLOCKS = 1;
|
||||||
|
|
||||||
// --- public prototype functions
|
// --- public prototype functions
|
||||||
BlockService.prototype.getAPIMethods = function() {
|
BlockService.prototype.getAPIMethods = function() {
|
||||||
@ -247,7 +247,7 @@ BlockService.prototype._broadcast = function(subscribers, name, entity) {
|
|||||||
|
|
||||||
BlockService.prototype._cacheBlock = function(block) {
|
BlockService.prototype._cacheBlock = function(block) {
|
||||||
|
|
||||||
log.debug('Setting block: ' + block.rhash() + ' in the block cache.');
|
log.debug('Block Service: Setting block: ' + block.rhash() + ' in the block cache.');
|
||||||
|
|
||||||
// 1. set the block queue, which holds full blocks in memory
|
// 1. set the block queue, which holds full blocks in memory
|
||||||
this._blockQueue.set(block.rhash(), block);
|
this._blockQueue.set(block.rhash(), block);
|
||||||
@ -424,7 +424,7 @@ BlockService.prototype._handleReorg = function(hash, allHeaders) {
|
|||||||
|
|
||||||
this._reorging = true; // while this is set, we won't be sending blocks
|
this._reorging = true; // while this is set, we won't be sending blocks
|
||||||
|
|
||||||
log.warn('Chain reorganization detected! Our current block tip is: ' +
|
log.warn('Block Serivce: Chain reorganization detected! Our current block tip is: ' +
|
||||||
this._tip.hash + ' the current block: ' + hash + '.');
|
this._tip.hash + ' the current block: ' + hash + '.');
|
||||||
|
|
||||||
this._findCommonAncestor(hash, allHeaders, function(err, newHash, commonAncestorHash, oldBlocks) {
|
this._findCommonAncestor(hash, allHeaders, function(err, newHash, commonAncestorHash, oldBlocks) {
|
||||||
@ -441,7 +441,7 @@ BlockService.prototype._handleReorg = function(hash, allHeaders) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var commonAncestorHeader = allHeaders.get(commonAncestorHash);
|
var commonAncestorHeader = allHeaders.get(commonAncestorHash);
|
||||||
log.warn('A common ancestor block was found to at hash: ' + commonAncestorHeader + '.');
|
log.warn('Block Service: A common ancestor block was found to at hash: ' + commonAncestorHeader + '.');
|
||||||
|
|
||||||
this._broadcast(this.subscriptions.reorg, 'block/reorg', [commonAncestorHeader, oldBlocks]);
|
this._broadcast(this.subscriptions.reorg, 'block/reorg', [commonAncestorHeader, oldBlocks]);
|
||||||
|
|
||||||
@ -587,7 +587,7 @@ BlockService.prototype._processBlock = function() {
|
|||||||
value: tipOps.value
|
value: tipOps.value
|
||||||
});
|
});
|
||||||
|
|
||||||
self._db._store.batch(operations, function(err) {
|
self._db.batch(operations, function(err) {
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
log.error(err);
|
log.error(err);
|
||||||
@ -602,6 +602,10 @@ BlockService.prototype._processBlock = function() {
|
|||||||
|
|
||||||
BlockService.prototype._onBlock = function(block) {
|
BlockService.prototype._onBlock = function(block) {
|
||||||
|
|
||||||
|
if (this.node.stopping) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
log.debug('Block Service: new block: ' + block.rhash());
|
log.debug('Block Service: new block: ' + block.rhash());
|
||||||
|
|
||||||
this._unprocessedBlocks.push(block);
|
this._unprocessedBlocks.push(block);
|
||||||
@ -679,8 +683,8 @@ BlockService.prototype._setListeners = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
BlockService.prototype._setTip = function(tip) {
|
BlockService.prototype._setTip = function(tip) {
|
||||||
log.debug('Setting tip to height: ' + tip.height);
|
log.debug('Block Service: Setting tip to height: ' + tip.height);
|
||||||
log.debug('Setting tip to hash: ' + tip.hash);
|
log.debug('Block Service: Setting tip to hash: ' + tip.hash);
|
||||||
this._tip = tip;
|
this._tip = tip;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -691,7 +695,7 @@ BlockService.prototype._startSync = function() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info('Gathering: ' + this._numNeeded + ' block(s) from the peer-to-peer network.');
|
log.info('Block Service: Gathering: ' + this._numNeeded + ' block(s) from the peer-to-peer network.');
|
||||||
|
|
||||||
this._sync();
|
this._sync();
|
||||||
};
|
};
|
||||||
@ -712,17 +716,22 @@ BlockService.prototype._startSubscriptions = function() {
|
|||||||
|
|
||||||
BlockService.prototype._sync = function() {
|
BlockService.prototype._sync = function() {
|
||||||
|
|
||||||
|
if (this.node.stopping) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var headers = this._header.getAllHeaders();
|
var headers = this._header.getAllHeaders();
|
||||||
var size = headers.size - 1;
|
var size = headers.size - 1;
|
||||||
|
|
||||||
if (this._tip.height < size) {
|
if (this._tip.height < size) {
|
||||||
|
|
||||||
log.info('Blocks download progress: ' + this._tip.height + '/' +
|
log.info('Block Service: Blocks download progress: ' + this._tip.height + '/' +
|
||||||
this._numNeeded + ' (' + (this._tip.height / this._bestHeight*100).toFixed(2) + '%)');
|
this._numNeeded + ' (' + (this._tip.height / this._bestHeight*100).toFixed(2) + '%)');
|
||||||
|
|
||||||
var end = headers.getIndex(Math.min(this._tip.height + BlockService.MAX_BLOCKS, size));
|
var end = headers.getIndex(Math.min(this._tip.height + BlockService.MAX_BLOCKS, size));
|
||||||
var endHash = end ? end.hash : null;
|
var endHash = end ? end.hash : null;
|
||||||
|
|
||||||
|
|
||||||
this._p2p.getBlocks({ startHash: this._tip.hash, endHash: endHash });
|
this._p2p.getBlocks({ startHash: this._tip.hash, endHash: endHash });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -122,7 +122,7 @@ DB.prototype.get = function(key, options, callback) {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DB.prototype.put = function(key, value, options) {
|
DB.prototype.put = function(key, value, callback) {
|
||||||
|
|
||||||
assert(Buffer.isBuffer(key), 'key NOT a buffer as expected.');
|
assert(Buffer.isBuffer(key), 'key NOT a buffer as expected.');
|
||||||
|
|
||||||
@ -138,18 +138,10 @@ DB.prototype.put = function(key, value, options) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self._store.put(key, value, options, function(err) {
|
self._store.put(key, value, callback);
|
||||||
|
|
||||||
if (err) {
|
|
||||||
self.emit('error', err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DB.prototype.batch = function(ops, options) {
|
DB.prototype.batch = function(ops, callback) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
@ -168,14 +160,7 @@ DB.prototype.batch = function(ops, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self._store.batch(ops, options, function(err) {
|
self._store.batch(ops, callback);
|
||||||
|
|
||||||
if (err) {
|
|
||||||
self.emit('error', err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -202,16 +187,13 @@ DB.prototype.createKeyStream = function(op) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
DB.prototype.stop = function(callback) {
|
DB.prototype.stop = function(callback) {
|
||||||
var self = this;
|
this._stopping = true;
|
||||||
self._stopping = true;
|
this.close(callback);
|
||||||
|
|
||||||
self.close(callback);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DB.prototype.close = function(callback) {
|
DB.prototype.close = function(callback) {
|
||||||
var self = this;
|
if (this._store && this._store.isOpen()) {
|
||||||
if (self._store && self._store.isOpen()) {
|
this._store.close(callback);
|
||||||
self._store.close(callback);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -92,8 +92,16 @@ HeaderService.prototype.start = function(callback) {
|
|||||||
},
|
},
|
||||||
function(tip, next) {
|
function(tip, next) {
|
||||||
self._tip = tip;
|
self._tip = tip;
|
||||||
|
self._originalTip = {
|
||||||
|
height: self._tip.height,
|
||||||
|
hash: self._tip.hash
|
||||||
|
};
|
||||||
|
if (self._tip.height > self._checkpoint) {
|
||||||
|
self._tip.height -= self._checkpoint;
|
||||||
|
}
|
||||||
if (self._tip.height === 0) {
|
if (self._tip.height === 0) {
|
||||||
self._headers.set(self.GENESIS_HASH, {
|
|
||||||
|
var genesisHeader = {
|
||||||
hash: self.GENESIS_HASH,
|
hash: self.GENESIS_HASH,
|
||||||
height: 0,
|
height: 0,
|
||||||
chainwork: HeaderService.STARTING_CHAINWORK,
|
chainwork: HeaderService.STARTING_CHAINWORK,
|
||||||
@ -103,12 +111,15 @@ HeaderService.prototype.start = function(callback) {
|
|||||||
nonce: 2083236893,
|
nonce: 2083236893,
|
||||||
bits: 0x1d00ffff,
|
bits: 0x1d00ffff,
|
||||||
merkleRoot: '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b'
|
merkleRoot: '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b'
|
||||||
});
|
};
|
||||||
|
|
||||||
|
self._headers.set(self.GENESIS_HASH, genesisHeader);
|
||||||
|
|
||||||
|
self._db._store.put(self._encoding.encodeHeaderKey(0, self.GENESIS_HASH),
|
||||||
|
self._encoding.encodeHeaderValue(genesisHeader), next);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
self._originalTip = {
|
|
||||||
height: self._tip.height,
|
|
||||||
hash: self._tip.hash
|
|
||||||
};
|
|
||||||
next();
|
next();
|
||||||
},
|
},
|
||||||
function(next) {
|
function(next) {
|
||||||
@ -120,6 +131,9 @@ HeaderService.prototype.start = function(callback) {
|
|||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self._headers.size > 0) {
|
||||||
|
self._tip.hash = self._headers.getLastIndex().hash;
|
||||||
|
}
|
||||||
self._setListeners();
|
self._setListeners();
|
||||||
self._startSubscriptions();
|
self._startSubscriptions();
|
||||||
callback();
|
callback();
|
||||||
@ -186,34 +200,23 @@ HeaderService.prototype._onBlock = function(block) {
|
|||||||
var header = block.toHeaders().toJSON();
|
var header = block.toHeaders().toJSON();
|
||||||
header.timestamp = header.ts;
|
header.timestamp = header.ts;
|
||||||
header.prevHash = header.prevBlock;
|
header.prevHash = header.prevBlock;
|
||||||
this._onHeaders([header], 1);
|
this._onHeaders([header]);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HeaderService.prototype._onHeaders = function(headers, convert) {
|
HeaderService.prototype._onHeaders = function(headers) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
if (!headers || headers.length < 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
log.debug('Header Service: Received: ' + headers.length + ' header(s).');
|
log.debug('Header Service: Received: ' + headers.length + ' header(s).');
|
||||||
|
|
||||||
var newHeaders = headers;
|
|
||||||
if (!convert) {
|
|
||||||
newHeaders = headers.map(function(header) {
|
|
||||||
header = header.toObject();
|
|
||||||
return header;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var runningHeight = self._tip.height;
|
|
||||||
var prevHeader = self._headers.getLastIndex();
|
var prevHeader = self._headers.getLastIndex();
|
||||||
|
|
||||||
var dbOps = [];
|
var dbOps = [];
|
||||||
for(var i = 0; i < headers.length; i++) {
|
for(var i = 0; i < headers.length; i++) {
|
||||||
var header = headers[i];
|
var header = headers[i];
|
||||||
header.height = ++runningHeight;
|
header.height = ++self._tip.height;
|
||||||
|
self._tip.hash = header.hash;
|
||||||
header.chainwork = self._getChainwork(header, prevHeader).toString(16, 32);
|
header.chainwork = self._getChainwork(header, prevHeader).toString(16, 32);
|
||||||
dbOps.push({
|
dbOps.push({
|
||||||
type: 'put',
|
type: 'put',
|
||||||
@ -224,9 +227,6 @@ HeaderService.prototype._onHeaders = function(headers, convert) {
|
|||||||
self._headers.set(header.hash, header);
|
self._headers.set(header.hash, header);
|
||||||
}
|
}
|
||||||
|
|
||||||
self._startingHash = self._tip.hash = newHeaders[newHeaders.length - 1].hash;
|
|
||||||
self._tip.height = self._tip.height + newHeaders.length;
|
|
||||||
|
|
||||||
var tipOps = utils.encodeTip(self._tip, self.name);
|
var tipOps = utils.encodeTip(self._tip, self.name);
|
||||||
dbOps.push({
|
dbOps.push({
|
||||||
type: 'put',
|
type: 'put',
|
||||||
@ -234,7 +234,7 @@ HeaderService.prototype._onHeaders = function(headers, convert) {
|
|||||||
value: tipOps.value
|
value: tipOps.value
|
||||||
});
|
});
|
||||||
|
|
||||||
self._db._store.batch(dbOps, function() {
|
self._db.batch(dbOps, function() {
|
||||||
|
|
||||||
if (self._tip.height < self._bestHeight) {
|
if (self._tip.height < self._bestHeight) {
|
||||||
self._sync();
|
self._sync();
|
||||||
@ -247,7 +247,6 @@ HeaderService.prototype._onHeaders = function(headers, convert) {
|
|||||||
if (self._originalTip.height > 0) {
|
if (self._originalTip.height > 0) {
|
||||||
|
|
||||||
var headerHash = self._headers.getIndex(self._originalTip.height).hash;
|
var headerHash = self._headers.getIndex(self._originalTip.height).hash;
|
||||||
console.log(headerHash, self._originalTip, self._tip, self._headers.getIndex(0));
|
|
||||||
|
|
||||||
if (self._originalTip.hash !== headerHash) {
|
if (self._originalTip.hash !== headerHash) {
|
||||||
|
|
||||||
@ -258,6 +257,7 @@ HeaderService.prototype._onHeaders = function(headers, convert) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
log.debug('Header Service: emitting headers to block service.');
|
||||||
self.emit('headers', self._headers);
|
self.emit('headers', self._headers);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -270,7 +270,8 @@ HeaderService.prototype._setListeners = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
HeaderService.prototype._onBestHeight = function(height) {
|
HeaderService.prototype._onBestHeight = function(height) {
|
||||||
assert(height >= this._tip.height, 'Our peer does not seem to be fully synced.');
|
assert(height >= this._tip.height, 'Our peer does not seem to be fully synced: best height: ' +
|
||||||
|
height + ' tip height: ' + this._tip.height);
|
||||||
log.debug('Header Service: Best Height is: ' + height);
|
log.debug('Header Service: Best Height is: ' + height);
|
||||||
this._bestHeight = height;
|
this._bestHeight = height;
|
||||||
this._startSync();
|
this._startSync();
|
||||||
@ -280,10 +281,6 @@ HeaderService.prototype._startSync = function() {
|
|||||||
|
|
||||||
this._numNeeded = Math.max(this._bestHeight - this._tip.height, this._checkpoint);
|
this._numNeeded = Math.max(this._bestHeight - this._tip.height, this._checkpoint);
|
||||||
|
|
||||||
if (this._tip.height > this._checkpoint) {
|
|
||||||
this._tip.height -= this._checkpoint;
|
|
||||||
this._tip.hash = this._headers.getIndex(this._tip.height).hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info('Header Service: Gathering: ' + this._numNeeded + ' ' + 'header(s) from the peer-to-peer network.');
|
log.info('Header Service: Gathering: ' + this._numNeeded + ' ' + 'header(s) from the peer-to-peer network.');
|
||||||
|
|
||||||
@ -310,8 +307,11 @@ HeaderService.prototype.getAllHeaders = function() {
|
|||||||
HeaderService.prototype._getPersistedHeaders = function(callback) {
|
HeaderService.prototype._getPersistedHeaders = function(callback) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
|
||||||
var start = self._encoding.encodeHeaderKey(0);
|
var start = self._encoding.encodeHeaderKey(0);
|
||||||
var end = self._encoding.encodeHeaderKey(0xffffffff);
|
var end = self._encoding.encodeHeaderKey(self._tip.height + 1);
|
||||||
|
|
||||||
var criteria = {
|
var criteria = {
|
||||||
gte: start,
|
gte: start,
|
||||||
lte: end
|
lte: end
|
||||||
|
|||||||
@ -241,10 +241,8 @@ P2P.prototype._onPeerBlock = function(peer, message) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
P2P.prototype._onPeerDisconnect = function(peer, addr) {
|
P2P.prototype._onPeerDisconnect = function(peer, addr) {
|
||||||
|
|
||||||
this._removePeer(peer);
|
this._removePeer(peer);
|
||||||
log.info('Disconnected from peer: ' + addr.ip.v4);
|
log.info('Disconnected from peer: ' + addr.ip.v4);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
P2P.prototype._onPeerHeaders = function(peer, message) {
|
P2P.prototype._onPeerHeaders = function(peer, message) {
|
||||||
|
|||||||
@ -153,6 +153,10 @@ TransactionService.prototype.onBlock = function(block, callback) {
|
|||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
if (self.node.stopping) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
|
||||||
var operations = block.txs.map(function(tx) {
|
var operations = block.txs.map(function(tx) {
|
||||||
return self._processTransaction(tx, { block: block });
|
return self._processTransaction(tx, { block: block });
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user