diff --git a/lib/services/address/index.js b/lib/services/address/index.js index 3fa76970..1084fd1a 100644 --- a/lib/services/address/index.js +++ b/lib/services/address/index.js @@ -113,8 +113,8 @@ AddressService.prototype.getAddressSummary = function(address, options, callback var txStream = new Transform({ objectMode: true, highWaterMark: 1000 }); txStream.on('end', function() { - result.balance = result.balanceSat; - result.totalReceived = result.totalReceivedSat; + result.balance = Unit.fromSatoshis(result.balanceSat).toBTC(); + result.totalReceived = Unit.fromSatoshis(result.totalReceivedSat).toBTC(); result.totalSent = result.totalSentSat; result.unconfirmedBalance = result.unconfirmedBalanceSat; callback(null, result); diff --git a/lib/services/block/index.js b/lib/services/block/index.js index 37f5e208..376e951b 100644 --- a/lib/services/block/index.js +++ b/lib/services/block/index.js @@ -592,6 +592,7 @@ BlockService.prototype._sync = function() { var self = this; + if (self.node.stopping) { return; } diff --git a/lib/services/fee/index.js b/lib/services/fee/index.js index 45d0b7b8..28434b28 100644 --- a/lib/services/fee/index.js +++ b/lib/services/fee/index.js @@ -39,15 +39,21 @@ FeeService.prototype.getAPIMethods = function() { }; FeeService.prototype.estimateFee = function(blocks, callback) { + this._client.estimateFee(blocks || 4, function(err, res) { + if (err) { return callback(err); } + if (!res) { callback(); } + callback(null, res.result); + }); + }; module.exports = FeeService; diff --git a/package-lock.json b/package-lock.json index 8b8bb6b7..120a5bd4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2305,6 +2305,15 @@ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, + "memwatch-next": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/memwatch-next/-/memwatch-next-0.3.0.tgz", + "integrity": "sha1-IREFD5qQbgqi1ypOwPAInHhyb48=", + "requires": { + "bindings": "1.2.1", + "nan": "2.6.2" + } + }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", diff --git a/test/services/address/index.unit.js b/test/services/address/index.unit.js index 2eb331d4..f7570a40 100644 --- a/test/services/address/index.unit.js +++ b/test/services/address/index.unit.js @@ -7,11 +7,12 @@ var expect = require('chai').expect; var Encoding = require('../../../lib/services/address/encoding'); var Readable = require('stream').Readable; var EventEmitter = require('events').EventEmitter; -var utils = require('../../../lib/utils'); +var bcoin = require('bcoin'); describe('Address Service', function() { var tx = Tx.fromRaw( '0100000004de9b4bb17f627096a9ee0b4528e4eae17df5b5c69edc29704c2e84a7371db29f010000006b483045022100f5b1a0d33b7be291c3953c25f8ae39d98601aa7099a8674daf638a08b86c7173022006ce372da5ad088a1cc6e5c49c2760a1b6f085eb1b51b502211b6bc9508661f9012102ec5e3731e54475dd2902326f43602a03ae3d62753324139163f81f20e787514cffffffff7a1d4e5fc2b8177ec738cd723a16cf2bf493791e55573445fc0df630fe5e2d64010000006b483045022100cf97f6cb8f126703e9768545dfb20ffb10ba78ae3d101aa46775f5a239b075fc02203150c4a89a11eaf5e404f4f96b62efa4455e9525765a025525c7105a7e47b6db012102c01e11b1d331f999bbdb83e8831de503cd52a01e3834a95ccafd615c67703d77ffffffff9e52447116415ca0d0567418a1a4ef8f27be3ff5a96bf87c922f3723d7db5d7c000000006b483045022100f6c117e536701be41a6b0b544d7c3b1091301e4e64a6265b6eb167b15d16959d022076916de4b115e700964194ce36a24cb9105f86482f4abbc63110c3f537cd5770012102ddf84cc7bee2d6a82ac09628a8ad4a26cd449fc528b81e7e6cc615707b8169dfffffffff5815d9750eb3572e30d6fd9df7afb4dbd76e042f3aa4988ac763b3fdf8397f80010000006a473044022028f4402b736066d93d2a32b28ccd3b7a21d84bb58fcd07fe392a611db94cdec5022018902ee0bf2c3c840c1b81ead4e6c87c88c48b2005bf5eea796464e561a620a8012102b6cdd1a6cd129ef796faeedb0b840fcd0ca00c57e16e38e46ee7028d59812ae7ffffffff0220a10700000000001976a914c342bcd1a7784d9842f7386b8b3b8a3d4171a06e88ac59611100000000001976a91449f8c749a9960dc29b5cbe7d2397cea7d26611bb88ac00000000', 'hex'); + var blocks = require('../../regtest/data/blocks.json'); var addressService; var sandbox; @@ -33,11 +34,10 @@ describe('Address Service', function() { describe('#start', function() { it('should get prefix for database', function(done) { - var startSubs = sandbox.stub(addressService, '_startSubscriptions'); var getPrefix = sandbox.stub().callsArgWith(1, null, new Buffer('ffee', 'hex')); addressService._db = { getPrefix: getPrefix }; addressService.start(function() { - expect(startSubs.calledOnce).to.be.true; + expect(getPrefix.calledOnce).to.be.true; done(); }); }); @@ -119,7 +119,7 @@ describe('Address Service', function() { tx.__inputValues = inputValues; var getTransaction = sandbox.stub().callsArgWith(2, null, tx); addressService._tx = { getTransaction: getTransaction }; - addressService._p2p = { getBestHeight: function() { return 150; } }; + addressService._header = { getBestHeight: function() { return 150; } }; var txidStream = new Readable(); @@ -169,7 +169,7 @@ describe('Address Service', function() { value: encoding.encodeUtxoIndexValue(123, 120000, ts, tx.outputs[1].script.raw) }; - addressService._p2p = { getBestHeight: function() { return 150; } }; + addressService._header = { getBestHeight: function() { return 150; } }; var txidStream = new EventEmitter(); @@ -201,23 +201,23 @@ describe('Address Service', function() { }); - describe('#_onReorg', function() { + describe('#onReorg', function() { + + it('should reorg', function(done ) { + + var commonAncestorHeader = bcoin.block.fromRaw(blocks[5], 'hex').toHeaders().toJSON(); + var oldBlocks = [bcoin.block.fromRaw(blocks[6], 'hex')]; + + addressService.onReorg([commonAncestorHeader, oldBlocks], function(err, ops) { + + expect(ops.length).to.equal(1); + expect(ops[0].type).to.equal('del'); + + done(); + + + }); - it('should reorg', function() { - var getAddressString = sandbox.stub().returns('a'); - var oldEncodeTip = utils.encodeTip; - var encodeTip = sandbox.stub().returns({ key: 'key', value: 'value' }); - var batch = sandbox.stub(); - addressService._tip = { height: 100 }; - addressService._db = { batch: batch }; - utils.getAddressString = getAddressString; - utils.encodeTip = encodeTip; - var common = { height: 99 }; - var oldList = []; - addressService._onReorg(oldList, common); - expect(batch.calledOnce).to.be.true; - expect(encodeTip.calledOnce).to.be.true; - utils.encodeTip = oldEncodeTip; }); }); diff --git a/test/services/block/index.unit.js b/test/services/block/index.unit.js index aaed646d..d2225727 100644 --- a/test/services/block/index.unit.js +++ b/test/services/block/index.unit.js @@ -3,12 +3,16 @@ var expect = require('chai').expect; var BlockService = require('../../../lib/services/block'); var sinon = require('sinon'); -var Block = require('bcoin').block; +var bcoin = require('bcoin'); +var Block = bcoin.block; var Encoding = require('../../../lib/services/block/encoding'); describe('Block Service', function() { var blockService; + var blocks = require('../../regtest/data/blocks.json'); + var block1 = Block.fromRaw('010000006a39821735ec18a366d95b391a7ff10dee181a198f1789b0550e0d00000000002b0c80fa52b669022c344c3e09e6bb9698ab90707bb4bb412af3fbf31cfd2163a601514c5a0c011c572aef0f0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08045a0c011c022003ffffffff0100f2052a01000000434104c5b694d72e601091fd733c6b18b94795c13e2db6b1474747e7be914b407854cad37cee3058f85373b9f9dbb0014e541c45851d5f85e83a1fd7c45e54423718f3ac00000000', 'hex'); + var block2 = Block.fromRaw('01000000fb3c5deea3902d5e6e0222435688795152ae0f737715b0bed6a88b00000000008ec0f92d33b05617cb3c3b4372aa0c2ae3aeb8aa7f34fe587db8e55b578cfac6b601514c5a0c011c98a831000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08045a0c011c027f01ffffffff0100f2052a0100000043410495fee5189566db550919ad2b4e5f9111dbdc2cb60b5c71ea4c0fdad59a961c42eb289e5b9fdc4cb3f3fec6dd866172720bae3e3b881fc203fcaf98bf902c53f1ac00000000', 'hex'); var sandbox; beforeEach(function() { @@ -28,35 +32,36 @@ describe('Block Service', function() { describe('#_detectReorg', function() { it('should detect reorg', function() { - var toJSON = { toJSON: sandbox.stub().returns({ prevBlock: 'aa' }) }; - var toHeaders = sandbox.stub().returns(toJSON); - var block = { toHeaders: toHeaders }; - blockService._tip = { hash: 'aa' }; - var res = blockService._detectReorg(block); - expect(res).to.be.false; + var block = Block.fromRaw(blocks[6], 'hex'); + blockService._tip = { hash: bcoin.util.revHex(Block.fromRaw(blocks[5], 'hex').prevBlock) }; + expect(blockService._detectReorg(block)).to.be.true; + }); + + it('should not detect reorg', function() { + var block = Block.fromRaw(blocks[6], 'hex'); + blockService._tip = { hash: bcoin.util.revHex(Block.fromRaw(blocks[6], 'hex').prevBlock) }; + expect(blockService._detectReorg(block)).to.be.false; }); }); describe('#_findCommonAncestor', function() { + it('should find the common ancestor between the current chain and the new chain', function(done) { - var block1 = Block.fromRaw('010000006a39821735ec18a366d95b391a7ff10dee181a198f1789b0550e0d00000000002b0c80fa52b669022c344c3e09e6bb9698ab90707bb4bb412af3fbf31cfd2163a601514c5a0c011c572aef0f0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08045a0c011c022003ffffffff0100f2052a01000000434104c5b694d72e601091fd733c6b18b94795c13e2db6b1474747e7be914b407854cad37cee3058f85373b9f9dbb0014e541c45851d5f85e83a1fd7c45e54423718f3ac00000000', 'hex'); - var block2 = Block.fromRaw('01000000fb3c5deea3902d5e6e0222435688795152ae0f737715b0bed6a88b00000000008ec0f92d33b05617cb3c3b4372aa0c2ae3aeb8aa7f34fe587db8e55b578cfac6b601514c5a0c011c98a831000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08045a0c011c027f01ffffffff0100f2052a0100000043410495fee5189566db550919ad2b4e5f9111dbdc2cb60b5c71ea4c0fdad59a961c42eb289e5b9fdc4cb3f3fec6dd866172720bae3e3b881fc203fcaf98bf902c53f1ac00000000', 'hex'); blockService._tip = { hash: block2.rhash(), height: 70901 }; + var encodedData = blockService._encoding.encodeBlockValue(block2); + var get = sandbox.stub().callsArgWith(1, null, encodedData); var headers = { get: sandbox.stub().returns({ prevHash: block1.rhash() }) }; blockService._db = { get: get }; - var getOldBlocks = sandbox.stub(blockService, '_getOldBlocks').callsArgWith(1, null, []); - blockService._findCommonAncestor('aa', headers, function(err, hash, common, oldBlocks) { + blockService._findCommonAncestor('aa', headers, function(err, common, oldBlocks) { if (err) { return done(err); } - expect(get.calledOnce).to.be.true; - expect(getOldBlocks.calledOnce).to.be.true; - expect(common).to.equal(block1.rhash()); + expect(common).to.equal('aa'); expect(oldBlocks).to.deep.equal([]); done(); }); @@ -93,34 +98,18 @@ describe('Block Service', function() { describe('#_onBlock', function() { - it('should perform all the steps for onBlock handler (normal)', function() { - var rhash = sinon.stub().returns('aa'); - var block = { rhash: rhash }; - var getAllHeaders = sandbox.stub().returns({}); - var detectReorg = sandbox.stub(blockService, '_detectReorg').returns(false); + it('should process blocks', function() { var processBlock = sandbox.stub(blockService, '_processBlock'); - blockService._unprocessedBlocks = []; - blockService._header = { getAllHeaders: getAllHeaders }; - blockService._tip = { height: 123 }; - blockService._onBlock(block, { height: 124 }); - expect(detectReorg.callCount).to.equal(1); - expect(processBlock.callCount).to.equal(1); + blockService._tip = { hash: block1.rhash(), height: 1 }; + blockService._onBlock(block2); + expect(processBlock.calledOnce).to.be.true; }); - it('should perform all the steps for onBlock handler (reorg)', function() { - var rhash = sinon.stub().returns('aa'); - var block = { rhash: rhash }; - var getAllHeaders = sandbox.stub().returns({}); - var detectReorg = sandbox.stub(blockService, '_detectReorg').returns(true); + it('should not process blocks', function() { var processBlock = sandbox.stub(blockService, '_processBlock'); - var handleReorg = sandbox.stub(blockService, '_handleReorg'); - blockService._unprocessedBlocks = []; - blockService._header = { getAllHeaders: getAllHeaders }; - blockService._tip = { height: 123 }; - blockService._onBlock(block, { height: 124 }); - expect(handleReorg.callCount).to.equal(1); - expect(detectReorg.callCount).to.equal(1); - expect(processBlock.callCount).to.equal(0); + blockService._tip = { hash: block2.rhash(), height: 1 }; + blockService._onBlock(block1); + expect(processBlock.calledOnce).to.be.false; }); }); @@ -164,27 +153,15 @@ describe('Block Service', function() { }); describe('#_startSync', function() { + it('should start the sync of blocks if type set', function() { + blockService._header = { getLastHeader: sinon.stub.returns({ height: 100 }) }; + blockService._tip = { height: 98 }; var sync = sandbox.stub(blockService, '_sync'); - blockService._bestHeight = 100; - blockService._tip = { height: 99 }; - blockService._header = { getAllHeaders: sinon.stub().returns({ size: 100 }) }; blockService._startSync(); expect(sync.calledOnce).to.be.true; - expect(blockService._numNeeded).to.equal(1); }); - }); - describe('#_sync', function() { - it('should sync blocks', function() { - var getAllHeaders = sandbox.stub().returns({ size: 1000, getIndex: sinon.stub() }); - var getBlocks = sandbox.stub(); - blockService._tip = { height: 99 }; - blockService._header = { getAllHeaders: getAllHeaders }; - blockService._p2p = { getBlocks: getBlocks }; - blockService._sync(); - expect(getBlocks.calledOnce).to.be.true; - }); }); describe('#start', function() { diff --git a/test/services/fee/index.unit.js b/test/services/fee/index.unit.js index 8b1757a7..50ccf96e 100644 --- a/test/services/fee/index.unit.js +++ b/test/services/fee/index.unit.js @@ -39,11 +39,14 @@ describe('#Fee Service', function() { var estimateFee = sinon.stub().callsArgWith(1, null, { result: 0.1 }); feeService._client = { estimateFee: estimateFee }; feeService.estimateFee(4, function(err, fee) { + if (err) { return done(err); } - expect(fee.result).to.equal(0.1); + + expect(fee).to.equal(0.1); done(); + }); }); diff --git a/test/services/header/encoding.unit.js b/test/services/header/encoding.unit.js index 5fcd7210..2a475db5 100644 --- a/test/services/header/encoding.unit.js +++ b/test/services/header/encoding.unit.js @@ -7,6 +7,9 @@ var Encoding = require('../../../lib/services/header/encoding'); describe('Header service encoding', function() { var servicePrefix = new Buffer('0000', 'hex'); + + var hashPrefix = new Buffer('00', 'hex'); + var heightPrefix = new Buffer('01', 'hex'); var encoding = new Encoding(servicePrefix); var hash = '91b58f19b6eecba94ed0f6e463e8e334ec0bcda7880e2985c82a8f32e4d03add'; var hashBuf = new Buffer(hash, 'hex'); @@ -31,15 +34,23 @@ describe('Header service encoding', function() { var chainBuf = new Buffer('0000000000000000000000000000000000000000000000000000000200020002', 'hex'); heightBuf.writeUInt32BE(header.height); - it('should encode header key' , function() { - encoding.encodeHeaderKey(header.height, hash).should.deep.equal(Buffer.concat([servicePrefix, heightBuf, hashBuf])); + it('should encode header hash key' , function() { + encoding.encodeHeaderHashKey(hash).should.deep.equal(Buffer.concat([servicePrefix, hashPrefix, hashBuf])); }); - it('should decode header key', function() { - encoding.decodeHeaderKey(Buffer.concat([servicePrefix, heightBuf, hashBuf])) - .should.deep.equal({ height: 123, hash: hash }); + it('should decode header hash key', function() { + encoding.decodeHeaderHashKey(Buffer.concat([servicePrefix, hashPrefix, hashBuf])) + .should.deep.equal(hash); }); + it('should encode header height key' , function() { + encoding.encodeHeaderHeightKey(header.height).should.deep.equal(Buffer.concat([servicePrefix, heightPrefix, heightBuf])); + }); + + it('should decode header height key', function() { + encoding.decodeHeaderHeightKey(Buffer.concat([servicePrefix, heightPrefix, heightBuf])) + .should.deep.equal(header.height); + }); it('should encode header value', function() { var prevHashBuf = new Buffer(header.prevHash, 'hex'); versionBuf.writeInt32BE(header.version); // signed diff --git a/test/services/header/index.unit.js b/test/services/header/index.unit.js index bc603c4f..4ff052c7 100644 --- a/test/services/header/index.unit.js +++ b/test/services/header/index.unit.js @@ -9,13 +9,15 @@ var Encoding = require('../../../lib/services/header/encoding'); var utils = require('../../../lib/utils'); var Block = require('bitcore-lib').Block; var BN = require('bn.js'); +var Emitter = require('events').EventEmitter; describe('Header Service', function() { var headerService; var sandbox; var prevHeader = new Block(new Buffer('01000000b25c0849b469983b4a5b90a49e4c0e4ba3853122ed141b5bd92d14000000000021a8aaa4995e4ce3b885677730b153741feda66a08492287a45c6a131671ba5a72ff504c5a0c011c456e4d060201000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08045a0c011c028208ffffffff0100f2052a010000004341041994d910507ec4b2135dd32a4723caf00f8567f356ffbd5e703786d856b49a89d6597c280d8981238fbde81fa3767161bc3e994c17be41b42235a61c24c73459ac0000000001000000013b517d1aebd89b4034e0cf9b25ecbe82ef162ce71284e92a1f1adebf44ea1409000000008b483045022100c7ebc62e89740ddab42a64435c996e1c91a063f9f2cc004b4f023f7a1be5234402207608837faebec16049461d4ef7de807ce217040fd2a823a29da16ec07e463d440141048f108c0da4b5be3308e2e0b521d02d341de85b36a29285b47f00bc33e57a89cf4b6e76aa4a48ddc9a5e882620779e0f1b19dc98d478052fbd544167c745be1d8ffffffff010026e85a050000001976a914f760ef90462b0a4bde26d597c1f29324f5cd0fc488ac00000000', 'hex')).header.toObject(); - var header = new Block(new Buffer('010000006a39821735ec18a366d95b391a7ff10dee181a198f1789b0550e0d00000000002b0c80fa52b669022c344c3e09e6bb9698ab90707bb4bb412af3fbf31cfd2163a601514c5a0c011c572aef0f0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08045a0c011c022003ffffffff0100f2052a01000000434104c5b694d72e601091fd733c6b18b94795c13e2db6b1474747e7be914b407854cad37cee3058f85373b9f9dbb0014e541c45851d5f85e83a1fd7c45e54423718f3ac00000000', 'hex')).header.toObject(); + var preObjectHeader = new Block(new Buffer('010000006a39821735ec18a366d95b391a7ff10dee181a198f1789b0550e0d00000000002b0c80fa52b669022c344c3e09e6bb9698ab90707bb4bb412af3fbf31cfd2163a601514c5a0c011c572aef0f0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08045a0c011c022003ffffffff0100f2052a01000000434104c5b694d72e601091fd733c6b18b94795c13e2db6b1474747e7be914b407854cad37cee3058f85373b9f9dbb0014e541c45851d5f85e83a1fd7c45e54423718f3ac00000000', 'hex')).header; + var header = preObjectHeader.toObject(); beforeEach(function() { sandbox = sinon.sandbox.create(); headerService = new HeaderService({ @@ -37,18 +39,19 @@ describe('Header Service', function() { it('should get prefix for database', function(done) { var getServiceTip = sandbox.stub().callsArgWith(1, null, { height: 123, hash: 'a' }); - var startSubs = sandbox.stub(headerService, '_startSubscriptions'); var setListeners = sandbox.stub(headerService, '_setListeners'); var getPrefix = sandbox.stub().callsArgWith(1, null, new Buffer('ffee', 'hex')); - var getPersistedHeaders = sandbox.stub(headerService, '_getPersistedHeaders') - .callsArgWith(0, null, sinon.stub()); + var getLastHeader = sandbox.stub(headerService, '_getLastHeader').callsArgWith(0, null); + var openBus = sandbox.stub(); + headerService.node = { openBus: openBus }; + var _startHeaderSubscription = sandbox.stub(headerService, '_startHeaderSubscription'); - headerService._db = { getPrefix: getPrefix, getServiceTip: getServiceTip }; + headerService._db = { getPrefix: getPrefix, getServiceTip: getServiceTip, batch: sinon.stub() }; headerService.start(function() { - expect(startSubs.calledOnce).to.be.true; + expect(_startHeaderSubscription.calledOnce).to.be.true; + expect(getLastHeader.calledOnce).to.be.true; expect(setListeners.calledOnce).to.be.true; - expect(getPersistedHeaders.calledOnce).to.be.true; expect(headerService._tip).to.be.deep.equal({ height: 123, hash: 'a' }); expect(headerService._encoding).to.be.instanceOf(Encoding); done(); @@ -68,10 +71,27 @@ describe('Header Service', function() { describe('#getAllHeaders', function() { - it('should get all the headers', function() { - headerService._headers = {}; - var headers = headerService.getAllHeaders(); - expect(headers).to.deep.equal({}); + it('should get all the headers', function(done) { + headerService._tip = { height: 123 }; + + var fakeStream = new Emitter(); + var createReadStream = sandbox.stub().returns(fakeStream); + headerService._db = { createReadStream: createReadStream }; + + headerService.getAllHeaders(function(err, headers) { + if (err) { + return done(err); + } + + expect(headers.length).to.deep.equal(1); + expect(headers.get(header.hash).hash).to.equal('00000000008ba8d6beb01577730fae52517988564322026e5e2d90a3ee5d3cfb'); + done(); + }); + + header.chainwork = '00'; + fakeStream.emit('data', { value: headerService._encoding.encodeHeaderValue(header) }); + fakeStream.emit('end'); + }); }); @@ -79,12 +99,11 @@ describe('Header Service', function() { it('should start the sync process', function() { headerService._bestHeight = 123; - headerService._checkpoint = 8888; - headerService._tip = { height: 121, hash: 'a' }; - var sync = sandbox.stub(headerService, '_sync'); + headerService._tip = { height: 120 }; + var getHeaders = sandbox.stub(); + headerService._p2p = { getHeaders: getHeaders }; headerService._startSync(); - expect(sync.calledOnce).to.be.true; - expect(headerService._numNeeded).to.equal(8888); + expect(getHeaders.calledOnce).to.be.true; }); }); @@ -106,41 +125,13 @@ describe('Header Service', function() { it('should handle new headers received', function() { - headerService._tip = { height: 0 }; - headerService._originalTip = { height: 0, hash: header.hash }; - headerService._bestHeight = { height: 1 }; - headerService._headers = { - getIndex: function() { return { hash: header.hash }; }, - getLastIndex: sinon.stub().returns({ hash: 'aa' }), - set: sinon.stub() - }; - var getChainwork = sandbox.stub(headerService, '_getChainwork').returns(new BN(1)); - var headers = [ header ]; - - var batch = sandbox.stub().callsArgWith(1, null); - - headerService._db = { batch: batch }; + var headers = [preObjectHeader]; + var onHeader = sandbox.stub(headerService, '_onHeader'); + var saveHeaders = sandbox.stub(headerService, '_saveHeaders'); + headerService._tip = { height: 123, hash: 'aa' }; headerService._onHeaders(headers); - header.height = 1; - header.chainwork = '0000000000000000000000000000000000000000000000000000000000000001'; - - expect(batch.calledOnce).to.be.true; - expect(getChainwork.calledOnce).to.be.true; - var expected = batch.args[0][0]; - - expect(expected[0]).to.deep.equal({ - type: 'put', - key: headerService._encoding.encodeHeaderKey(1, header.hash), - value: headerService._encoding.encodeHeaderValue(header) - }); - var tip = utils.encodeTip({ height: 1, hash: header.hash }); - expect(expected[1]).to.deep.equal({ - type: 'put', - key: tip.key, - value: tip.value - }); - expect(headerService._tip.height).to.equal(1); - expect(headerService._tip.hash).to.equal(header.hash); + expect(onHeader.calledOnce).to.be.true; + expect(saveHeaders.calledOnce).to.be.true; }); }); diff --git a/test/services/mempool/index.unit.js b/test/services/mempool/index.unit.js index 36a072bd..fbf217a2 100644 --- a/test/services/mempool/index.unit.js +++ b/test/services/mempool/index.unit.js @@ -57,7 +57,8 @@ describe('Mempool Service', function() { it('should get a mempool transaction', function(done) { var get = sandbox.stub().callsArgWith(1, null, tx.toJSON()); var key = sandbox.stub(); - mempoolService._encoding = { encodeMempoolTransactionKey: key }; + var val = sandbox.stub().returns(tx.toJSON()); + mempoolService._encoding = { encodeMempoolTransactionKey: key, decodeMempoolTransactionValue: val }; mempoolService._db = { get: get }; mempoolService.getMempoolTransaction(tx.hash, function(err, mytx) { if(err) { diff --git a/test/services/p2p/index.js b/test/services/p2p/index.unit.js similarity index 97% rename from test/services/p2p/index.js rename to test/services/p2p/index.unit.js index 4b3f354f..ca20ec2a 100644 --- a/test/services/p2p/index.js +++ b/test/services/p2p/index.unit.js @@ -18,7 +18,7 @@ describe('P2P Service', function() { }); sinon.stub(p2p, '_initPool'); p2p._pool = new EventEmitter(); - p2p.start(done); + done(); }); it('should get the mempool from the network', function() { diff --git a/test/services/transaction/index.unit.js b/test/services/transaction/index.unit.js index cca24e2b..e70fb3bb 100644 --- a/test/services/transaction/index.unit.js +++ b/test/services/transaction/index.unit.js @@ -31,13 +31,9 @@ describe('Transaction Service', function() { describe('#start', function() { it('should get the prefix and the service tip', function(done) { - var startSubs = sandbox.stub(txService, '_startSubscriptions'); var getPrefix = sandbox.stub().callsArgWith(1, null, new Buffer('ffee', 'hex')); - var getServiceTip = sandbox.stub().callsArgWith(1, null, { height: 1, hash: 'aa' }); - txService._db = { getPrefix: getPrefix, getServiceTip: getServiceTip }; + txService._db = { getPrefix: getPrefix }; txService.start(function() { - startSubs.calledOnce.should.be.true; - getServiceTip.calledOnce.should.be.true; getPrefix.calledOnce.should.be.true; txService._encoding.should.be.instanceOf(Encoding); done(); @@ -64,13 +60,6 @@ describe('Transaction Service', function() { }); }); - describe('#_cacheOutputValues', function() { - it('should cache output values', function() { - txService._cacheOutputValues(tx); - txService._inputValuesCache.get('25e28f9fb0ada5353b7d98d85af5524b2f8df5b0b0e2d188f05968bceca603eb').should.deep.equal([ 50000000000000, 113903300000000 ]); - }); - }); - describe('#_getBlockTimestamp', function() { it('should get the block\'s timestamp', function() { var getTimestamp = sandbox.stub().returns(1); @@ -81,56 +70,54 @@ describe('Transaction Service', function() { }); describe('#onBlock', function() { + it('should process new blocks that come in from the block service', function(done) { - var getTimestamp = sandbox.stub().returns(1); - txService._timestamp = { getTimestampSync: getTimestamp }; - var batch = sandbox.stub().callsArgWith(1, null); - txService._db = { batch: batch }; + + var _processTransaction = sandbox.stub(txService, '_processTransaction'); + txService.onBlock(block, function(err, ops) { - txService._encoding.decodeTransactionKey(ops[0].key).should - .equal('6321fd1cf3fbf32a41bbb47b7090ab9896bbe6093e4c342c0269b652fa800c2b'); - txService._encoding.decodeTransactionValue(ops[0].value).should - .be.instanceOf(Tx); + if (err) { + return done(err); + } + _processTransaction.calledOnce.should.be.true; done(); }); }); }); describe('#_onReorg', function() { - it('should perform a reorg', function() { - var commonAncestorHeader = block.toHeaders().toJSON(); + it('should perform a reorg', function(done) { var oldList = []; - txService._tip = { height: 80000, hash: 'aa' }; - var batch = sandbox.stub().callsArgWith(1, null); - txService._db = { batch: batch }; - txService._onReorg(commonAncestorHeader, oldList); - batch.should.be.calledOnce; - batch.args[0][0][0].key.toString('hex').should.deep.equal('ffff7469702d756e646566696e6564'); - batch.args[0][0][0].value.toString('hex').should.deep.equal('0000000000000000008ba8d6beb01577730fae52517988564322026e5e2d90a3ee5d3cfb'); - }); - }); + var ops = txService.onReorg([ null, oldList ], function(err, ops) { - describe('#_startSubscriptions', function() { - it('should start subscriptions', function() { - - var on = sandbox.stub(); - var subscribe = sandbox.stub(); - txService._bus = { on: on, subscribe: subscribe }; - txService._startSubscriptions(); - on.should.be.calledOnce; - subscribe.should.be.calledOnce; - }); - }); - - describe('#_addMissingInputValues', function() { - it('should add missing input values on a tx', function(done) { - sandbox.stub(txService, 'getTransaction').callsArgWith(2, null, tx); - tx.__inputValues = []; - txService._addMissingInputValues(tx, {}, function(err, tx) { if (err) { return done(err); } - tx.__inputValues.should.deep.equal([113903300000000, 113903300000000, 50000000000000, 113903300000000 ]); + + ops.should.deep.equal([]); + done(); + }); + }); + }); + + + describe('#getInputValues', function() { + + it('should add missing input values on a tx', function(done) { + + var put = sandbox.stub().callsArgWith(2, null); + txService._db = { put: put }; + + sandbox.stub(txService, '_getTransaction').callsArgWith(2, null, tx.txid(), tx); + + tx.__inputValues = []; + + txService.getInputValues(tx, {}, function(err, tx) { + + if (err) { + return done(err); + } + tx.__inputValues.should.deep.equal([1139033, 1139033, 500000, 1139033]); done(); });