UNPKG

bitcore-node

Version:

A blockchain indexing node with extended capabilities using bitcore

129 lines (112 loc) 5.26 kB
#!/usr/bin/env node const { Storage } = require('../build/src/services/storage'); const { BitcoinBlockStorage: BlockStorage } = require('../build/src/models/block'); const { TransactionStorage } = require('../build/src/models/transaction'); const { CoinStorage } = require('../build/src/models/coin'); const rl = require('readline').createInterface({ input: process.stdin, output: process.stdout }); const { wait } = require('../build/src/utils'); function usage(errMsg) { console.log('USAGE: ./purgeNetworkData.js [options'); console.log('OPTIONS:'); console.log(' --chain <value> REQUIRED - e.g. BTC, BCH, DOGE, LTC...'); console.log(' --network <value> REQUIRED - e.g. mainnet, testnet3, regtest...'); console.log(' --limit <value> Number of documents to delete at a time. Default: 250'); console.log(' --sleep <value> Sleep time in milliseconds between deletions. Default: 50'); console.log(' --every <value> Sleep for --sleep milliseconds every --every loop iteration. Default: 10'); if (errMsg) { console.log('\nERROR: ' + errMsg); } process.exit(); } const args = process.argv.slice(2); if (args.includes('--help') || args.includes('-h')) { usage(); } const chainIdx = args.indexOf('--chain'); const networkIdx = args.indexOf('--network'); const chain = args[chainIdx + 1]?.toUpperCase(); const network = args[networkIdx + 1]?.toLowerCase(); if (chainIdx === -1 || networkIdx === -1 || !chain || !network) { usage('Missing required options.'); } const limitIdx = args.indexOf('--limit'); const limit = (limitIdx > -1 && parseInt(args[limitIdx + 1])) || 250; const sleepIdx = args.indexOf('--sleep'); const sleepMs = (sleepIdx > -1 && parseInt(args[sleepIdx + 1])) || 50; const everyIdx = args.indexOf('--every'); const nSleep = (everyIdx > -1 && parseInt(args[everyIdx + 1])) || 10; let quit = false; process.on('SIGINT', () => { if (quit) { process.exit(1); } console.log('Caught interrupt signal'); quit = true; }); console.log('Connecting to database...'); Storage.start() .then(async () => { console.log('Collecting stats. This could take a minute...') const blkCount = await BlockStorage.collection.countDocuments({ chain, network }); const txCount = await TransactionStorage.collection.countDocuments({ chain, network }); const coinCount = await CoinStorage.collection.countDocuments({ chain, network }); let progressCnt = 0; console.log(`If you continue, the following ${chain}:${network} data will be purged:`); console.log('Blocks:', blkCount); console.log('Transactions:', txCount); console.log('Coins:', coinCount); console.log(`Data will be deleted in batches of ${limit} documents with a sleep time of ${sleepMs}ms every ${nSleep} iterations.`); const ans = await new Promise(r => rl.question('Do you want to continue? (y/N): ', r)); if (ans?.toLowerCase() !== 'y') { console.log('Aborted.'); return; } { progressCnt = 0; let blkIds = await BlockStorage.collection.find({ chain, network }).project({ _id: 1 }).limit(limit).toArray(); while (blkIds.length && !quit) { process.stdout.write(`Blocks: ${(progressCnt / blkCount * 100).toFixed(2)}% (${progressCnt} / ${blkCount})\r`); const res = await BlockStorage.collection.deleteMany({ _id: { $in: blkIds.map(a => a._id) } }); progressCnt += blkIds.length; if (progressCnt % nSleep === 0) { await wait(sleepMs); } blkIds = await BlockStorage.collection.find({ chain, network }).project({ _id: 1 }).limit(limit).toArray(); }; !quit && console.log('\nBlocks purged.'); } { progressCnt = 0; let txIds = await TransactionStorage.collection.find({ chain, network }).project({ _id: 1 }).limit(limit).toArray(); while (txIds.length && !quit) { process.stdout.write(`Transactions: ${(progressCnt / txCount * 100).toFixed(2)}% (${progressCnt} / ${txCount})\r`); const res = await TransactionStorage.collection.deleteMany({ _id: { $in: txIds.map(a => a._id) } }); progressCnt += txIds.length; if (progressCnt % nSleep === 0) { await wait(sleepMs); } txIds = await TransactionStorage.collection.find({ chain, network }).project({ _id: 1 }).limit(limit).toArray(); } !quit && console.log('\nTransactions purged.'); } { progressCnt = 0; let coinIds = await CoinStorage.collection.find({ chain, network }).project({ _id: 1 }).limit(limit).toArray(); while (coinIds.length && !quit) { process.stdout.write(`Coins: ${(progressCnt / coinCount * 100).toFixed(2)}% (${progressCnt} / ${coinCount})\r`); const res = await CoinStorage.collection.deleteMany({ _id: { $in: coinIds.map(a => a._id) } }); progressCnt += coinIds.length; if (progressCnt % nSleep === 0) { await wait(sleepMs); } coinIds = await CoinStorage.collection.find({ chain, network }).project({ _id: 1 }).limit(limit).toArray(); } !quit && console.log('\nCoins purged.'); } !quit && console.log('Data purged.'); }) .catch(console.error) .finally(() => { rl.close(); Storage.stop(); });