Skip to content

Instantly share code, notes, and snippets.

@phiresky
Last active September 17, 2024 13:47
Show Gist options
  • Save phiresky/153411abb794ad61eb4ba949236bc6ce to your computer and use it in GitHub Desktop.
Save phiresky/153411abb794ad61eb4ba949236bc6ce to your computer and use it in GitHub Desktop.
parity auto-kill script
/node_modules
*.log

auto kill parity to work around parity issue #11737

auto kills / restarts a parity node when it is out of date by more than 7 mins (which should never happen normally) or down

if node does not exit gracefully, sigkill it

start parity either using an auto-restarting manager like systemd or using

while true; do parity --foo --params; sleep 1m; done

When node is synced, run the kill script using this:

npm install
parity_url=http://localhost:8545 npm run auto-kill-parity | tee -a log$(date -I).log
/**
* shitty script to kill parity because it keeps getting stuck after a few hours to a few days
*/
import { JsonRpcProvider } from "ethers/providers";
import { exec as _exec } from "child_process";
import { promisify } from "util";
const exec = promisify(_exec);
function sleep(time_ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, time_ms));
}
async function getBlockAgeMinutes(localBackend: JsonRpcProvider) {
const blkHeight = await localBackend.getBlockNumber();
const blk = await localBackend.getBlock(blkHeight);
const blockAge = new Date().getTime() - blk.timestamp * 1000;
const blockAgeMinutes = blockAge / 1000 / 60;
return blockAgeMinutes;
}
function log(...args: any[]) {
console.log(new Date(), ...args);
}
async function go() {
const url = process.env.parity_url;
if (!url) {
throw Error("supply backend in env parity_url");
}
const localBackend = new JsonRpcProvider(url);
while (true) {
const blockAgeMinutes = await Promise.race([
getBlockAgeMinutes(localBackend),
sleep(60 * 1000).then(() => Promise.reject("timeout")),
]).catch(e => {
log("error", e);
return "down" as const;
});
if (blockAgeMinutes === "down" || blockAgeMinutes > 7) {
log(`block is ${blockAgeMinutes} min old, killing node`);
try {
// safeguard: if process has been running for less than an hour, maybe it's still syncing up?
await exec("killall parity --older-than 60m");
} catch (e) {
log("pkill 1 fail", e);
}
await sleep(60 * 1000);
// if it takes more than 60s to exit, sigkill
try {
await exec("killall parity --older-than 60m --signal KILL");
} catch (e) {
log("pkill 2 fail", e);
}
await sleep(600 * 1000);
} else {
log(`parity is current (${blockAgeMinutes.toFixed(1)} min)`);
}
await sleep(20 * 1000);
}
}
go();
{
"scripts": {
"auto-kill-parity": "ts-node --transpile-only auto-kill-parity.ts"
},
"dependencies": {
"ethers": "^4.0.47",
"ts-node": "^8.9.0",
"typescript": "^3.8.3",
"web3": "^1.2.7"
}
}
@webcaetano
Copy link

@phiresky awesome work. i would recommend run this script on something like pm2, for keep it alive all the time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment