wip
This commit is contained in:
parent
73687b36cf
commit
1b77fdf5e4
@ -265,67 +265,59 @@ BlockService.prototype._blockAlreadyProcessed = function(block) {
|
|||||||
|
|
||||||
BlockService.prototype._mergeBlockIntoChainTips = function(block) {
|
BlockService.prototype._mergeBlockIntoChainTips = function(block) {
|
||||||
|
|
||||||
function getPrevHashChain(keys, hash) {
|
|
||||||
|
|
||||||
for(var i = 0; i < keys.length; i++) {
|
|
||||||
console.log('here');
|
|
||||||
|
|
||||||
var key = keys[i];
|
|
||||||
|
|
||||||
var searchChain = this._chainTips.get(key);
|
|
||||||
console.log(searchChain);
|
|
||||||
|
|
||||||
var chainIndex = searchChain.indexOf(hash);
|
|
||||||
|
|
||||||
if (chainIndex > -1) {
|
|
||||||
return searchChain.slice(chainIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var prevHash = utils.reverseBufferToString(block.header.prevHash);
|
var prevHash = utils.reverseBufferToString(block.header.prevHash);
|
||||||
var hasChildren = false;
|
var hasChildren = false;
|
||||||
|
|
||||||
var chain = this._chainTips.get(prevHash);
|
var chain = this._chainTips.get(prevHash);
|
||||||
|
|
||||||
|
this._chainTips.del(prevHash);
|
||||||
|
|
||||||
if (chain) {
|
if (chain) {
|
||||||
chain.unshift(prevHash);
|
chain.unshift(prevHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
var keys = this._chainTips.keys();
|
var keys = this._chainTips.keys();
|
||||||
|
|
||||||
// looking for chains where this block is an ancestor of the tip of the chain
|
|
||||||
for(var i = 0; i < keys.length; i++) {
|
for(var i = 0; i < keys.length; i++) {
|
||||||
|
|
||||||
var key = keys[i];
|
var key = keys[i];
|
||||||
var searchChain = this._chainTips.get(key);
|
var searchChain = this._chainTips.get(key);
|
||||||
|
|
||||||
|
assert(searchChain.length > 0, 'chain tips collection appears to be invalid');
|
||||||
|
|
||||||
var chainIndex = searchChain.indexOf(block.hash);
|
var chainIndex = searchChain.indexOf(block.hash);
|
||||||
|
|
||||||
if (chainIndex > -1) {
|
if (chainIndex > -1) {
|
||||||
hasChildren = true;
|
hasChildren = true;
|
||||||
var newChain = searchChain.concat(chain || getPrevHashChain(keys, prevHash));
|
this._chainTips.set(key, searchChain.concat(chain || [prevHash]));
|
||||||
this._chainTips.set(key, newChain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chain && !hasChildren) {
|
if (chain && !hasChildren) {
|
||||||
|
|
||||||
this._chainTips.set(block.hash, chain);
|
this._chainTips.set(block.hash, chain);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this._chainTips.del(prevHash);
|
if (!chain && !hasChildren) {
|
||||||
|
|
||||||
// if we have don't have any parents or children in chainTips, then create a new chain with this block
|
var longestChain = [];
|
||||||
if (!hasChildren && !chain) {
|
for(var j = 0; j < keys.length; j++) {
|
||||||
this._chainTips.set(block.hash, getPrevHashChain(keys, prevHash));
|
var key = keys[j];
|
||||||
|
var searchChain = this._chainTips.get(key);
|
||||||
|
var chainIndex = searchChain.indexOf(prevHash);
|
||||||
|
if (chainIndex > -1) {
|
||||||
|
var chain = searchChain.slice(chainIndex);
|
||||||
|
if (chain.length > longestChain.length) {
|
||||||
|
longestChain = chain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
longestChain = longestChain.length <= 1 ? [prevHash] : longestChain;
|
||||||
|
this._chainTips.set(block.hash, longestChain);
|
||||||
}
|
}
|
||||||
|
console.log(block.hash);
|
||||||
|
console.log(this._chainTips);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BlockService.prototype._onBlock = function(block) {
|
||||||
BlockService.prototype._onBlock = function(block) {
|
BlockService.prototype._onBlock = function(block) {
|
||||||
|
|
||||||
// 1. have we already seen this block?
|
// 1. have we already seen this block?
|
||||||
|
|||||||
@ -49,7 +49,7 @@ describe('Block Service', function() {
|
|||||||
expect(blockService._chainTips.get('ee')).to.deep.equal(['dd', 'cc', 'bb', 'aa', '00']);
|
expect(blockService._chainTips.get('ee')).to.deep.equal(['dd', 'cc', 'bb', 'aa', '00']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should merge chain tips where there is a fork (a parent block has more than one child)' , function() {
|
it('should merge blocks where there is a fork (a parent block has more than one child)' , function() {
|
||||||
|
|
||||||
var blocks = ['aa','bb','cc','dd','ee'];
|
var blocks = ['aa','bb','cc','dd','ee'];
|
||||||
var prevBlocks = ['00','aa','aa','cc','dd'];
|
var prevBlocks = ['00','aa','aa','cc','dd'];
|
||||||
@ -62,8 +62,41 @@ describe('Block Service', function() {
|
|||||||
|
|
||||||
expect(blockService._chainTips.length).to.equal(2);
|
expect(blockService._chainTips.length).to.equal(2);
|
||||||
expect(blockService._chainTips.get('ee')).to.deep.equal(['dd', 'cc', 'aa', '00']);
|
expect(blockService._chainTips.get('ee')).to.deep.equal(['dd', 'cc', 'aa', '00']);
|
||||||
|
expect(blockService._chainTips.get('bb')).to.deep.equal(['aa', '00']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should merge blocks where there is a fork (a parent block has more than one child) and blocks are received out of order' , function() {
|
||||||
|
|
||||||
|
var blocks = ['cc','aa','bb','ee','dd'];
|
||||||
|
var prevBlocks = ['aa','00','aa','dd','cc'];
|
||||||
|
|
||||||
|
blocks.forEach(function(n, index) {
|
||||||
|
var block = { header: { prevHash: new Buffer(prevBlocks[index], 'hex') }, hash: n };
|
||||||
|
blockService._mergeBlockIntoChainTips(block);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
expect(blockService._chainTips.length).to.equal(2);
|
||||||
|
expect(blockService._chainTips.get('ee')).to.deep.equal(['dd', 'cc', 'aa', '00']);
|
||||||
|
expect(blockService._chainTips.get('bb')).to.deep.equal(['aa', '00']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should merge blocks where there is a three-way fork (a parent block has more than one child) and blocks are received out of order' , function() {
|
||||||
|
|
||||||
|
var blocks = ['cc','aa','bb','ee','dd'];
|
||||||
|
var prevBlocks = ['aa','00','aa','dd','aa'];
|
||||||
|
|
||||||
|
blocks.forEach(function(n, index) {
|
||||||
|
var block = { header: { prevHash: new Buffer(prevBlocks[index], 'hex') }, hash: n };
|
||||||
|
blockService._mergeBlockIntoChainTips(block);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
expect(blockService._chainTips.length).to.equal(3);
|
||||||
|
expect(blockService._chainTips.get('ee')).to.deep.equal(['dd', 'aa', '00']);
|
||||||
|
expect(blockService._chainTips.get('bb')).to.deep.equal(['aa', '00']);
|
||||||
|
expect(blockService._chainTips.get('cc')).to.deep.equal(['aa', '00']);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user