Skip to content

Commit

Permalink
fullnode: reemit abort and let bin handle the shutdown.
Browse files Browse the repository at this point in the history
  • Loading branch information
nodech authored and pinheadmz committed Jun 7, 2022
1 parent 4c665cb commit ee5d45f
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 64 deletions.
20 changes: 20 additions & 0 deletions bin/node
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
20 changes: 20 additions & 0 deletions bin/spvnode
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
15 changes: 9 additions & 6 deletions lib/blockchain/chain.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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:'
Expand Down
25 changes: 3 additions & 22 deletions lib/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
19 changes: 1 addition & 18 deletions lib/node/fullnode.js
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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.
Expand Down
11 changes: 11 additions & 0 deletions lib/node/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
19 changes: 1 addition & 18 deletions lib/node/spvnode.js
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down Expand Up @@ -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.
Expand Down
16 changes: 16 additions & 0 deletions test/node-critical-error-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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!');
Expand Down

0 comments on commit ee5d45f

Please sign in to comment.