add blockchain install scripts
This commit is contained in:
parent
0e9e27b97b
commit
178f576cfb
39 changed files with 3938 additions and 750 deletions
33
lib/blockchain/bitcoin.js
Normal file
33
lib/blockchain/bitcoin.js
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const coinUtils = require('../coin-utils')
|
||||
|
||||
const common = require('./common')
|
||||
|
||||
module.exports = {setup}
|
||||
|
||||
const es = common.es
|
||||
|
||||
function setup (dataDir) {
|
||||
const coinRec = coinUtils.getCryptoCurrency('BTC')
|
||||
common.firewall([coinRec.defaultPort])
|
||||
const config = buildConfig()
|
||||
fs.writeFileSync(path.resolve(dataDir, coinRec.configFile), config)
|
||||
setupPm2(dataDir)
|
||||
}
|
||||
|
||||
function buildConfig () {
|
||||
return `rpcuser=lamassuserver
|
||||
rpcpassword=${common.randomPass()}
|
||||
dbcache=500
|
||||
server=1
|
||||
connections=40
|
||||
keypool=10000
|
||||
prune=4000
|
||||
daemon=0`
|
||||
}
|
||||
|
||||
function setupPm2 (dataDir) {
|
||||
es(`pm2 start /usr/local/bin/bitcoind -- -datadir=${dataDir}`)
|
||||
}
|
||||
61
lib/blockchain/common.js
Normal file
61
lib/blockchain/common.js
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
const crypto = require('crypto')
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
const cp = require('child_process')
|
||||
const logger = require('console-log-level')({level: 'info'})
|
||||
|
||||
module.exports = {es, firewall, randomPass, fetchAndInstall, logger}
|
||||
|
||||
const BINARIES = {
|
||||
BTC: {
|
||||
url: 'https://bitcoin.org/bin/bitcoin-core-0.14.2/bitcoin-0.14.2-x86_64-linux-gnu.tar.gz',
|
||||
dir: 'bitcoin-0.14.2/bin'
|
||||
},
|
||||
ETH: {
|
||||
url: 'https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.6.6-10a45cb5.tar.gz',
|
||||
dir: 'geth-linux-amd64-1.6.6-10a45cb5'
|
||||
},
|
||||
ZEC: {
|
||||
url: 'https://z.cash/downloads/zcash-1.0.10-1-linux64.tar.gz',
|
||||
dir: 'zcash-1.0.10-1/bin'
|
||||
},
|
||||
DASH: {
|
||||
url: 'https://www.dash.org/binaries/dashcore-0.12.1.5-linux64.tar.gz',
|
||||
dir: 'dashcore-0.12.1/bin'
|
||||
},
|
||||
LTC: {
|
||||
url: 'https://download.litecoin.org/litecoin-0.13.2/linux/litecoin-0.13.2-x86_64-linux-gnu.tar.gz',
|
||||
dir: 'litecoin-0.13.2/bin'
|
||||
}
|
||||
}
|
||||
|
||||
function firewall (ports) {
|
||||
if (!ports || ports.length === 0) throw new Error('No ports supplied')
|
||||
const portsString = ports.join(',')
|
||||
es(`sudo ufw allow ${portsString}`)
|
||||
}
|
||||
|
||||
function randomPass () {
|
||||
return crypto.randomBytes(32).toString('hex')
|
||||
}
|
||||
|
||||
function es (cmd) {
|
||||
const env = {HOME: os.userInfo().homedir}
|
||||
const options = {encoding: 'utf8', env}
|
||||
const res = cp.execSync(cmd, options)
|
||||
logger.debug(res)
|
||||
return res.toString()
|
||||
}
|
||||
|
||||
function fetchAndInstall (crypto) {
|
||||
const binaries = BINARIES[crypto.cryptoCode]
|
||||
if (!binaries) throw new Error(`No such coin: ${crypto.code}`)
|
||||
|
||||
const url = binaries.url
|
||||
const downloadFile = path.basename(url)
|
||||
const binDir = binaries.dir
|
||||
|
||||
es(`wget -q ${url}`)
|
||||
es(`tar -xzf ${downloadFile}`)
|
||||
es(`sudo cp ${binDir}/* /usr/local/bin`)
|
||||
}
|
||||
28
lib/blockchain/dash.js
Normal file
28
lib/blockchain/dash.js
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const coinUtils = require('../coin-utils')
|
||||
|
||||
const common = require('./common')
|
||||
|
||||
module.exports = {setup}
|
||||
|
||||
const es = common.es
|
||||
|
||||
function setup (dataDir) {
|
||||
const coinRec = coinUtils.getCryptoCurrency('DASH')
|
||||
common.firewall([coinRec.defaultPort])
|
||||
const config = buildConfig()
|
||||
fs.writeFileSync(path.resolve(dataDir, coinRec.configFile), config)
|
||||
setupPm2(dataDir)
|
||||
}
|
||||
|
||||
function buildConfig () {
|
||||
return `rpcuser=lamassuserver
|
||||
rpcpassword=${common.randomPass()}
|
||||
dbcache=500`
|
||||
}
|
||||
|
||||
function setupPm2 (dataDir) {
|
||||
es(`pm2 start /usr/local/bin/dashd -- -datadir=${dataDir}`)
|
||||
}
|
||||
0
lib/blockchain/dashd.js
Normal file
0
lib/blockchain/dashd.js
Normal file
67
lib/blockchain/do-volume.js
Normal file
67
lib/blockchain/do-volume.js
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
const fs = require('fs')
|
||||
|
||||
const common = require('./common')
|
||||
|
||||
const MOUNT_POINT = '/mnt/blockchains'
|
||||
|
||||
module.exports = {prepareVolume}
|
||||
|
||||
const logger = common.logger
|
||||
|
||||
function isMounted () {
|
||||
return fs.existsSync(MOUNT_POINT)
|
||||
}
|
||||
|
||||
function isFormatted (volumePath) {
|
||||
const res = common.es(`file --dereference -s ${volumePath}`)
|
||||
return res !== `${volumePath}: data`
|
||||
}
|
||||
|
||||
function formatVolume (volumePath) {
|
||||
if (isFormatted(volumePath)) {
|
||||
logger.info('Volume is already formatted.')
|
||||
return
|
||||
}
|
||||
|
||||
logger.info('Formatting...')
|
||||
common.es(`sudo mkfs.ext4 ${volumePath}`)
|
||||
}
|
||||
|
||||
function mountVolume (volumePath) {
|
||||
if (isMounted()) {
|
||||
logger.info('Volume is already mounted.')
|
||||
return
|
||||
}
|
||||
|
||||
logger.info('Mounting...')
|
||||
common.es(`sudo mkdir -p ${MOUNT_POINT}`)
|
||||
common.es(`sudo mount -o discard,defaults ${volumePath} ${MOUNT_POINT}`)
|
||||
common.es(`echo ${volumePath} ${MOUNT_POINT} ext4 defaults,nofail,discard 0 0 | sudo tee -a /etc/fstab`)
|
||||
}
|
||||
|
||||
function locateVolume () {
|
||||
const res = common.es('ls /dev/disk/by-id/*')
|
||||
const lines = res.trim().split('\n')
|
||||
|
||||
if (lines.length > 1) {
|
||||
logger.error('More than one volume present, cannot prepare.')
|
||||
return null
|
||||
}
|
||||
|
||||
if (lines.length === 0) {
|
||||
logger.error('No available volumes. You might need to attach one.')
|
||||
return null
|
||||
}
|
||||
|
||||
return lines[0].trim()
|
||||
}
|
||||
|
||||
function prepareVolume () {
|
||||
const volumePath = locateVolume()
|
||||
if (!volumePath) return false
|
||||
|
||||
formatVolume(volumePath)
|
||||
mountVolume(volumePath)
|
||||
|
||||
return true
|
||||
}
|
||||
17
lib/blockchain/ethereum.js
Normal file
17
lib/blockchain/ethereum.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
const coinUtils = require('../coin-utils')
|
||||
|
||||
const common = require('./common')
|
||||
|
||||
module.exports = {setup}
|
||||
|
||||
const es = common.es
|
||||
|
||||
function setup (dataDir) {
|
||||
const coinRec = coinUtils.getCryptoCurrency('ETH')
|
||||
common.firewall([coinRec.defaultPort])
|
||||
setupPm2(dataDir)
|
||||
}
|
||||
|
||||
function setupPm2 (dataDir) {
|
||||
es(`pm2 start /usr/local/bin/geth -- --datadir "${dataDir}" --cache 500`)
|
||||
}
|
||||
95
lib/blockchain/install.js
Normal file
95
lib/blockchain/install.js
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const process = require('process')
|
||||
|
||||
const makeDir = require('make-dir')
|
||||
const inquirer = require('inquirer')
|
||||
const _ = require('lodash/fp')
|
||||
|
||||
const options = require('../options')
|
||||
const coinUtils = require('../coin-utils')
|
||||
|
||||
const common = require('./common')
|
||||
const doVolume = require('./do-volume')
|
||||
|
||||
const cryptos = coinUtils.cryptoCurrencies()
|
||||
|
||||
const logger = common.logger
|
||||
|
||||
const PLUGINS = {
|
||||
BTC: require('./bitcoin.js'),
|
||||
LTC: require('./litecoin.js'),
|
||||
ETH: require('./ethereum.js'),
|
||||
DASH: require('./dash.js'),
|
||||
ZEC: require('./zcash.js')
|
||||
}
|
||||
|
||||
function installedFilePath (crypto) {
|
||||
return path.resolve(options.blockchainDir, crypto.code, '.installed')
|
||||
}
|
||||
|
||||
function isInstalled (crypto) {
|
||||
return fs.existsSync(installedFilePath(crypto))
|
||||
}
|
||||
|
||||
const choices = _.map(c => {
|
||||
const checked = isInstalled(c)
|
||||
return {
|
||||
name: c.display,
|
||||
value: c.code,
|
||||
checked,
|
||||
disabled: checked && 'Installed'
|
||||
}
|
||||
}, cryptos)
|
||||
|
||||
const questions = []
|
||||
|
||||
questions.push({
|
||||
type: 'checkbox',
|
||||
name: 'crypto',
|
||||
message: 'Which cryptocurrencies would you like to install?',
|
||||
choices
|
||||
})
|
||||
|
||||
function processCryptos (codes) {
|
||||
if (_.isEmpty(codes)) {
|
||||
logger.info('No cryptos selected. Exiting.')
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
doVolume.prepareVolume()
|
||||
|
||||
logger.info('Thanks! Installing: %s. Will take a while...', _.join(', ', codes))
|
||||
|
||||
const selectedCryptos = _.map(code => _.find(['code', code], cryptos), codes)
|
||||
_.forEach(setupCrypto, selectedCryptos)
|
||||
common.es('pm2 save')
|
||||
logger.info('Installation complete.')
|
||||
}
|
||||
|
||||
inquirer.prompt(questions)
|
||||
.then(answers => processCryptos(answers.crypto))
|
||||
|
||||
function plugin (crypto) {
|
||||
const plugin = PLUGINS[crypto.cryptoCode]
|
||||
if (!plugin) throw new Error(`No such plugin: ${crypto.cryptoCode}`)
|
||||
return plugin
|
||||
}
|
||||
|
||||
function setupCrypto (crypto) {
|
||||
logger.info(`Installing ${crypto.display}...`)
|
||||
const cryptoDir = path.resolve(options.blockchainDir, crypto.code)
|
||||
makeDir.sync(cryptoDir)
|
||||
const cryptoPlugin = plugin(crypto)
|
||||
const oldDir = process.cwd()
|
||||
const tmpDir = '/tmp/blockchain-install'
|
||||
|
||||
makeDir.sync(tmpDir)
|
||||
process.chdir(tmpDir)
|
||||
common.es('rm -rf *')
|
||||
common.fetchAndInstall(crypto)
|
||||
cryptoPlugin.setup(cryptoDir)
|
||||
fs.writeFileSync(installedFilePath(crypto), '')
|
||||
process.chdir(oldDir)
|
||||
}
|
||||
|
||||
33
lib/blockchain/litecoin.js
Normal file
33
lib/blockchain/litecoin.js
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const coinUtils = require('../coin-utils')
|
||||
|
||||
const common = require('./common')
|
||||
|
||||
module.exports = {setup}
|
||||
|
||||
const es = common.es
|
||||
|
||||
function setup (dataDir) {
|
||||
const coinRec = coinUtils.getCryptoCurrency('LTC')
|
||||
common.firewall([coinRec.defaultPort])
|
||||
const config = buildConfig()
|
||||
fs.writeFileSync(path.resolve(dataDir, coinRec.configFile), config)
|
||||
setupPm2(dataDir)
|
||||
}
|
||||
|
||||
function buildConfig () {
|
||||
return `rpcuser=lamassuserver
|
||||
rpcpassword=${common.randomPass()}
|
||||
dbcache=500
|
||||
server=1
|
||||
connections=40
|
||||
keypool=10000
|
||||
prune=4000
|
||||
daemon=0`
|
||||
}
|
||||
|
||||
function setupPm2 (dataDir) {
|
||||
es(`pm2 start /usr/local/bin/litecoind -- -datadir=${dataDir}`)
|
||||
}
|
||||
37
lib/blockchain/zcash.js
Normal file
37
lib/blockchain/zcash.js
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const coinUtils = require('../coin-utils')
|
||||
|
||||
const common = require('./common')
|
||||
|
||||
module.exports = {setup}
|
||||
|
||||
const es = common.es
|
||||
const logger = common.logger
|
||||
|
||||
function setup (dataDir) {
|
||||
es('sudo apt-get update')
|
||||
es('sudo apt-get install libgomp1 -y')
|
||||
const coinRec = coinUtils.getCryptoCurrency('ZEC')
|
||||
|
||||
common.firewall([coinRec.defaultPort])
|
||||
logger.info('Fetching Zcash proofs, will take a while...')
|
||||
es('zcash-fetch-params 2>&1')
|
||||
logger.info('Finished fetching proofs.')
|
||||
const config = buildConfig()
|
||||
fs.writeFileSync(path.resolve(dataDir, 'zcash.conf'), config)
|
||||
setupPm2(dataDir)
|
||||
}
|
||||
|
||||
function buildConfig () {
|
||||
return `mainnet=1
|
||||
addnode=mainnet.z.cash
|
||||
rpcuser=lamassuserver
|
||||
rpcpassword=${common.randomPass()}
|
||||
dbcache=500`
|
||||
}
|
||||
|
||||
function setupPm2 (dataDir) {
|
||||
es(`pm2 start /usr/local/bin/zcashd -- -datadir=${dataDir}`)
|
||||
}
|
||||
0
lib/blockchain/zcashd.js
Normal file
0
lib/blockchain/zcashd.js
Normal file
Loading…
Add table
Add a link
Reference in a new issue