diff --git a/.circleci/config.yml b/.circleci/config.yml index adff32ae7e..397b163153 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,8 +9,7 @@ restore_node_modules: &restore_node_modules name: Restore node_modules cache keys: - v1-node-{{ .Branch }}-{{ checksum "package.json" }} - - v1-node-{{ .Branch }}- - - v1-node- + - v1-node-{{ checksum "package.json" }} jobs: install: <<: *defaults diff --git a/lib/fakeBlockChain.js b/lib/fakeBlockChain.js index 9d8d469ecb..d8d0252218 100644 --- a/lib/fakeBlockChain.js +++ b/lib/fakeBlockChain.js @@ -24,5 +24,9 @@ module.exports = { delBlock: function (hash, cb) { cb(null) + }, + + iterator: function (name, onBlock, cb) { + cb(null) } } diff --git a/lib/runBlockchain.js b/lib/runBlockchain.js index ef20d1ea11..2ceca40134 100644 --- a/lib/runBlockchain.js +++ b/lib/runBlockchain.js @@ -53,8 +53,9 @@ module.exports = function (blockchain, cb) { }, function (err, results) { if (err) { // remove invalid block - console.log('Invalid block error:', err) - blockchain.delBlock(block.header.hash(), cb) + blockchain.delBlock(block.header.hash(), function () { + cb(err) + }) } else { // set as new head block headBlock = block diff --git a/tests/api/runBlockchain.js b/tests/api/runBlockchain.js new file mode 100644 index 0000000000..38d816ba01 --- /dev/null +++ b/tests/api/runBlockchain.js @@ -0,0 +1,99 @@ +const tape = require('tape') +const Levelup = require('levelup') +const Memdown = require('memdown') +const { promisify } = require('util') +const Blockchain = require('ethereumjs-blockchain') +const Block = require('ethereumjs-block') +const util = require('ethereumjs-util') +const runBlockchain = require('../../lib/runBlockchain') +const StateManager = require('../../lib/stateManager') + +tape('runBlockchain', (t) => { + const blockchainDB = new Levelup('', { db: Memdown }) + const blockchain = new Blockchain({ db: blockchainDB }) + const vm = { stateManager: new StateManager(), blockchain } + + const putGenesisP = promisify(blockchain.putGenesis.bind(blockchain)) + const putBlockP = promisify(blockchain.putBlock.bind(blockchain)) + const getHeadP = promisify(blockchain.getHead.bind(blockchain)) + const runBlockchainP = promisify(runBlockchain.bind(vm)) + + t.test('should run without a blockchain parameter', async (st) => { + await runBlockchainP() + st.end() + }) + + t.test('should run without blocks', async (st) => { + await runBlockchainP(blockchain) + st.end() + }) + + t.test('should run with genesis block', async (st) => { + const genesis = createGenesis() + + await putGenesisP(genesis) + st.ok(blockchain.meta.genesis, 'genesis should be set for blockchain') + + await runBlockchainP(blockchain) + st.end() + }) + + t.test('should run with valid and invalid blocks', async (st) => { + // Produce error on the third time runBlock is called + let runBlockInvocations = 0 + vm.runBlock = (opts, cb) => { + runBlockInvocations++ + if (runBlockInvocations === 3) { + return cb(new Error('test'), {}) + } + cb(null, {}) + } + + const genesis = createGenesis() + await putGenesisP(genesis) + + const b1 = createBlock(genesis, 1) + const b2 = createBlock(b1, 2) + const b3 = createBlock(b2, 3) + + blockchain.validate = false + + await putBlockP(b1) + await putBlockP(b2) + await putBlockP(b3) + + let head = await getHeadP() + st.deepEqual(head.hash(), b3.hash(), 'block3 should be the current head') + + try { + await runBlockchainP(blockchain) + st.fail('should have returned error') + } catch (e) { + st.equal(e.message, 'test') + + head = await getHeadP() + st.deepEqual(head.hash(), b2.hash(), 'should have removed invalid block from head') + + st.end() + } + }) +}) + +function createGenesis () { + const genesis = new Block() + genesis.setGenesisParams() + return genesis +} + +function createBlock (parent = null, n = 0) { + if (parent === null) { + return createGenesis() + } + + const b = new Block() + b.header.number = util.toBuffer(n) + b.header.parentHash = parent.hash() + b.header.difficulty = '0xfffffff' + + return b +}