wip
This commit is contained in:
parent
4a294f7058
commit
c91155cc35
@ -48,7 +48,7 @@ inherits(BlockService, BaseService);
|
|||||||
|
|
||||||
BlockService.dependencies = [ 'p2p', 'db', 'header' ];
|
BlockService.dependencies = [ 'p2p', 'db', 'header' ];
|
||||||
|
|
||||||
BlockService.MAX_BLOCKS = 250;
|
BlockService.MAX_BLOCKS = 10;
|
||||||
|
|
||||||
// --- public prototype functions
|
// --- public prototype functions
|
||||||
BlockService.prototype.getAPIMethods = function() {
|
BlockService.prototype.getAPIMethods = function() {
|
||||||
|
|||||||
@ -12,6 +12,7 @@ var $ = bitcore.util.preconditions;
|
|||||||
var Service = require('../../service');
|
var Service = require('../../service');
|
||||||
var constants = require('../../constants');
|
var constants = require('../../constants');
|
||||||
var log = require('../../index').log;
|
var log = require('../../index').log;
|
||||||
|
var assert = require('assert');
|
||||||
|
|
||||||
function DB(options) {
|
function DB(options) {
|
||||||
|
|
||||||
@ -70,38 +71,10 @@ DB.prototype._setDataPath = function() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// _checkVersion only governs db versions from bitcore-node >= 4.0
|
|
||||||
DB.prototype._checkVersion = function(callback) {
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
// presupposition is that IF there is a database to open -and- there is a version key
|
|
||||||
// in the form below, it will be related to us and it must be equal to this service's version.
|
|
||||||
|
|
||||||
var versionBuf = Buffer.concat([ self._dbPrefix, new Buffer('version', 'utf8') ]);
|
|
||||||
self.get(versionBuf, self.dbOptions, function(err, buffer) {
|
|
||||||
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
var version;
|
|
||||||
|
|
||||||
if (buffer) {
|
|
||||||
version = buffer.readUInt32BE();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.version !== version) {
|
|
||||||
return callback(new Error('The version of the database "' + version + '" does not match the expected version "'));
|
|
||||||
}
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
DB.prototype._setVersion = function(callback) {
|
DB.prototype._setVersion = function(callback) {
|
||||||
var versionBuffer = new Buffer(new Array(4));
|
var versionBuffer = new Buffer(new Array(4));
|
||||||
versionBuffer.writeUInt32BE(this.version);
|
versionBuffer.writeUInt32BE(this.version);
|
||||||
this.put(this._dbPrefix + 'version', versionBuffer, callback);
|
this.put(Buffer.concat([ this._dbPrefix, new Buffer('version', 'utf8') ]), versionBuffer, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
DB.prototype.start = function(callback) {
|
DB.prototype.start = function(callback) {
|
||||||
@ -113,10 +86,7 @@ DB.prototype.start = function(callback) {
|
|||||||
|
|
||||||
self._store = levelup(self.dataPath, { db: self.levelupStore, keyEncoding: 'binary', valueEncoding: 'binary'});
|
self._store = levelup(self.dataPath, { db: self.levelupStore, keyEncoding: 'binary', valueEncoding: 'binary'});
|
||||||
|
|
||||||
|
setImmediate(callback);
|
||||||
setImmediate(function() {
|
|
||||||
self._checkVersion(self._setVersion.bind(self, callback));
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -154,6 +124,15 @@ DB.prototype.get = function(key, options, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
DB.prototype.put = function(key, value, options) {
|
DB.prototype.put = function(key, value, options) {
|
||||||
|
|
||||||
|
assert(Buffer.isBuffer(key), 'key NOT a buffer as expected.');
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
|
||||||
|
assert(Buffer.isBuffer(value), 'value exists but NOT a buffer as expected.');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (self._stopping) {
|
if (self._stopping) {
|
||||||
@ -174,12 +153,24 @@ DB.prototype.put = function(key, value, options) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
DB.prototype.batch = function(ops, options) {
|
DB.prototype.batch = function(ops, options) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (self._stopping) {
|
if (self._stopping) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(var i = 0; i < ops.length; i++) {
|
||||||
|
|
||||||
|
assert(Buffer.isBuffer(ops[i].key), 'key NOT a buffer as expected.');
|
||||||
|
|
||||||
|
if (ops[i].value) {
|
||||||
|
|
||||||
|
assert(Buffer.isBuffer(ops[i].value), 'value exists but NOT a buffer as expected.');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self._operationsCount += ops.length;
|
self._operationsCount += ops.length;
|
||||||
self._store.batch(ops, options, function(err) {
|
self._store.batch(ops, options, function(err) {
|
||||||
|
|
||||||
|
|||||||
@ -132,39 +132,24 @@ HeaderService.prototype._onHeaders = function(headers, convert) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var operations = this._getHeaderOperations(newHeaders);
|
var runningHeight = this._tip.height;
|
||||||
|
var prevHeader = Array.from(this._headers)[this._headers.length - 1];
|
||||||
|
|
||||||
|
for(var i = 0; i < headers.length; i++) {
|
||||||
|
var header = headers[i];
|
||||||
|
header.height = ++runningHeight;
|
||||||
|
header.chainwork = this._getChainwork(header, prevHeader).toString(16, 32);
|
||||||
|
prevHeader = header;
|
||||||
|
this._headers.set(header.hash, header);
|
||||||
|
}
|
||||||
|
|
||||||
this._tip.hash = newHeaders[newHeaders.length - 1].hash;
|
this._tip.hash = newHeaders[newHeaders.length - 1].hash;
|
||||||
this._tip.height = this._tip.height + newHeaders.length;
|
this._tip.height = this._tip.height + newHeaders.length;
|
||||||
|
|
||||||
this._db.batch(operations);
|
|
||||||
|
|
||||||
this._sync();
|
this._sync();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HeaderService.prototype._getHeaderOperations = function(headers) {
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
var runningHeight = this._tip.height;
|
|
||||||
// get the last header placed in the map
|
|
||||||
var prevHeader = Array.from(this._headers)[this._headers.length - 1];
|
|
||||||
|
|
||||||
return headers.map(function(header) {
|
|
||||||
header.height = ++runningHeight;
|
|
||||||
header.chainwork = self._getChainwork(header, prevHeader).toString(16, 32);
|
|
||||||
prevHeader = header;
|
|
||||||
// set the header in the in-memory map
|
|
||||||
self._headers.set(header.hash, header);
|
|
||||||
return {
|
|
||||||
type: 'put',
|
|
||||||
key: self._encoding.encodeHeaderKey(header.height, header.hash),
|
|
||||||
value: self._encoding.encodeHeaderValue(header)
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
HeaderService.prototype._setListeners = function() {
|
HeaderService.prototype._setListeners = function() {
|
||||||
|
|
||||||
this._p2p.once('bestHeight', this._onBestHeight.bind(this));
|
this._p2p.once('bestHeight', this._onBestHeight.bind(this));
|
||||||
|
|||||||
@ -54,13 +54,14 @@ MempoolService.prototype._startSubscriptions = function() {
|
|||||||
|
|
||||||
MempoolService.prototype._onBlock = function(block) {
|
MempoolService.prototype._onBlock = function(block) {
|
||||||
// remove this block's txs from mempool
|
// remove this block's txs from mempool
|
||||||
|
var self = this;
|
||||||
var ops = block.txs.map(function(tx) {
|
var ops = block.txs.map(function(tx) {
|
||||||
return {
|
return {
|
||||||
type: 'del',
|
type: 'del',
|
||||||
key: tx.txid()
|
key: self._encoding.encodeMempoolTransactionKey(tx.txid())
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
this._db.batch(ops);
|
self._db.batch(ops);
|
||||||
};
|
};
|
||||||
|
|
||||||
MempoolService.prototype._onTransaction = function(tx) {
|
MempoolService.prototype._onTransaction = function(tx) {
|
||||||
|
|||||||
@ -6,7 +6,7 @@ var BN = require('bn.js');
|
|||||||
var assert = require('chai').assert;
|
var assert = require('chai').assert;
|
||||||
var crypto = require('crypto');
|
var crypto = require('crypto');
|
||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
var Block = require('bitcore-lib').Block;
|
var Block = require('bcoin').block;
|
||||||
var Encoding = require('../../../lib/services/block/encoding');
|
var Encoding = require('../../../lib/services/block/encoding');
|
||||||
var LRU = require('lru-cache');
|
var LRU = require('lru-cache');
|
||||||
var constants = require('../../../lib/constants');
|
var constants = require('../../../lib/constants');
|
||||||
@ -105,16 +105,18 @@ describe('Block Service', function() {
|
|||||||
sandbox.restore();
|
sandbox.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should find the common ancestor between the current chain and the new chain', function() {
|
it('should find the common ancestor between the current chain and the new chain', function(done) {
|
||||||
var block = { hash: 'cc' };
|
|
||||||
blockService._tip = { hash: 'bb' }
|
blockService._header = { getAllHeaders: sinon.stub().returns({}) };
|
||||||
blockService._blockQueue = new LRU(5);
|
blockService._db = { get: sinon.stub() };
|
||||||
blockService._blockQueue.set('aa', { prevHash: '00' });
|
blockService._chainTips = ['aa', 'bb'];
|
||||||
blockService._blockQueue.set('bb', { prevHash: 'aa' });
|
blockService._tip = { hash: 'aa' };
|
||||||
blockService._blockQueue.set('cc', { prevHash: 'aa' });
|
sandbox.stub(blockService, '_getOldBlocks').returns([]);
|
||||||
blockService._chainTips = [ 'cc', 'bb' ];
|
|
||||||
var commonAncestor = blockService._findCommonAncestor(block);
|
blockService._findCommonAncestor('cc');
|
||||||
expect(commonAncestor).to.equal('aa');
|
blockService.on('common ancestor', function() {
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -142,19 +144,19 @@ describe('Block Service', function() {
|
|||||||
describe('#_getBlockOperations', function() {
|
describe('#_getBlockOperations', function() {
|
||||||
|
|
||||||
it('should get block operations when given one block', function() {
|
it('should get block operations when given one block', function() {
|
||||||
var block = new Block(new Buffer('0100000095194b8567fe2e8bbda931afd01a7acd399b9325cb54683e64129bcd00000000660802c98f18fd34fd16d61c63cf447568370124ac5f3be626c2e1c3c9f0052d19a76949ffff001d33f3c25d0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d014dffffffff0100f2052a01000000434104e70a02f5af48a1989bf630d92523c9d14c45c75f7d1b998e962bff6ff9995fc5bdb44f1793b37495d80324acba7c8f537caaf8432b8d47987313060cc82d8a93ac00000000', 'hex'));
|
var block = Block.fromRaw('0100000095194b8567fe2e8bbda931afd01a7acd399b9325cb54683e64129bcd00000000660802c98f18fd34fd16d61c63cf447568370124ac5f3be626c2e1c3c9f0052d19a76949ffff001d33f3c25d0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d014dffffffff0100f2052a01000000434104e70a02f5af48a1989bf630d92523c9d14c45c75f7d1b998e962bff6ff9995fc5bdb44f1793b37495d80324acba7c8f537caaf8432b8d47987313060cc82d8a93ac00000000', 'hex');
|
||||||
var ops = blockService._getBlockOperations(block);
|
var ops = blockService._getBlockOperations(block);
|
||||||
|
|
||||||
expect(ops[0]).to.deep.equal({ type: 'put', key: blockService._encoding.encodeBlockKey(block.hash), value: blockService._encoding.encodeBlockValue(block) });
|
expect(ops[0]).to.deep.equal({ type: 'put', key: blockService._encoding.encodeBlockKey(block.rhash()), value: blockService._encoding.encodeBlockValue(block) });
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get block operations when given more than one block', function() {
|
it('should get block operations when given more than one block', function() {
|
||||||
var block = new Block(new Buffer('0100000095194b8567fe2e8bbda931afd01a7acd399b9325cb54683e64129bcd00000000660802c98f18fd34fd16d61c63cf447568370124ac5f3be626c2e1c3c9f0052d19a76949ffff001d33f3c25d0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d014dffffffff0100f2052a01000000434104e70a02f5af48a1989bf630d92523c9d14c45c75f7d1b998e962bff6ff9995fc5bdb44f1793b37495d80324acba7c8f537caaf8432b8d47987313060cc82d8a93ac00000000', 'hex'));
|
var block = Block.fromRaw('0100000095194b8567fe2e8bbda931afd01a7acd399b9325cb54683e64129bcd00000000660802c98f18fd34fd16d61c63cf447568370124ac5f3be626c2e1c3c9f0052d19a76949ffff001d33f3c25d0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d014dffffffff0100f2052a01000000434104e70a02f5af48a1989bf630d92523c9d14c45c75f7d1b998e962bff6ff9995fc5bdb44f1793b37495d80324acba7c8f537caaf8432b8d47987313060cc82d8a93ac00000000', 'hex');
|
||||||
var ops = blockService._getBlockOperations([block, block]);
|
var ops = blockService._getBlockOperations([block, block]);
|
||||||
|
|
||||||
expect(ops[0]).to.deep.equal({ type: 'put', key: blockService._encoding.encodeBlockKey(block.hash), value: blockService._encoding.encodeBlockValue(block) });
|
expect(ops[0]).to.deep.equal({ type: 'put', key: blockService._encoding.encodeBlockKey(block.rhash()), value: blockService._encoding.encodeBlockValue(block) });
|
||||||
expect(ops[1]).to.deep.equal({ type: 'put', key: blockService._encoding.encodeBlockKey(block.hash), value: blockService._encoding.encodeBlockValue(block) });
|
expect(ops[1]).to.deep.equal({ type: 'put', key: blockService._encoding.encodeBlockKey(block.rhash()), value: blockService._encoding.encodeBlockValue(block) });
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -165,19 +167,6 @@ describe('Block Service', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#_getChainwork', function() {
|
|
||||||
|
|
||||||
it('should get chainwork', function() {
|
|
||||||
var expected = new BN(new Buffer('000000000000000000000000000000000000000000677c7b8122f9902c79f4e0', 'hex'));
|
|
||||||
blockService._meta = [ { chainwork: '000000000000000000000000000000000000000000677bd68118a98f8779ea90', hash: 'aa' } ];
|
|
||||||
blockService._blockQueue = LRU(1);
|
|
||||||
blockService._blockQueue.set('bb', { header: { bits: 0x18018d30 }});
|
|
||||||
var actual = blockService._getChainwork('bb');
|
|
||||||
assert(actual.eq(expected), 'not equal: actual: ' + actual + ' expected: ' + expected);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#_getDelta', function() {
|
describe('#_getDelta', function() {
|
||||||
|
|
||||||
var sandbox;
|
var sandbox;
|
||||||
@ -191,17 +180,25 @@ describe('Block Service', function() {
|
|||||||
|
|
||||||
it('should get all unsent blocks for the active chain', function() {
|
it('should get all unsent blocks for the active chain', function() {
|
||||||
|
|
||||||
var block1 = { header: { prevHash: new Buffer('00', 'hex') }};
|
var toJSON1 = sinon.stub().returns({ prevBlock: 'bb' });
|
||||||
var block2 = { header: { prevHash: new Buffer('aa', 'hex') }};
|
var toJSON2 = sinon.stub().returns({ prevBlock: 'aa' });
|
||||||
var block3 = { header: { prevHash: new Buffer('bb', 'hex') }};
|
var toJSON3 = sinon.stub().returns({ prevBlock: '00' });
|
||||||
var expected = [ block2, block3 ];
|
var blocks = [
|
||||||
|
{ toHeaders: sinon.stub().returns({ toJSON: toJSON3 }) },
|
||||||
|
{ toHeaders: sinon.stub().returns({ toJSON: toJSON2 }) },
|
||||||
|
{ toHeaders: sinon.stub().returns({ toJSON: toJSON1 }) }
|
||||||
|
];
|
||||||
|
var get = sandbox.stub();
|
||||||
|
get.onCall(0).returns(blocks[2]);
|
||||||
|
get.onCall(1).returns(blocks[1]);
|
||||||
|
blockService._blockQueue = { get: get };
|
||||||
|
|
||||||
|
|
||||||
|
var expected = [ blocks[1], blocks[2] ];
|
||||||
blockService._tip = { hash: 'aa' };
|
blockService._tip = { hash: 'aa' };
|
||||||
blockService._blockQueue = LRU(3);
|
|
||||||
blockService._blockQueue.set('aa', block1);
|
|
||||||
blockService._blockQueue.set('bb', block2);
|
|
||||||
blockService._blockQueue.set('cc', block3);
|
|
||||||
var actual = blockService._getDelta('cc');
|
var actual = blockService._getDelta('cc');
|
||||||
expect(actual).to.deep.equal(expected);
|
expect(actual).to.deep.equal(expected);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -211,14 +208,16 @@ describe('Block Service', function() {
|
|||||||
describe('#_isChainReorganizing', function() {
|
describe('#_isChainReorganizing', function() {
|
||||||
|
|
||||||
it('should decide that chain is reorging', function() {
|
it('should decide that chain is reorging', function() {
|
||||||
|
var toJSON = sinon.stub().returns({ prevBlock: 'bb' });
|
||||||
|
var block = { toHeaders: sinon.stub().returns({ toJSON: toJSON }) };
|
||||||
blockService._tip = { hash: 'aa' };
|
blockService._tip = { hash: 'aa' };
|
||||||
var block = { header: { prevHash: new Buffer('00', 'hex') }};
|
|
||||||
expect(blockService._isChainReorganizing(block)).to.be.true;
|
expect(blockService._isChainReorganizing(block)).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should decide that chain is not reorging', function() {
|
it('should decide that chain is not reorging', function() {
|
||||||
|
var toJSON = sinon.stub().returns({ prevBlock: 'aa' });
|
||||||
|
var block = { toHeaders: sinon.stub().returns({ toJSON: toJSON }) };
|
||||||
blockService._tip = { hash: 'aa' };
|
blockService._tip = { hash: 'aa' };
|
||||||
var block = { header: { prevHash: new Buffer('aa', 'hex') }};
|
|
||||||
expect(blockService._isChainReorganizing(block)).to.be.false;
|
expect(blockService._isChainReorganizing(block)).to.be.false;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -226,67 +225,39 @@ describe('Block Service', function() {
|
|||||||
|
|
||||||
describe('#_isOutOfOrder', function() {
|
describe('#_isOutOfOrder', function() {
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
var prevHash = '00000000';
|
|
||||||
for(var i = 0; i < 110; i++) {
|
|
||||||
var newHash = crypto.randomBytes(4);
|
|
||||||
var mock = { toBuffer: function() { return new Buffer(new Array(10), 'hex') } };
|
|
||||||
blockService._blockQueue.set(newHash, mock);
|
|
||||||
prevHash = newHash;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should detect an orphaned block', function() {
|
it('should detect an orphaned block', function() {
|
||||||
var block = { hash: 'ee', header: { prevHash: new Buffer('aa', 'hex') }};
|
blockService._chainTips = [ 'cc', 'dd' ];
|
||||||
|
var toJSON = sinon.stub().returns({ prevBlock: 'aa' });
|
||||||
|
var block = { toHeaders: sinon.stub().returns({ toJSON: toJSON }) };
|
||||||
expect(blockService._isOutOfOrder(block)).to.be.true;
|
expect(blockService._isOutOfOrder(block)).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not detect an orphaned block', function() {
|
it('should not detect an orphaned block', function() {
|
||||||
var block = { hash: 'new', header: { prevHash: '00' }};
|
var toJSON = sinon.stub().returns({ prevBlock: 'cc' });
|
||||||
|
var block = { toHeaders: sinon.stub().returns({ toJSON: toJSON }) };
|
||||||
expect(blockService._isOutOfOrder(block)).to.be.true;
|
expect(blockService._isOutOfOrder(block)).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe.only('#_onBlock', function() {
|
||||||
describe('#_onBestHeight', function() {
|
|
||||||
var sandbox;
|
|
||||||
beforeEach(function() {
|
|
||||||
sandbox = sinon.sandbox.create();
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function() {
|
|
||||||
sandbox.restore();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set best height', function() {
|
|
||||||
var startSync = sandbox.stub(blockService, '_startSync');
|
|
||||||
blockService._onBestHeight(123);
|
|
||||||
expect(blockService._bestHeight).to.equal(123);
|
|
||||||
expect(startSync.calledOnce).to.be.true;
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#_onBlock', function() {
|
|
||||||
|
|
||||||
it('should perform all the steps for onBlock handler (normal)', function() {
|
it('should perform all the steps for onBlock handler (normal)', function() {
|
||||||
|
|
||||||
var sandbox = sinon.sandbox.create();
|
var sandbox = sinon.sandbox.create();
|
||||||
var alreadyProcessed = sandbox.stub(blockService, '_blockAlreadyProcessed').returns(false);
|
var alreadyProcessed = sandbox.stub(blockService, '_blockAlreadyProcessed').returns(false);
|
||||||
var cacheBlock = sandbox.stub(blockService, '_cacheBlock');
|
var cacheBlock = sandbox.stub(blockService, '_cacheBlock');
|
||||||
var blockState = sandbox.stub(blockService, '_determineBlockState').returns('normal');
|
var blockState = sandbox.stub(blockService, '_determineBlockState').returns('normal');
|
||||||
var updateChainTips = sandbox.stub(blockService, '_updateChainInfo');
|
var updateChainTips = sandbox.stub(blockService, '_updateChainInfo');
|
||||||
var sendAllUnsent = sandbox.stub(blockService, '_sendDelta');
|
var sendAllUnsent = sandbox.stub(blockService, '_sendDelta');
|
||||||
var saveMetaData = sandbox.stub(blockService, '_saveMetaData');
|
|
||||||
|
|
||||||
blockService._onBlock({ hash: 'aa' });
|
var rhash = sinon.stub().returns('aa');
|
||||||
|
var block = { rhash: rhash };
|
||||||
|
|
||||||
|
blockService._onBlock(block);
|
||||||
expect(alreadyProcessed.callCount).to.equal(1);
|
expect(alreadyProcessed.callCount).to.equal(1);
|
||||||
expect(cacheBlock.callCount).to.equal(1);
|
expect(cacheBlock.callCount).to.equal(1);
|
||||||
expect(blockState.callCount).to.equal(1);
|
expect(blockState.callCount).to.equal(1);
|
||||||
expect(updateChainTips.callCount).to.equal(1);
|
expect(updateChainTips.callCount).to.equal(1);
|
||||||
expect(sendAllUnsent.callCount).to.equal(1);
|
expect(sendAllUnsent.callCount).to.equal(1);
|
||||||
expect(saveMetaData.callCount).to.equal(1);
|
|
||||||
|
|
||||||
sandbox.restore();
|
sandbox.restore();
|
||||||
|
|
||||||
@ -295,7 +266,10 @@ describe('Block Service', function() {
|
|||||||
it('should perform all the steps for onBlock handler (reorg)', function() {
|
it('should perform all the steps for onBlock handler (reorg)', function() {
|
||||||
|
|
||||||
var sandbox = sinon.sandbox.create();
|
var sandbox = sinon.sandbox.create();
|
||||||
var block = { hash: 'aa' };
|
|
||||||
|
var rhash = sinon.stub().returns('aa');
|
||||||
|
var block = { rhash: rhash };
|
||||||
|
|
||||||
var alreadyProcessed = sandbox.stub(blockService, '_blockAlreadyProcessed').returns(false);
|
var alreadyProcessed = sandbox.stub(blockService, '_blockAlreadyProcessed').returns(false);
|
||||||
var cacheBlock = sandbox.stub(blockService, '_cacheBlock');
|
var cacheBlock = sandbox.stub(blockService, '_cacheBlock');
|
||||||
var blockState = sandbox.stub(blockService, '_determineBlockState').returns('reorg');
|
var blockState = sandbox.stub(blockService, '_determineBlockState').returns('reorg');
|
||||||
|
|||||||
@ -134,6 +134,19 @@ describe('Header Service', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('#_getChainwork', function() {
|
||||||
|
|
||||||
|
it('should get chainwork', function() {
|
||||||
|
var expected = new BN(new Buffer('000000000000000000000000000000000000000000677c7b8122f9902c79f4e0', 'hex'));
|
||||||
|
headerService._meta = [ { chainwork: '000000000000000000000000000000000000000000677bd68118a98f8779ea90', hash: 'aa' } ];
|
||||||
|
headerService._blockQueue = LRU(1);
|
||||||
|
headerService._blockQueue.set('bb', { header: { bits: 0x18018d30 }});
|
||||||
|
var actual = headerService._getChainwork('bb');
|
||||||
|
assert(actual.eq(expected), 'not equal: actual: ' + actual + ' expected: ' + expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
describe('#_computeChainwork', function() {
|
describe('#_computeChainwork', function() {
|
||||||
|
|
||||||
it('should calculate chain work correctly', function() {
|
it('should calculate chain work correctly', function() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user