fullnode: reemit abort and let bin handle the shutdown.
This commit is contained in:
parent
4c665cb42b
commit
ee5d45fa31
8 changed files with 81 additions and 64 deletions
20
bin/node
20
bin/node
|
|
@ -50,6 +50,26 @@ process.on('SIGINT', async () => {
|
|||
await node.close();
|
||||
});
|
||||
|
||||
node.on('abort', async (err) => {
|
||||
const timeout = setTimeout(() => {
|
||||
console.error('Shutdown is taking a long time. Exitting.');
|
||||
process.exit(3);
|
||||
}, 5000);
|
||||
|
||||
timeout.unref();
|
||||
|
||||
try {
|
||||
console.error('Shutting down...');
|
||||
await node.close();
|
||||
clearTimeout(timeout);
|
||||
console.error(err.stack);
|
||||
process.exit(2);
|
||||
} catch (e) {
|
||||
console.error(`Error occurred during shutdown: ${e.message}`);
|
||||
process.exit(3);
|
||||
}
|
||||
});
|
||||
|
||||
(async () => {
|
||||
await node.ensure();
|
||||
await node.open();
|
||||
|
|
|
|||
20
bin/spvnode
20
bin/spvnode
|
|
@ -67,6 +67,26 @@ process.on('SIGINT', async () => {
|
|||
await node.close();
|
||||
});
|
||||
|
||||
node.on('abort', async (err) => {
|
||||
const timeout = setTimeout(() => {
|
||||
console.error('Shutdown is taking a long time. Exitting.');
|
||||
process.exit(3);
|
||||
}, 5000);
|
||||
|
||||
timeout.unref();
|
||||
|
||||
try {
|
||||
console.error('Shutting down...');
|
||||
await node.close();
|
||||
clearTimeout(timeout);
|
||||
console.error(err.stack);
|
||||
process.exit(2);
|
||||
} catch (e) {
|
||||
console.error(`Error occurred during shutdown: ${e.message}`);
|
||||
process.exit(3);
|
||||
}
|
||||
});
|
||||
|
||||
(async () => {
|
||||
await node.ensure();
|
||||
await node.open();
|
||||
|
|
|
|||
|
|
@ -998,8 +998,9 @@ class Chain extends AsyncEmitter {
|
|||
|
||||
if (ns.isNull()) {
|
||||
if (!covenant.isClaim() && !covenant.isOpen()) {
|
||||
this.emit('abort', 'Unexpected null NameState.');
|
||||
throw new CriticalError('Database inconsistency.');
|
||||
const error = new CriticalError('Database inconsistency.');
|
||||
this.emit('abort', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
const name = covenant.get(2);
|
||||
|
|
@ -1899,8 +1900,9 @@ class Chain extends AsyncEmitter {
|
|||
try {
|
||||
await this.db.save(entry, block, view);
|
||||
} catch (e) {
|
||||
this.emit('abort', e.message);
|
||||
throw new CriticalError(e);
|
||||
const error = new CriticalError(e.message);
|
||||
this.emit('abort', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
// Expose the new state.
|
||||
|
|
@ -1963,8 +1965,9 @@ class Chain extends AsyncEmitter {
|
|||
try {
|
||||
await this.db.save(entry, block);
|
||||
} catch (e) {
|
||||
this.emit('abort', e.message);
|
||||
throw new CriticalError(e);
|
||||
const error = new CriticalError(e.message);
|
||||
this.emit('abort', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
this.logger.warning('Heads up: Competing chain at height %d:'
|
||||
|
|
|
|||
|
|
@ -10,43 +10,24 @@
|
|||
* @module errors
|
||||
*/
|
||||
|
||||
const assert = require('bsert');
|
||||
|
||||
/**
|
||||
* Critical Error
|
||||
* An error severe enough to warrant shutting down the node.
|
||||
* @extends Error
|
||||
* @param {Block|TX} msg
|
||||
* @param {String} code - Reject packet code.
|
||||
* @param {String} reason - Reject packet reason.
|
||||
* @param {Number} score - Ban score increase
|
||||
* (can be -1 for no reject packet).
|
||||
* @param {Boolean} malleated
|
||||
*/
|
||||
|
||||
class CriticalError extends Error {
|
||||
/**
|
||||
* Create a verify error.
|
||||
* @constructor
|
||||
* @param {Block|TX} msg
|
||||
* @param {String} code - Reject packet code.
|
||||
* @param {String} reason - Reject packet reason.
|
||||
* @param {Number} score - Ban score increase
|
||||
* (can be -1 for no reject packet).
|
||||
* @param {Boolean} malleated
|
||||
* @param {String} msg
|
||||
*/
|
||||
|
||||
constructor(err) {
|
||||
constructor(msg) {
|
||||
super();
|
||||
|
||||
this.type = 'CriticalError';
|
||||
|
||||
if (err instanceof Error) {
|
||||
this.message = `Critical Error: ${err.message}`;
|
||||
} else {
|
||||
assert(typeof err === 'string');
|
||||
this.message = `Critical Error: ${err}`;
|
||||
}
|
||||
this.message = `Critical Error: ${msg}`;
|
||||
|
||||
if (Error.captureStackTrace)
|
||||
Error.captureStackTrace(this, CriticalError);
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ class FullNode extends Node {
|
|||
init() {
|
||||
// Bind to errors
|
||||
this.chain.on('error', err => this.error(err));
|
||||
this.chain.on('abort', msg => this.abort(msg));
|
||||
this.chain.on('abort', err => this.abort(err));
|
||||
|
||||
this.mempool.on('error', err => this.error(err));
|
||||
this.pool.on('error', err => this.error(err));
|
||||
|
|
@ -350,23 +350,6 @@ class FullNode extends Node {
|
|||
this.emit('closed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Emergency shutdown.
|
||||
* @param {String} msg - error message
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
async abort(msg) {
|
||||
this.logger.error(`Critical error, shutting down: ${msg}`);
|
||||
try {
|
||||
this.emit('abort', msg);
|
||||
await this.close();
|
||||
} catch (e) {
|
||||
this.logger.error(`Error occurred during shutdown: ${e.message}`);
|
||||
process.exit(-2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rescan for any missed transactions.
|
||||
* @param {Number|Hash} start - Start block.
|
||||
|
|
|
|||
|
|
@ -305,6 +305,17 @@ class Node extends EventEmitter {
|
|||
this.emit('error', err);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit and log an abort error.
|
||||
* @private
|
||||
* @param {Error} err
|
||||
*/
|
||||
|
||||
abort(err) {
|
||||
this.logger.error(err);
|
||||
this.emit('abort', err);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get node uptime in seconds.
|
||||
* @returns {Number}
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ class SPVNode extends Node {
|
|||
init() {
|
||||
// Bind to errors
|
||||
this.chain.on('error', err => this.error(err));
|
||||
this.chain.on('abort', msg => this.abort(msg));
|
||||
this.chain.on('abort', err => this.abort(err));
|
||||
|
||||
this.pool.on('error', err => this.error(err));
|
||||
|
||||
|
|
@ -221,23 +221,6 @@ class SPVNode extends Node {
|
|||
this.emit('closed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Emergency shutdown.
|
||||
* @param {String} msg - error message
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
async abort(msg) {
|
||||
this.logger.error(`Critical error, shutting down: ${msg}`);
|
||||
try {
|
||||
this.emit('abort', msg);
|
||||
await this.close();
|
||||
} catch (e) {
|
||||
this.logger.error(`Error occurred during shutdown: ${e.message}`);
|
||||
process.exit(-2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan for any missed transactions.
|
||||
* Note that this will replay the blockchain sync.
|
||||
|
|
|
|||
|
|
@ -88,6 +88,14 @@ describe('Node Critical Error', function() {
|
|||
node.once('closed', () => resolve());
|
||||
});
|
||||
|
||||
node.on('abort', async () => {
|
||||
try {
|
||||
await node.close();
|
||||
} catch (e) {
|
||||
;
|
||||
}
|
||||
});
|
||||
|
||||
await mineBlocks(node, 99);
|
||||
node.chain.db.db.batch = () => {
|
||||
return {
|
||||
|
|
@ -112,6 +120,14 @@ describe('Node Critical Error', function() {
|
|||
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!');
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue