itns-sidechain/test/node-critical-error-test.js

143 lines
4.5 KiB
JavaScript
Raw Permalink Normal View History

/* eslint-env mocha */
'use strict';
const assert = require('bsert');
const FullNode = require('../lib/node/fullnode');
const {rimraf, testdir} = require('./util/common');
describe('Node Critical Error', function() {
this.timeout(30000);
let prefix, node;
beforeEach(async () => {
prefix = testdir('hsd-critical-error-test');
node = new FullNode({
memory: false,
network: 'regtest',
prefix
});
await node.ensure();
await node.open();
});
afterEach(async () => {
if (node && node.opened)
await node.close();
await rimraf(prefix);
});
async function mineBlocks(node, count) {
for (let i = 0; i < count; i++) {
if (!node || !node.opened)
break;
const block = await node.miner.mineBlock(
null,
'rs1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqn6kda'
);
try {
// We are catching this error in the test but normally
// it would bubble up all the way from blockstore to Peer,
// where it is caught and logged, then we disconnect the peer
// that sent us whatever data caused the error (even if it's our fault!)
//
// [error] (net) Could not write block.
// at FileBlockStore._write (hsd/lib/blockstore/file.js:424:13)
// at async FileBatch.write (hsd/lib/blockstore/file.js:755:11)
// at async ChainDB.commit (hsd/lib/blockchain/chaindb.js:332:7)
// at async ChainDB.save (hsd/lib/blockchain/chaindb.js:1531:5)
// at async Chain.setBestChain (hsd/lib/blockchain/chain.js:1835:5)
// at async Chain.connect (hsd/lib/blockchain/chain.js:2236:7)
// at async Chain._add (hsd/lib/blockchain/chain.js:2145:19)
// at async Chain.add (hsd/lib/blockchain/chain.js:2073:14)
// at async Pool._addBlock (hsd/lib/net/pool.js:2459:15)
// at async Pool.addBlock (hsd/lib/net/pool.js:2426:14)
// at async Pool.handleBlock (hsd/lib/net/pool.js:2410:5)
// at async Pool.handlePacket (hsd/lib/net/pool.js:1331:9)
// at async Peer.handlePacket (hsd/lib/net/peer.js:1549:7)
// at async Peer.readPacket (hsd/lib/net/peer.js:1486:11)
// at async Parser.<anonymous> (hsd/lib/net/peer.js:185:9)
await node.chain.add(block);
} catch (e) {
assert.strictEqual(e.message, 'Critical Error: Disk full!');
assert.strictEqual(e.type, 'CriticalError');
break;
}
}
}
it('should not run out of disk space', async () => {
await mineBlocks(node, 100);
assert.strictEqual(node.chain.height, 100);
assert.strictEqual(node.opened, true);
assert.strictEqual(node.chain.opened, true);
assert.strictEqual(node.chain.db.db.loaded, true);
assert.strictEqual(node.chain.db.blocks.db.loaded, true);
await node.close();
assert.strictEqual(node.opened, false);
assert.strictEqual(node.chain.opened, false);
assert.strictEqual(node.chain.db.db.loaded, false);
assert.strictEqual(node.chain.db.blocks.db.loaded, false);
});
it('should run out of disk space on block write and abort', async () => {
const waiter = new Promise((resolve) => {
node.once('closed', () => resolve());
});
node.on('abort', async () => {
try {
await node.close();
} catch (e) {
;
}
});
await mineBlocks(node, 99);
node.chain.db.db.batch = () => {
return {
clear: () => {},
put: () => {},
del: () => {},
write: () => {
throw new Error('Disk full!');
}
};
};
await mineBlocks(node, 1);
await waiter;
assert.strictEqual(node.opened, false);
assert.strictEqual(node.chain.opened, false);
assert.strictEqual(node.chain.db.db.loaded, false);
assert.strictEqual(node.chain.db.blocks.db.loaded, false);
});
it('should run out of disk space on tree commit and abort', async () => {
const waiter = new Promise((resolve) => {
node.once('closed', () => resolve());
});
node.on('abort', async () => {
try {
await node.close();
} catch (e) {
;
}
});
await mineBlocks(node, 50);
node.chain.db.tree.store.commit = () => {
throw new Error('Disk full!');
};
await mineBlocks(node, 50);
await waiter;
assert.strictEqual(node.opened, false);
assert.strictEqual(node.chain.opened, false);
assert.strictEqual(node.chain.db.db.loaded, false);
assert.strictEqual(node.chain.db.blocks.db.loaded, false);
});
});